@@ -52,6 +52,25 @@ struct TStateStorageInfo : public TThrRefBase {
52
52
mutable ui64 Hash;
53
53
};
54
54
55
+ class TStateStorageRingWalker {
56
+ const ui32 Sz;
57
+ const ui32 Delta;
58
+ ui32 A;
59
+ public:
60
+ TStateStorageRingWalker (ui32 hash, ui32 sz)
61
+ : Sz(sz)
62
+ , Delta(Primes[hash % 128 ])
63
+ , A(hash + Delta)
64
+ {
65
+ Y_DEBUG_ABORT_UNLESS (Delta > Sz);
66
+ }
67
+
68
+ ui32 Next () {
69
+ A += Delta;
70
+ return (A % Sz);
71
+ }
72
+ };
73
+
55
74
void TStateStorageInfo::SelectReplicas (ui64 tabletId, TSelection *selection) const {
56
75
const ui32 hash = StateStorageHashFromTabletID (tabletId);
57
76
const ui32 total = Rings.size ();
@@ -69,7 +88,7 @@ void TStateStorageInfo::SelectReplicas(ui64 tabletId, TSelection *selection) con
69
88
selection->SelectedReplicas [idx] = Rings[idx].SelectReplica (hash);
70
89
}
71
90
} else { // NToSelect < total, first - select rings with walker, then select concrete node
72
- TStateStorageRingWalker walker (hash, total);
91
+ NStateStorageOld:: TStateStorageRingWalker walker (hash, total);
73
92
for (ui32 idx : xrange (NToSelect))
74
93
selection->SelectedReplicas [idx] = Rings[walker.Next ()].SelectReplica (hash);
75
94
}
@@ -350,6 +369,11 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) {
350
369
TStateStorageInfo::TSelection selection;
351
370
for (ui64 tabletId = 8000000 ; tabletId < 9000000 ; ++tabletId) {
352
371
info.SelectReplicas (tabletId, &selection, 0 );
372
+ std::unordered_set<TActorId> ids;
373
+ for (ui32 i : xrange (selection.Sz )) {
374
+ ids.insert (selection.SelectedReplicas [i]);
375
+ }
376
+ Y_ABORT_UNLESS (ids.size () == selection.Sz );
353
377
Y_ABORT_UNLESS (nToSelect == selection.Sz );
354
378
for (ui32 idx : xrange (nToSelect))
355
379
retHash = CombineHashes<ui64>(retHash, selection.SelectedReplicas [idx].Hash ());
@@ -379,31 +403,31 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) {
379
403
380
404
Y_UNIT_TEST (TestReplicaSelection) {
381
405
UNIT_ASSERT (StabilityRun (3 , 3 , 1 , false ) == 17606246762804570019ULL );
382
- UNIT_ASSERT (StabilityRun (13 , 3 , 1 , false ) == 421354124534079828ULL );
383
- UNIT_ASSERT (StabilityRun (13 , 9 , 1 , false ) == 10581416019959162949ULL );
406
+ UNIT_ASSERT (StabilityRun (13 , 3 , 1 , false ) == 6799095354188407094ULL );
407
+ UNIT_ASSERT (StabilityRun (13 , 9 , 1 , false ) == 9959984117877048199ULL );
384
408
UNIT_ASSERT (StabilityRun (3 , 3 , 1 , true ) == 17606246762804570019ULL );
385
- UNIT_ASSERT (StabilityRun (13 , 3 , 1 , true ) == 421354124534079828ULL );
386
- UNIT_ASSERT (StabilityRun (13 , 9 , 1 , true ) == 10581416019959162949ULL );
409
+ UNIT_ASSERT (StabilityRun (13 , 3 , 1 , true ) == 6799095354188407094ULL );
410
+ UNIT_ASSERT (StabilityRun (13 , 9 , 1 , true ) == 9959984117877048199ULL );
387
411
}
388
412
389
413
Y_UNIT_TEST (TestMultiReplicaFailDomains) {
390
414
UNIT_ASSERT (StabilityRun (3 , 3 , 3 , false ) == 12043409773822600429ULL );
391
- UNIT_ASSERT (StabilityRun (13 , 3 , 5 , false ) == 3265154396592024904ULL );
392
- UNIT_ASSERT (StabilityRun (13 , 9 , 8 , false ) == 12079940289459527060ULL );
415
+ UNIT_ASSERT (StabilityRun (13 , 3 , 5 , false ) == 16389704234708466102ULL );
416
+ UNIT_ASSERT (StabilityRun (13 , 9 , 8 , false ) == 15827315848675537518ULL );
393
417
UNIT_ASSERT (StabilityRun (3 , 3 , 3 , true ) == 7845257406715748850ULL );
394
- UNIT_ASSERT (StabilityRun (13 , 3 , 5 , true ) == 1986618578793030392ULL );
395
- UNIT_ASSERT (StabilityRun (13 , 9 , 8 , true ) == 6173011524598124144ULL );
418
+ UNIT_ASSERT (StabilityRun (13 , 3 , 5 , true ) == 16411438521907095913ULL );
419
+ UNIT_ASSERT (StabilityRun (13 , 9 , 8 , true ) == 5026957911653120252ULL );
396
420
}
397
421
398
422
Y_UNIT_TEST (TestReplicaSelectionUniqueCombinations) {
399
- UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 1 , false ), 0.000206 , 1e-7 );
400
- UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 3 , false ), 0.000519 , 1e-7 );
423
+ UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 1 , false ), 0.000205 , 1e-7 );
424
+ UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 3 , false ), 0.000518 , 1e-7 );
401
425
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 3 , 1 , false ), 0.009091 , 1e-7 );
402
426
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 3 , 5 , false ), 0.045251 , 1e-7 );
403
427
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 9 , 1 , false ), 0.009237 , 1e-7 );
404
428
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 9 , 8 , false ), 0.01387 , 1e-7 );
405
- UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 1 , true ), 0.000206 , 1e-7 );
406
- UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 3 , true ), 0.004263 , 1e-7 );
429
+ UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 1 , true ), 0.000205 , 1e-7 );
430
+ UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (13 , 3 , 3 , true ), 0.004262 , 1e-7 );
407
431
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 3 , 1 , true ), 0.009091 , 1e-7 );
408
432
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 3 , 5 , true ), 0.63673 , 1e-7 );
409
433
UNIT_ASSERT_DOUBLES_EQUAL (UniqueCombinationsRun (113 , 9 , 1 , true ), 0.009237 , 1e-7 );
@@ -462,6 +486,72 @@ Y_UNIT_TEST_SUITE(TStateStorageConfig) {
462
486
info1.RingGroups [0 ].State = ERingGroupState::DISCONNECTED;
463
487
UNIT_ASSERT (info1.RingGroups [0 ].SameConfiguration (info2.RingGroups [0 ]));
464
488
}
489
+
490
+ Y_UNIT_TEST (Tablet72075186224040026Test) {
491
+ TStateStorageInfo info;
492
+ FillStateStorageInfo (&info, 9 , 5 , 1 , false );
493
+ NKikimr::TStateStorageInfo::TSelection selection;
494
+ info.SelectReplicas (72075186224040026UL , &selection, 0 );
495
+ ui32 expected[] = {0 , 2 , 1 , 3 , 4 };
496
+ for (ui32 i : xrange (5 )) {
497
+ UNIT_ASSERT_EQUAL (selection.SelectedReplicas [i].NodeId (), expected[i]);
498
+ }
499
+ }
500
+
501
+ Y_UNIT_TEST (NonDuplicatedNodesTest) {
502
+ TStateStorageInfo info;
503
+ NStateStorageOld::TStateStorageInfo oldInfo;
504
+ FillStateStorageInfo (&info, 9 , 5 , 1 , false );
505
+ oldInfo.Rings .resize (9 );
506
+ oldInfo.NToSelect = 5 ;
507
+ for (ui32 i : xrange (9 )) {
508
+ oldInfo.Rings [i].Replicas .push_back (TActorId (i, i, i, i));
509
+ }
510
+ ui32 good = 0 ;
511
+ for (ui64 tabletId : xrange (Max<ui64>() - 1000000UL , Max<ui64>())) {
512
+ NKikimr::TStateStorageInfo::TSelection selection;
513
+ NStateStorageOld::TStateStorageInfo::TSelection oldSelection;
514
+ info.SelectReplicas (tabletId, &selection, 0 );
515
+ oldInfo.SelectReplicas (tabletId, &oldSelection);
516
+ std::unordered_set<TActorId> nodes;
517
+ for (ui32 i : xrange (5 )) {
518
+ nodes.insert (oldSelection.SelectedReplicas [i]);
519
+ }
520
+ if (nodes.size () == 5 ) {
521
+ good++;
522
+ for (ui32 i : xrange (5 )) {
523
+ UNIT_ASSERT_EQUAL (oldSelection.SelectedReplicas [i], selection.SelectedReplicas [i]);
524
+ }
525
+ } else {
526
+ ui32 same = 0 ;
527
+ for (ui32 i : xrange (5 )) {
528
+ if (oldSelection.SelectedReplicas [i] == selection.SelectedReplicas [i]) {
529
+ same++;
530
+ }
531
+ }
532
+ UNIT_ASSERT_EQUAL (same, nodes.size ());
533
+ }
534
+ }
535
+ UNIT_ASSERT_EQUAL (good, 999941 );
536
+ }
537
+
538
+ Y_UNIT_TEST (DuplicatedNodesTest) {
539
+ TStateStorageInfo info;
540
+ FillStateStorageInfo (&info, 9 , 5 , 1 , false );
541
+ ui32 bad = 0 ;
542
+ for (ui64 tabletId : xrange (Max<ui64>() - 1000000UL , Max<ui64>())) {
543
+ NKikimr::TStateStorageInfo::TSelection selection;
544
+ info.SelectReplicas (tabletId, &selection, 0 );
545
+ std::unordered_set<TActorId> nodes;
546
+ for (ui32 i : xrange (5 )) {
547
+ nodes.insert (selection.SelectedReplicas [i]);
548
+ }
549
+ if (nodes.size () != 5 ) {
550
+ bad++;
551
+ }
552
+ }
553
+ UNIT_ASSERT_EQUAL (bad, 0 );
554
+ }
465
555
}
466
556
467
557
}
0 commit comments