@@ -247,58 +247,98 @@ ColumnFamilies {
247
247
info.KMeans .ChildBegin = 201 ;
248
248
info.KMeans .Child = 201 ;
249
249
250
- TVector<TCell> from = {TCell::Make ((ui64)1 ), TCell::Make (123 )};
251
- TVector<TCell> to = {TCell::Make ((ui64)3 ), TCell::Make (123 )};
252
- auto range = TSerializedTableRange (from, true , to, true );
253
- info.AddParent (range, TShardIdx (1 , 1 ));
250
+ auto addShard = [&](ui64 fromCluster, ui64 toCluster, ui32 shard, bool partialFrom = false ) {
251
+ TVector<TCell> from = {TCell::Make (fromCluster), TCell::Make (123 )};
252
+ if (partialFrom) {
253
+ from.pop_back ();
254
+ }
255
+ TVector<TCell> to = {TCell::Make (toCluster), TCell::Make (123 )};
256
+ auto range = TSerializedTableRange (from, true , to, true );
257
+ info.AddParent (range, TShardIdx (1 , shard));
258
+ };
259
+ auto checkShards = [&](ui64 from, ui64 to, std::vector<ui32> shards) {
260
+ auto rng = info.Cluster2Shards .at (to);
261
+ if (rng.From != from || rng.Shards .size () != shards.size ()) {
262
+ return false ;
263
+ }
264
+ for (size_t i = 0 ; i < shards.size (); i++) {
265
+ if (rng.Shards [i] != TShardIdx (1 , shards[i])) {
266
+ return false ;
267
+ }
268
+ }
269
+ return true ;
270
+ };
254
271
272
+ // no intersection + empty list
273
+ addShard (1 , 3 , 1 );
255
274
UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 1 );
256
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (3 ).From , 1 );
257
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (3 ).Shards .size (), 1 );
275
+ UNIT_ASSERT (checkShards (1 , 3 , {1 }));
258
276
259
277
// add an intersecting shard. it even crashed here until 02.07.2025 :)
260
- from = {TCell::Make ((ui64)3 ), TCell::Make (123 )};
261
- to = {TCell::Make ((ui64)4 ), TCell::Make (123 )};
262
- range = TSerializedTableRange (from, true , to, true );
263
- info.AddParent (range, TShardIdx (1 , 2 ));
278
+ // intersection by start + both larger than 1
279
+ addShard (3 , 4 , 2 );
280
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 3 );
281
+ UNIT_ASSERT (checkShards (1 , 2 , {1 }));
282
+ UNIT_ASSERT (checkShards (3 , 3 , {1 , 2 }));
283
+ UNIT_ASSERT (checkShards (4 , 4 , {2 }));
264
284
265
- // Cluster2Shards is a rather stupid thing - for now, it just merges all intersecting
266
- // shard ranges into a single item , thus losing the range info for individual cluster IDs
267
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . size (), 1 );
268
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at ( 4 ). From , 1 );
269
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . at ( 4 ). Shards . size (), 2 );
285
+ // intersection by start + both 1 (duplicate range)
286
+ // incomplete range is "from (3, +infinity)" , thus equal to "from 4"
287
+ addShard ( 3 , 4 , 3 , true );
288
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 3 );
289
+ UNIT_ASSERT ( checkShards ( 4 , 4 , { 2 , 3 }) );
270
290
271
- // add a non-intersecting shard
272
- from = { TCell::Make ((ui64) 5 ), TCell::Make ( 123 )} ;
273
- to = { TCell::Make ((ui64) 6 ), TCell::Make ( 123 )} ;
274
- range = TSerializedTableRange (from, true , to, true );
275
- info. AddParent (range, TShardIdx ( 1 , 3 ));
291
+ // intersection by start + old 1 + new larger than 1
292
+ addShard ( 4 , 6 , 4 ) ;
293
+ UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . size (), 4 ) ;
294
+ UNIT_ASSERT ( checkShards ( 4 , 4 , { 2 , 3 , 4 }) );
295
+ UNIT_ASSERT ( checkShards ( 5 , 6 , { 4 } ));
276
296
277
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . size (), 2 );
278
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . at ( 4 ). From , 1 );
279
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at ( 4 ). Shards . size (), 2 );
280
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . at ( 6 ). From , 5 );
281
- UNIT_ASSERT_VALUES_EQUAL (info. Cluster2Shards . at ( 6 ). Shards . size (), 1 );
297
+ // intersection by start + old larger than 1 + new 1
298
+ addShard ( 6 , 6 , 5 );
299
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 5 );
300
+ UNIT_ASSERT ( checkShards ( 5 , 5 , { 4 }) );
301
+ UNIT_ASSERT ( checkShards ( 6 , 6 , { 4 , 5 }) );
282
302
283
- // incomplete range is "from (99, +infinity)", thus equal to "from [100]"
284
- from = {TCell::Make ((ui64)99 )};
285
- to = {TCell::Make ((ui64)100 ), TCell::Make (123 )};
286
- range = TSerializedTableRange (from, true , to, true );
287
- info.AddParent (range, TShardIdx (1 , 4 ));
303
+ // no intersection + after non-empty list
304
+ addShard (19 , 20 , 6 );
305
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 6 );
306
+ UNIT_ASSERT (checkShards (19 , 20 , {6 }));
288
307
289
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 3 );
290
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (100 ).From , 100 );
291
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (100 ).Shards .size (), 1 );
308
+ // intersection by end + both larger than 1
309
+ addShard (18 , 19 , 7 );
310
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 8 );
311
+ UNIT_ASSERT (checkShards (18 , 18 , {7 }));
312
+ UNIT_ASSERT (checkShards (19 , 19 , {6 , 7 }));
313
+ UNIT_ASSERT (checkShards (20 , 20 , {6 }));
292
314
293
- // insert and check something before an existing item
294
- from = {TCell::Make ((ui64)50 ), TCell::Make (123 )};
295
- to = {TCell::Make ((ui64)51 ), TCell::Make (123 )};
296
- range = TSerializedTableRange (from, true , to, true );
297
- info.AddParent (range, TShardIdx (1 , 5 ));
315
+ // intersection by end + both 1 (duplicate range)
316
+ addShard (18 , 18 , 8 );
317
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 8 );
318
+ UNIT_ASSERT (checkShards (18 , 18 , {7 , 8 }));
298
319
299
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 4 );
300
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (51 ).From , 50 );
301
- UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .at (51 ).Shards .size (), 1 );
320
+ // intersection by end + old 1 + new larger than 1
321
+ addShard (16 , 18 , 9 );
322
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 9 );
323
+ UNIT_ASSERT (checkShards (16 , 17 , {9 }));
324
+ UNIT_ASSERT (checkShards (18 , 18 , {7 , 8 , 9 }));
325
+
326
+ // intersection by end + old larger than 1 + new 1
327
+ addShard (16 , 16 , 10 );
328
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 10 );
329
+ UNIT_ASSERT (checkShards (16 , 16 , {9 , 10 }));
330
+ UNIT_ASSERT (checkShards (17 , 17 , {9 }));
331
+
332
+ // intersection by both
333
+ addShard (7 , 9 , 11 );
334
+ addShard (13 , 15 , 12 );
335
+ addShard (9 , 13 , 13 );
336
+ UNIT_ASSERT_VALUES_EQUAL (info.Cluster2Shards .size (), 15 );
337
+ UNIT_ASSERT (checkShards (7 , 8 , {11 }));
338
+ UNIT_ASSERT (checkShards (9 , 9 , {11 , 13 }));
339
+ UNIT_ASSERT (checkShards (10 , 12 , {13 }));
340
+ UNIT_ASSERT (checkShards (13 , 13 , {12 , 13 }));
341
+ UNIT_ASSERT (checkShards (14 , 15 , {12 }));
302
342
303
343
}
304
344
0 commit comments