Skip to content

Commit 765cacc

Browse files
committed
feature: Optimize pipeline invocation
Do not invoke the pipeline for updates if the cached object is identical with the new one.
1 parent 0b92e54 commit 765cacc

1 file changed

Lines changed: 26 additions & 9 deletions

File tree

pkg/pipeline/zset_adaptor.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,23 @@ func (p *Pipeline) ConvertDeltaToZSet(delta object.Delta) (*dbsp.DocumentZSet, e
2828
// Strip UID (if any)
2929
object.RemoveUID(deltaObj)
3030

31+
// Optimization: If the new object deep-equals the cached one, suppress the delta.
32+
// This avoids unnecessary DBSP processing for no-op updates.
33+
// IMPORTANT: Only apply to Updated/Replaced/Upserted, NOT to Added or Deleted!
34+
// - Added events should NOT be suppressed: DBSP multiplicity needs to accumulate
35+
// - Deleted events should NOT be suppressed: always process deletes
36+
// - Updated/Replaced/Upserted: safe to suppress if content hasn't changed
37+
if old != nil && (delta.Type == object.Updated || delta.Type == object.Replaced ||
38+
delta.Type == object.Upserted) {
39+
oldNoUID := object.DeepCopy(old)
40+
object.RemoveUID(oldNoUID)
41+
if object.DeepEqual(deltaObj, oldNoUID) {
42+
p.log.V(5).Info("suppressing no-op delta in ConvertDeltaToZSet",
43+
"key", ObjectKey(deltaObj), "type", delta.Type)
44+
return dbsp.NewDocumentZSet(), nil
45+
}
46+
}
47+
3148
zset := dbsp.NewDocumentZSet()
3249
switch delta.Type {
3350
case object.Added:
@@ -171,8 +188,8 @@ func (p *Pipeline) ConvertZSetToDelta(zset *dbsp.DocumentZSet, target schema.Gro
171188
// When these are converted to deltas, we get separate Add and Delete entries for the same
172189
// primary key (namespace/name), but with no guaranteed ordering. This creates ambiguity:
173190
//
174-
// - delete + add UPDATE (object existed, now has new content)
175-
// - add + delete NO-OP (object was transiently created and destroyed in the same batch)
191+
// - delete + add -> UPDATE (object existed, now has new content)
192+
// - add + delete -> NO-OP (object was transiently created and destroyed in the same batch)
176193
//
177194
// Both sequences produce identical delta lists, but require different reconciliation actions.
178195
// Content-based comparison fails when documents contain dynamic fields (e.g., @now timestamps)
@@ -184,8 +201,8 @@ func (p *Pipeline) ConvertZSetToDelta(zset *dbsp.DocumentZSet, target schema.Gro
184201
// whether an object existed prior to this batch, which determines the semantic meaning of
185202
// add+delete pairs:
186203
//
187-
// - If object existed it's an UPDATE (the delete removes old state, add provides new state)
188-
// - If object didn't exist it's TRANSIENT (created and destroyed within the batch, emit nothing)
204+
// - If object existed -> it's an UPDATE (the delete removes old state, add provides new state)
205+
// - If object didn't exist -> it's TRANSIENT (created and destroyed within the batch, emit nothing)
189206
//
190207
// # Algorithm
191208
//
@@ -272,18 +289,18 @@ func (p *Pipeline) Reconcile(ds []object.Delta) ([]object.Delta, error) {
272289
// else: deleting non-existent object - silently skip
273290

274291
case hasAdds && hasDeletes:
275-
// CRITICAL DISAMBIGUATION using cache state:
292+
// Disambiguate using cache state
276293
if ops.existedBefore {
277-
// Object existed this is an UPDATE (delete old + add new)
294+
// Object existed -> this is an UPDATE (delete old + add new)
278295
d := ops.adds[len(ops.adds)-1]
279296
if err := p.targetCache.Add(d.Object); err != nil {
280297
return nil, err
281298
}
282299
deltaCache[key] = object.Delta{Object: d.Object, Type: object.Upserted}
283300
}
284-
// else: Object didn't exist TRANSIENT (add + delete in same batch = no-op)
285-
// The object was created and destroyed within this delta batch,
286-
// so it should never reach the target. Emit nothing.
301+
// else: Object didn't exist -> TRANSIENT (add + delete in same batch =
302+
// no-op) The object was created and destroyed within this delta batch, so
303+
// it should never reach the target. Emit nothing.
287304
}
288305
}
289306

0 commit comments

Comments
 (0)