Skip to content

Commit 40b882b

Browse files
committed
fixes based on pr comments
refactor the slices and maps delete oprations, get and umarshall only the required xattrs, refactor the spec for mou update, use helper function to compute mou, refactor naked returns, early exit in a case where there is no compaction
1 parent 43ad7ce commit 40b882b

2 files changed

Lines changed: 35 additions & 32 deletions

File tree

db/crud.go

Lines changed: 33 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"maps"
1616
"math"
1717
"net/http"
18+
"slices"
1819
"strings"
1920
"time"
2021

@@ -218,46 +219,48 @@ func (c *DatabaseCollection) GetDocSyncData(ctx context.Context, docid string) (
218219

219220
// CompactDocChannelHistory removes channel history entries that ended at or before the given sequence number.
220221
// This is used to truncate stale channel assignment history to reduce storage overhead.
221-
func (c *DatabaseCollection) CompactDocChannelHistory(ctx context.Context, docid string, seq uint64) (err error) {
222+
func (c *DatabaseCollection) CompactDocChannelHistory(ctx context.Context, docid string, seq uint64) error {
222223
key := realDocID(docid)
223224
if key == "" {
224225
return base.HTTPErrorf(400, "Invalid doc ID")
225226
}
226227

227-
_, xattrs, cas, err := c.dataStore.GetWithXattrs(ctx, key, c.syncGlobalSyncMouRevSeqNoAndUserXattrKeys())
228+
xattrKeys := []string{base.SyncXattrName, base.VirtualXattrRevSeqNo, base.MouXattrName}
229+
_, xattrs, cas, err := c.dataStore.GetWithXattrs(ctx, key, xattrKeys)
228230
if err != nil {
229-
return
231+
return err
230232
}
231233

232-
doc, err := c.unmarshalDocumentWithXattrs(ctx, docid, nil, xattrs, cas, DocUnmarshalSync)
234+
doc, err := c.unmarshalDocumentWithXattrs(ctx, key, nil, xattrs, cas, DocUnmarshalSync)
233235
if err != nil {
234-
return
236+
return err
235237
}
236238

237-
var compactedChannelSetHistory []ChannelSetEntry
238-
for _, channel := range doc.SyncData.ChannelSetHistory {
239-
// Keep entries that are still active or that ended after the compaction point.
240-
if channel.End > seq {
241-
compactedChannelSetHistory = append(compactedChannelSetHistory, channel)
242-
}
243-
}
244-
doc.SyncData.ChannelSetHistory = compactedChannelSetHistory
239+
// Store lengths before compaction to detect if any changes occur
240+
historyLenBefore := len(doc.SyncData.ChannelSetHistory)
241+
channelSetLenBefore := len(doc.SyncData.ChannelSet)
242+
channelsLenBefore := len(doc.SyncData.Channels)
245243

246-
var compactedChannelSet []ChannelSetEntry
247-
for _, channel := range doc.SyncData.ChannelSet {
248-
if channel.End == 0 || channel.End > seq {
249-
compactedChannelSet = append(compactedChannelSet, channel)
250-
}
251-
}
252-
doc.SyncData.ChannelSet = compactedChannelSet
244+
doc.SyncData.ChannelSetHistory = slices.DeleteFunc(doc.SyncData.ChannelSetHistory, func(channel ChannelSetEntry) bool {
245+
return channel.End <= seq
246+
})
247+
248+
doc.SyncData.ChannelSet = slices.DeleteFunc(doc.SyncData.ChannelSet, func(channel ChannelSetEntry) bool {
249+
return channel.End != 0 && channel.End <= seq
250+
})
253251

254-
compactedChannels := make(channels.ChannelMap)
255252
for chanName, chanEntry := range doc.SyncData.Channels {
256-
if chanEntry == nil || chanEntry.Seq > seq {
257-
compactedChannels[chanName] = chanEntry
253+
if chanEntry != nil && chanEntry.Seq <= seq {
254+
delete(doc.SyncData.Channels, chanName)
258255
}
259256
}
260-
doc.SyncData.Channels = compactedChannels
257+
258+
// Exit early if no compaction occurred
259+
if len(doc.SyncData.ChannelSetHistory) == historyLenBefore &&
260+
len(doc.SyncData.ChannelSet) == channelSetLenBefore &&
261+
len(doc.SyncData.Channels) == channelsLenBefore {
262+
return nil
263+
}
261264

262265
rawSyncXattr, err := base.JSONMarshal(doc.SyncData)
263266
if err != nil {
@@ -269,19 +272,19 @@ func (c *DatabaseCollection) CompactDocChannelHistory(ctx context.Context, docid
269272
base.InfofCtx(ctx, base.KeyCRUD, `Could not determine the revSeqNo when attempting to compact channel history for doc: %s. Error: %v`, base.UD(docid), err)
270273
}
271274

272-
metadataOnlyUpdate := &MetadataOnlyUpdate{
273-
HexCAS: expandMacroCASValueString,
274-
PreviousHexCAS: doc.SyncData.Cas,
275-
PreviousRevSeqNo: revSeqNo,
276-
}
275+
metadataOnlyUpdate := computeMetadataOnlyUpdate(doc.Cas, revSeqNo, doc.MetadataOnlyUpdate)
276+
277277
rawMouXattr, err := base.JSONMarshal(metadataOnlyUpdate)
278278
if err != nil {
279279
return base.RedactErrorf("failed to marshal _mou when attempting to compact channel history for doc: %s. Error: %v", base.UD(docid), err)
280280
}
281281

282282
// build macro expansion for sync data. This will avoid the update to xattrs causing an extra import event (i.e. sync cas will be == to doc cas)
283283
opts := &sgbucket.MutateInOptions{}
284-
spec := append(macroExpandSpec(base.SyncXattrName), sgbucket.NewMacroExpansionSpec(XattrMouCasPath(), sgbucket.MacroCas))
284+
spec := []sgbucket.MacroExpansionSpec{
285+
sgbucket.NewMacroExpansionSpec(xattrCasPath(base.SyncXattrName), sgbucket.MacroCas),
286+
sgbucket.NewMacroExpansionSpec(XattrMouCasPath(), sgbucket.MacroCas),
287+
}
285288
opts.MacroExpansion = spec
286289
opts.PreserveExpiry = true // if doc has expiry, we should preserve this
287290

rest/api_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,7 +3963,7 @@ func TestDocumentChannelHistoryCompact(t *testing.T) {
39633963
require.NoError(t, err)
39643964
syncData, err = collection.GetDocSyncData(ctx, "doc1")
39653965
assert.NoError(t, err)
3966-
assert.Nil(t, syncData.ChannelSetHistory)
3966+
assert.Zero(t, len(syncData.ChannelSetHistory))
39673967
})
39683968

39693969
t.Run("seq zero keeps all history", func(t *testing.T) {
@@ -4024,7 +4024,7 @@ func TestDocumentChannelHistoryCompact(t *testing.T) {
40244024

40254025
syncData, err := collection.GetDocSyncData(ctx, "doc3")
40264026
require.NoError(t, err)
4027-
assert.Nil(t, syncData.ChannelSetHistory)
4027+
assert.Zero(t, len(syncData.ChannelSetHistory))
40284028
assert.Equal(t, len(syncDataBefore.Channels), len(syncData.Channels))
40294029
assert.Equal(t, len(syncDataBefore.ChannelSet), len(syncData.ChannelSet))
40304030
})

0 commit comments

Comments
 (0)