@@ -414,17 +414,33 @@ class PhTreeMultiMap {
414
414
* @param new_key The new position
415
415
* @param value The value that needs to be relocated. The relocate() method used the value's
416
416
* '==' operator to identify the entry that should be moved.
417
- * @param count_equals This setting toggles whether a relocate() between two identical keys
418
- * should be counted as 'success' and return '1'. The function may still return '0'
419
- * in case the keys are not in the index.
420
- * Background: the intuitively correct behavior is to return '1' for identical
421
- * (exising) keys. However, avoiding this check can considerably speed up
422
- * relocate() calls, especially when using a ConverterMultiply.
417
+ * @param verify_exists This setting toggles whether a relocate() between two identical keys
418
+ * should verify whether the key actually exist before return '1'.
419
+ * If set to 'false', this function will return '1' if the keys are identical,
420
+ * without checking whether the keys actually exist. Avoiding this check can
421
+ * considerably speed up relocate() calls, especially when using a
422
+ * ConverterMultiply.
423
423
*
424
424
* @return '1' if a value was found and reinserted, otherwise '0'.
425
425
*/
426
426
template <typename T2>
427
- size_t relocate (const Key& old_key, const Key& new_key, T2&& value, bool count_equals = true ) {
427
+ size_t relocate (const Key& old_key, const Key& new_key, T2&& value, bool verify_exists = true ) {
428
+ auto fn = [&value](BUCKET& src, BUCKET& dst) -> size_t {
429
+ auto it = src.find (value);
430
+ if (it != src.end () && dst.emplace (std::move (*it)).second ) {
431
+ src.erase (it);
432
+ return 1 ;
433
+ }
434
+ return 0 ;
435
+ };
436
+ auto count_fn = [&value](BUCKET& src) -> size_t { return src.find (value) != src.end (); };
437
+ return tree_._relocate_mm (
438
+ converter_.pre (old_key), converter_.pre (new_key), verify_exists, fn, count_fn);
439
+ }
440
+
441
+ template <typename T2>
442
+ [[deprecated]] size_t relocate2 (
443
+ const Key& old_key, const Key& new_key, T2&& value, bool count_equals = true ) {
428
444
auto pair = tree_._find_or_create_two_mm (
429
445
converter_.pre (old_key), converter_.pre (new_key), count_equals);
430
446
auto & iter_old = pair.first ;
@@ -478,17 +494,48 @@ class PhTreeMultiMap {
478
494
* @param new_key The new position
479
495
* @param predicate The predicate that is used for every value at position old_key to evaluate
480
496
* whether it should be relocated to new_key.
481
- * @param count_equals This setting toggles whether a relocate() between two identical keys
482
- * should be counted as 'success' and return '1'. The function may still return '0'
483
- * in case the keys are not in the index.
484
- * Background: the intuitively correct behavior is to return '1' for identical
485
- * (exising) keys. However, avoiding this check can considerably speed up
486
- * relocate() calls, especially when using a ConverterMultiply.
497
+ * @param verify_exists This setting toggles whether a relocate() between two identical keys
498
+ * should verify whether the key actually exist before return '1'.
499
+ * If set to 'false', this function will return '1' if the keys are identical,
500
+ * without checking whether the keys actually exist. Avoiding this check can
501
+ * considerably speed up relocate() calls, especially when using a
502
+ * ConverterMultiply.
487
503
*
488
504
* @return the number of values that were relocated.
489
505
*/
490
506
template <typename PREDICATE>
491
507
size_t relocate_if (
508
+ const Key& old_key, const Key& new_key, PREDICATE&& pred_fn, bool verify_exists = true ) {
509
+ auto fn = [&pred_fn](BUCKET& src, BUCKET& dst) -> size_t {
510
+ size_t result = 0 ;
511
+ auto iter_src = src.begin ();
512
+ while (iter_src != src.end ()) {
513
+ if (pred_fn (*iter_src) && dst.emplace (std::move (*iter_src)).second ) {
514
+ iter_src = src.erase (iter_src);
515
+ ++result;
516
+ } else {
517
+ ++iter_src;
518
+ }
519
+ }
520
+ return result;
521
+ };
522
+ auto count_fn = [&pred_fn](BUCKET& src) -> size_t {
523
+ size_t result = 0 ;
524
+ auto iter_src = src.begin ();
525
+ while (iter_src != src.end ()) {
526
+ if (pred_fn (*iter_src)) {
527
+ ++result;
528
+ }
529
+ ++iter_src;
530
+ }
531
+ return result;
532
+ };
533
+ return tree_._relocate_mm (
534
+ converter_.pre (old_key), converter_.pre (new_key), verify_exists, fn, count_fn);
535
+ }
536
+
537
+ template <typename PREDICATE>
538
+ [[deprecated]] size_t relocate_if2 (
492
539
const Key& old_key, const Key& new_key, PREDICATE&& predicate, bool count_equals = true ) {
493
540
auto pair = tree_._find_or_create_two_mm (
494
541
converter_.pre (old_key), converter_.pre (new_key), count_equals);
0 commit comments