Skip to content

Commit a195430

Browse files
committed
Skip REMOVE operation in additional cases.
1 parent e03f440 commit a195430

File tree

1 file changed

+26
-10
lines changed

1 file changed

+26
-10
lines changed

crates/core/src/operations.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,8 @@ UPDATE ps_oplog SET
6969
data = NULL
7070
WHERE ps_oplog.superseded = 0
7171
AND unlikely(ps_oplog.bucket = ?1)
72-
AND ps_oplog.key = ?2",
72+
AND ps_oplog.key = ?2
73+
RETURNING op_id",
7374
)?;
7475
supersede_statement.bind_text(1, bucket, sqlite::Destructor::STATIC)?;
7576

@@ -110,21 +111,36 @@ INSERT INTO ps_oplog(bucket, op_id, op, key, row_type, row_id, data, hash, super
110111

111112
last_op = Some(op_id);
112113

113-
let mut key: String = "".to_string();
114-
115114
if op == "PUT" || op == "REMOVE" {
115+
let key: String;
116116
if let (Ok(object_type), Ok(object_id)) = (object_type.as_ref(), object_id.as_ref()) {
117117
let subkey = iterate_statement.column_text(6).unwrap_or("null");
118-
let populated_key = format!("{}/{}/{}", &object_type, &object_id, subkey);
118+
key = format!("{}/{}/{}", &object_type, &object_id, subkey);
119+
} else {
120+
key = String::from("");
121+
}
119122

120-
supersede_statement.bind_text(2, &populated_key, sqlite::Destructor::STATIC)?;
121-
supersede_statement.exec()?;
123+
// TODO: Instead of "superseding" the previous operation, we could delete
124+
// it directly.
125+
supersede_statement.bind_text(2, &key, sqlite::Destructor::STATIC)?;
122126

123-
key = populated_key;
127+
let mut should_skip_remove = true;
128+
if (supersede_statement.step()? == ResultCode::ROW) {
129+
// Superseded an operation, only skip if the bucket was empty
130+
should_skip_remove = is_empty;
131+
}
132+
supersede_statement.reset()?;
133+
134+
if (should_skip_remove && op == "REMOVE") {
135+
// If a REMOVE statement did not replace (supersede) any previous
136+
// operations, we do not need to persist it.
137+
// The same applies if the bucket was not synced to the local db yet,
138+
// even if it did supersede another operation.
139+
// Handle the same as MOVE.
140+
add_checksum = add_checksum.wrapping_add(checksum);
141+
continue;
124142
}
125-
}
126143

127-
if op == "PUT" || (op == "REMOVE" && !is_empty) {
128144
let opi = if op == "PUT" { 3 } else { 4 };
129145
insert_statement.bind_int64(2, op_id)?;
130146
insert_statement.bind_int(3, opi)?;
@@ -149,7 +165,7 @@ INSERT INTO ps_oplog(bucket, op_id, op, key, row_type, row_id, data, hash, super
149165

150166
insert_statement.bind_int(8, checksum)?;
151167
insert_statement.exec()?;
152-
} else if op == "MOVE" || (is_empty && op == "REMOVE") {
168+
} else if op == "MOVE" {
153169
add_checksum = add_checksum.wrapping_add(checksum);
154170
} else if op == "CLEAR" {
155171
// Any remaining PUT operations should get an implicit REMOVE

0 commit comments

Comments
 (0)