@@ -56,3 +56,130 @@ func TestSegmentPersistentStorage(t *testing.T) {
5656 t .Error ("k1 should be removed" )
5757 }
5858}
59+
60+ func TestNewSegmentChangesCollectionInitializesChangeNumbers (t * testing.T ) {
61+ dbw , err := NewBoltWrapper (BoltInMemoryMode , nil )
62+ if err != nil {
63+ t .Error ("error creating bolt wrapper: " , err )
64+ }
65+
66+ logger := logging .NewLogger (nil )
67+
68+ // First, create a collection and add some segments with different change numbers
69+ segmentC := NewSegmentChangesCollection (dbw , logger )
70+
71+ // Add segment s1 with keys at change number 10
72+ segmentC .Update ("s1" , set .NewSet ("k1" , "k2" ), set .NewSet (), 10 )
73+
74+ // Add more keys to s1 at change number 20
75+ segmentC .Update ("s1" , set .NewSet ("k3" ), set .NewSet (), 20 )
76+
77+ // Add segment s2 with keys at change number 15
78+ segmentC .Update ("s2" , set .NewSet ("k4" , "k5" ), set .NewSet (), 15 )
79+
80+ // Verify change numbers are set correctly after updates
81+ if cn := segmentC .ChangeNumber ("s1" ); cn != 20 {
82+ t .Errorf ("s1 change number should be 20, got %d" , cn )
83+ }
84+
85+ if cn := segmentC .ChangeNumber ("s2" ); cn != 15 {
86+ t .Errorf ("s2 change number should be 15, got %d" , cn )
87+ }
88+
89+ // Now create a NEW collection from the same database (simulating a restart with snapshot)
90+ segmentC2 := NewSegmentChangesCollection (dbw , logger )
91+
92+ // Verify that the change numbers were initialized correctly from the stored data
93+ if cn := segmentC2 .ChangeNumber ("s1" ); cn != 20 {
94+ t .Errorf ("After initialization, s1 change number should be 20, got %d" , cn )
95+ }
96+
97+ if cn := segmentC2 .ChangeNumber ("s2" ); cn != 15 {
98+ t .Errorf ("After initialization, s2 change number should be 15, got %d" , cn )
99+ }
100+
101+ // Verify non-existent segment returns -1
102+ if cn := segmentC2 .ChangeNumber ("nonexistent" ); cn != - 1 {
103+ t .Errorf ("Non-existent segment should return -1, got %d" , cn )
104+ }
105+ }
106+
107+ func TestInitializeWithEmptyDatabase (t * testing.T ) {
108+ dbw , err := NewBoltWrapper (BoltInMemoryMode , nil )
109+ if err != nil {
110+ t .Error ("error creating bolt wrapper: " , err )
111+ }
112+
113+ logger := logging .NewLogger (nil )
114+
115+ // Create a collection on an empty database
116+ segmentC := NewSegmentChangesCollection (dbw , logger )
117+
118+ // Should not panic and should return -1 for any segment
119+ if cn := segmentC .ChangeNumber ("any_segment" ); cn != - 1 {
120+ t .Errorf ("Empty database should return -1 for any segment, got %d" , cn )
121+ }
122+ }
123+
124+ func TestInitializeWithRemovedKeys (t * testing.T ) {
125+ dbw , err := NewBoltWrapper (BoltInMemoryMode , nil )
126+ if err != nil {
127+ t .Error ("error creating bolt wrapper: " , err )
128+ }
129+
130+ logger := logging .NewLogger (nil )
131+ segmentC := NewSegmentChangesCollection (dbw , logger )
132+
133+ // Add keys at change number 10
134+ segmentC .Update ("s1" , set .NewSet ("k1" , "k2" , "k3" ), set .NewSet (), 10 )
135+
136+ // Remove some keys at change number 25
137+ segmentC .Update ("s1" , set .NewSet (), set .NewSet ("k1" ), 25 )
138+
139+ // Add new keys at change number 30
140+ segmentC .Update ("s1" , set .NewSet ("k4" ), set .NewSet (), 30 )
141+
142+ // The max change number should be 30
143+ if cn := segmentC .ChangeNumber ("s1" ); cn != 30 {
144+ t .Errorf ("s1 change number should be 30, got %d" , cn )
145+ }
146+
147+ // Create new collection to test initialization
148+ segmentC2 := NewSegmentChangesCollection (dbw , logger )
149+
150+ // Should pick up the maximum change number (30) even with mixed add/remove operations
151+ if cn := segmentC2 .ChangeNumber ("s1" ); cn != 30 {
152+ t .Errorf ("After initialization with removed keys, s1 change number should be 30, got %d" , cn )
153+ }
154+ }
155+
156+ func TestInitializeMultipleSegments (t * testing.T ) {
157+ dbw , err := NewBoltWrapper (BoltInMemoryMode , nil )
158+ if err != nil {
159+ t .Error ("error creating bolt wrapper: " , err )
160+ }
161+
162+ logger := logging .NewLogger (nil )
163+ segmentC := NewSegmentChangesCollection (dbw , logger )
164+
165+ // Create multiple segments with different change numbers
166+ segments := map [string ]int64 {
167+ "segment_a" : 100 ,
168+ "segment_b" : 250 ,
169+ "segment_c" : 50 ,
170+ "segment_d" : 999 ,
171+ }
172+
173+ for name , cn := range segments {
174+ segmentC .Update (name , set .NewSet ("key1" , "key2" ), set .NewSet (), cn )
175+ }
176+
177+ // Create new collection and verify all segments are initialized correctly
178+ segmentC2 := NewSegmentChangesCollection (dbw , logger )
179+
180+ for name , expectedCN := range segments {
181+ if cn := segmentC2 .ChangeNumber (name ); cn != expectedCN {
182+ t .Errorf ("Segment %s should have change number %d, got %d" , name , expectedCN , cn )
183+ }
184+ }
185+ }
0 commit comments