@@ -593,51 +593,6 @@ struct ConcurrentReadableHashMap {
593593 }
594594 }
595595
596- // Common implementation for `getOrInsert` and `GetOrInsertManyScope`
597- template <class KeyTy , typename Call>
598- void getOrInsertExternallyLocked (KeyTy key, const Call &call) {
599- auto indices = IndexStorage{Indices.load (std::memory_order_relaxed)};
600- auto indicesCapacityLog2 = indices.getCapacityLog2 ();
601- auto elementCount = ElementCount.load (std::memory_order_relaxed);
602- auto *elements = Elements.load (std::memory_order_relaxed);
603- auto *elementsPtr = elements ? elements->data () : nullptr ;
604-
605-
606- auto found = this ->find (key, indices, elementCount, elementsPtr);
607- if (found.first ) {
608- call (found.first , false );
609- return ;
610- }
611-
612- auto indicesCapacity = 1UL << indicesCapacityLog2;
613-
614- // The number of slots in use is elementCount + 1, since the capacity also
615- // takes a slot.
616- auto emptyCount = indicesCapacity - (elementCount + 1 );
617- auto proportion = indicesCapacity / emptyCount;
618- if (proportion >= ResizeProportion) {
619- indices = resize (indices, indicesCapacityLog2, elementsPtr);
620- found = find (key, indices, elementCount, elementsPtr);
621- assert (!found.first && " Shouldn't suddenly find the key after rehashing" );
622- }
623-
624- if (!elements || elementCount >= elements->Capacity ) {
625- elements = resize (elements, elementCount);
626- }
627- auto *element = &elements->data ()[elementCount];
628-
629- // Order matters: fill out the element, then update the count,
630- // then update the index.
631- bool keep = call (element, true );
632- if (keep) {
633- assert (hash_value (key) == hash_value (*element) &&
634- " Element must have the same hash code as its key." );
635- ElementCount.store (elementCount + 1 , std::memory_order_release);
636- indices.storeIndexAt (&Indices, elementCount + 1 , found.second ,
637- std::memory_order_release);
638- }
639- }
640-
641596public:
642597 // Implicitly trivial constructor/destructor.
643598 ConcurrentReadableHashMap () = default ;
@@ -729,48 +684,6 @@ struct ConcurrentReadableHashMap {
729684 return Snapshot (this , indices, elementsPtr, elementCount);
730685 }
731686
732- // / A wrapper that allows performing several `getOrInsert` operations under
733- // / the same lock.
734- class GetOrInsertManyScope {
735- GetOrInsertManyScope () = delete ;
736- GetOrInsertManyScope (const GetOrInsertManyScope &) = delete ;
737- GetOrInsertManyScope &operator =(const GetOrInsertManyScope &) = delete ;
738- GetOrInsertManyScope (GetOrInsertManyScope &&) = delete ;
739- GetOrInsertManyScope &operator =(GetOrInsertManyScope &&) = delete ;
740-
741- ConcurrentReadableHashMap ⤅
742-
743- public:
744- GetOrInsertManyScope (ConcurrentReadableHashMap &map) : Map(map) {
745- Map.WriterLock .lock ();
746- }
747-
748- ~GetOrInsertManyScope () {
749- Map.deallocateFreeListIfSafe ();
750- Map.WriterLock .unlock ();
751- }
752-
753- // / Get an element by key, or insert a new element for that key if one is
754- // / not already present. Invoke `call` with the pointer to the element.
755- // /
756- // / `call` is passed the following parameters:
757- // / - `element`: the pointer to the element corresponding to `key`
758- // / - `created`: true if the element is newly created, false if it already
759- // / exists
760- // / `call` returns a `bool`. When `created` is `true`, the return values
761- // / mean:
762- // / - `true` the new entry is to be kept
763- // / - `false` indicates that the new entry is discarded
764- // / If the new entry is kept, then the new element MUST be initialized, and
765- // / have a hash value that matches the hash value of `key`.
766- // /
767- // / The return value is ignored when `created` is `false`.
768- template <class KeyTy , typename Call>
769- void getOrInsert (KeyTy key, const Call &call) {
770- Map.getOrInsertExternallyLocked (key, call);
771- }
772- };
773-
774687 // / Get an element by key, or insert a new element for that key if one is not
775688 // / already present. Invoke `call` with the pointer to the element. BEWARE:
776689 // / `call` is invoked with the internal writer lock held, keep work to a
@@ -790,7 +703,48 @@ struct ConcurrentReadableHashMap {
790703 template <class KeyTy , typename Call>
791704 void getOrInsert (KeyTy key, const Call &call) {
792705 typename MutexTy::ScopedLock guard (WriterLock);
793- getOrInsertExternallyLocked (key, call);
706+
707+ auto indices = IndexStorage{Indices.load (std::memory_order_relaxed)};
708+ auto indicesCapacityLog2 = indices.getCapacityLog2 ();
709+ auto elementCount = ElementCount.load (std::memory_order_relaxed);
710+ auto *elements = Elements.load (std::memory_order_relaxed);
711+ auto *elementsPtr = elements ? elements->data () : nullptr ;
712+
713+ auto found = this ->find (key, indices, elementCount, elementsPtr);
714+ if (found.first ) {
715+ call (found.first , false );
716+ deallocateFreeListIfSafe ();
717+ return ;
718+ }
719+
720+ auto indicesCapacity = 1UL << indicesCapacityLog2;
721+
722+ // The number of slots in use is elementCount + 1, since the capacity also
723+ // takes a slot.
724+ auto emptyCount = indicesCapacity - (elementCount + 1 );
725+ auto proportion = indicesCapacity / emptyCount;
726+ if (proportion >= ResizeProportion) {
727+ indices = resize (indices, indicesCapacityLog2, elementsPtr);
728+ found = find (key, indices, elementCount, elementsPtr);
729+ assert (!found.first && " Shouldn't suddenly find the key after rehashing" );
730+ }
731+
732+ if (!elements || elementCount >= elements->Capacity ) {
733+ elements = resize (elements, elementCount);
734+ }
735+ auto *element = &elements->data ()[elementCount];
736+
737+ // Order matters: fill out the element, then update the count,
738+ // then update the index.
739+ bool keep = call (element, true );
740+ if (keep) {
741+ assert (hash_value (key) == hash_value (*element) &&
742+ " Element must have the same hash code as its key." );
743+ ElementCount.store (elementCount + 1 , std::memory_order_release);
744+ indices.storeIndexAt (&Indices, elementCount + 1 , found.second ,
745+ std::memory_order_release);
746+ }
747+
794748 deallocateFreeListIfSafe ();
795749 }
796750
0 commit comments