@@ -94,6 +94,41 @@ type SyncData struct {
9494
9595 addedRevisionBodies []string // revIDs of non-winning revision bodies that have been added (and so require persistence)
9696 removedRevisionBodyKeys map [string ]string // keys of non-winning revisions that have been removed (and so may require deletion), indexed by revID
97+
98+ currentRevChannels base.Set // A base.Set of the current revision's channels (determined by SyncData.Channels at UnmarshalJSON time)
99+ }
100+
101+ func (sd * SyncData ) UnmarshalJSON (b []byte ) error {
102+
103+ // type alias avoids UnmarshalJSON stack overflow (forces fallback to standard JSON unmarshal instead of this one)
104+ type stdSyncData SyncData
105+ var tmp stdSyncData
106+
107+ err := base .JSONUnmarshal (b , & tmp )
108+ if err != nil {
109+ return err
110+ }
111+
112+ * sd = SyncData (tmp )
113+
114+ // determine current revision's channels and store in-memory (avoids Channels iteration at access-check time)
115+ sd .currentRevChannels = sd .getCurrentChannels ()
116+
117+ return nil
118+ }
119+
120+ // determine set of current channels based on removal entries.
121+ func (sd * SyncData ) getCurrentChannels () base.Set {
122+ if len (sd .Channels ) > 0 {
123+ ch := base .SetOf ()
124+ for channelName , channelRemoval := range sd .Channels {
125+ if channelRemoval == nil || channelRemoval .Seq == 0 {
126+ ch .Add (channelName )
127+ }
128+ }
129+ return ch
130+ }
131+ return nil
97132}
98133
99134func (sd * SyncData ) HashRedact (salt string ) SyncData {
@@ -180,8 +215,6 @@ type Document struct {
180215 RevID string
181216 DocAttachments AttachmentsMeta
182217 inlineSyncData bool
183-
184- currentRevChannels base.Set // A base.Set of the current revision's channels (determined by SyncData.Channels at UnmarshalJSON time)
185218}
186219
187220type historyOnlySyncData struct {
@@ -1075,17 +1108,6 @@ func (doc *Document) UnmarshalJSON(data []byte) error {
10751108 doc .SyncData = * syncData .SyncData
10761109 }
10771110
1078- // determine current revision's channels and store in-memory (avoids doc.Channels iteration at access-check time)
1079- if len (doc .Channels ) > 0 {
1080- ch := base .SetOf ()
1081- for channelName , channelRemoval := range doc .Channels {
1082- if channelRemoval == nil || channelRemoval .Seq == 0 {
1083- ch .Add (channelName )
1084- }
1085- }
1086- doc .currentRevChannels = ch
1087- }
1088-
10891111 // Unmarshal the rest of the doc body as map[string]interface{}
10901112 if err := doc ._body .Unmarshal (data ); err != nil {
10911113 return pkgerrors .WithStack (base .RedactErrorf ("Failed to UnmarshalJSON() doc with id: %s. Error: %v" , base .UD (doc .ID ), err ))
0 commit comments