From a641e1cb0e95dfd4eee561d3f7c111d0a18aa07d Mon Sep 17 00:00:00 2001 From: Vito G Castellana Date: Tue, 7 Dec 2021 19:43:12 -0800 Subject: [PATCH] [#204] Style and other minor fixes --- include/shad/data_structures/local_multimap.h | 301 ++++++++++++------ 1 file changed, 201 insertions(+), 100 deletions(-) diff --git a/include/shad/data_structures/local_multimap.h b/include/shad/data_structures/local_multimap.h index f25ff45e..ea0f74e0 100644 --- a/include/shad/data_structures/local_multimap.h +++ b/include/shad/data_structures/local_multimap.h @@ -38,6 +38,10 @@ namespace shad { +namespace constants { +constexpr size_t kMMapDefaultNumEntriesPerBucket = 128; +} + template class lmultimap_iterator; @@ -73,9 +77,11 @@ class LocalMultimap { const std::pair>; using const_iterator = lmultimap_iterator, const std::pair>; - using key_iterator = lmultimap_key_iterator, + using key_iterator = lmultimap_key_iterator< + LocalMultimap, const std::pair>>; - using const_key_iterator = lmultimap_key_iterator, + using const_key_iterator = lmultimap_key_iterator< + LocalMultimap, const std::pair>>; /// @brief Constructor. @@ -87,7 +93,9 @@ class LocalMultimap { inserter_array_(numInitBuckets), size_(0) { - for (uint64_t i = 0; i < numInitBuckets; i ++) { deleter_array_[i] = 0; inserter_array_[i] = 0; } + for (uint64_t i = 0; i < numInitBuckets; i ++) { + deleter_array_[i] = 0; inserter_array_[i] = 0; + } } /// @brief Size of the multimap (number of entries). @@ -131,7 +139,9 @@ class LocalMultimap { size_ = 0; buckets_array_.clear(); buckets_array_ = std::vector(numBuckets_); - for (uint64_t i = 0; i < numBuckets_; i ++) { deleter_array_[i] = 0; inserter_array_[i] = 0; } + for (uint64_t i = 0; i < numBuckets_; i ++) { + deleter_array_[i] = 0; inserter_array_[i] = 0; + } } /// @brief Result for the Lookup and AsyncLookup methods. @@ -146,15 +156,18 @@ class LocalMultimap { bool found; size_t size; /// Size of the value vector. rt::Locality localLoc; /// Locality of the local site. - VTYPE * local_elems; /// Address of the value vector elements at the local site - VTYPE * remote_elems; /// Address of a copy of the value vector elements at the remote site + VTYPE * local_elems; /// Address of the value vector + /// elements at the local site + VTYPE * remote_elems; /// Address of a copy of the + /// value vector elements at the remote site }; /// @brief Asynchronously get the values associated to a key. /// @warning Asynchronous operations are guaranteed to have completed. only /// after calling the rt::waitForCompletion(rt::Handle &handle) method. /// - /// @param[in,out] handle Reference to the handle to be used to wait for completion. + /// @param[in,out] handle Reference to the handle to be used + /// to wait for completion. /// @param[in] key The key. /// @param[out] res The result of the lookup operation. void AsyncLookup(rt::Handle & handle, const KTYPE & key, LookupResult * result); @@ -216,7 +229,8 @@ class LocalMultimap { /// @brief Asynchronously apply a user-defined function to each key-value pair. /// - /// @tparam ApplyFunT User-defined function type. The function prototype /// should be: + /// @tparam ApplyFunT User-defined function type. The function prototype + /// should be: /// @code /// void(shad::rt::Handle&, const KTYPE&, VTYPE&, Args&); /// @endcode @@ -340,7 +354,8 @@ class LocalMultimap { private: static const uint8_t kHashSeed = 0; static const size_t kAllocPending = 0x1; - static const size_t kNumEntriesPerBucket = constants::kDefaultNumEntriesPerBucket; + static const size_t kNumEntriesPerBucket = + constants::kMMapDefaultNumEntriesPerBucket; static const uint32_t kKeyWords = sizeof(KTYPE) > sizeof(uint64_t) ? sizeof(KTYPE) / sizeof(uint64_t) : 1; @@ -369,8 +384,10 @@ class LocalMultimap { if (!entries) { std::lock_guard _(_entriesLock); - if (!entries) - entries = std::move(std::shared_ptr(new Entry[bucketSize_], std::default_delete())); + if (!entries) { + entries = std::move(std::shared_ptr( + new Entry[bucketSize_], std::default_delete())); + } } return entries.get()[i]; } @@ -420,11 +437,13 @@ class LocalMultimap { template static void ForEachEntryFunWrapper(const Tuple &args, size_t i) { - constexpr auto Size = std::tuple_size(args))>::type>::value; + constexpr auto Size = std::tuple_size(args))>::type>::value; Tuple &tuple = const_cast(args); CallForEachEntryFun(i, std::get<0>(tuple), - std::get<1>(tuple), std::get<2>(tuple), std::make_index_sequence{}); + std::get<1>(tuple), std::get<2>(tuple), + std::make_index_sequence{}); } template @@ -454,12 +473,15 @@ class LocalMultimap { } template - static void AsyncForEachEntryFunWrapper(rt::Handle &handle, const Tuple &args, size_t i) { - constexpr auto Size = std::tuple_size< typename std::decay(args))>::type>::value; + static void AsyncForEachEntryFunWrapper(rt::Handle &handle, + const Tuple &args, size_t i) { + constexpr auto Size = std::tuple_size< + typename std::decay(args))>::type>::value; Tuple &tuple = const_cast(args); AsyncCallForEachEntryFun(handle, i, std::get<0>(tuple), - std::get<1>(tuple), std::get<2>(tuple), std::make_index_sequence{}); + std::get<1>(tuple), std::get<2>(tuple), + std::make_index_sequence{}); } template @@ -489,7 +511,8 @@ class LocalMultimap { template static void ForEachKeyFunWrapper(const Tuple &args, size_t i) { - constexpr auto Size = std::tuple_size< typename std::decay(args))>::type>::value; + constexpr auto Size = std::tuple_size< + typename std::decay(args))>::type>::value; Tuple &tuple = const_cast(args); CallForEachKeyFun(i, std::get<0>(tuple), @@ -508,7 +531,7 @@ class LocalMultimap { while (bucket != nullptr) { Bucket *next_bucket = bucket->next.get(); - for (uint64_tj = 0; j < bucket->BucketSize(); ++j) { + for (uint64_t j = 0; j < bucket->BucketSize(); ++j) { Entry *entry = &bucket->getEntry(j); if (entry->state == USED) { function(handle, entry->key, std::get(args)...); @@ -521,8 +544,10 @@ class LocalMultimap { } template - static void AsyncForEachKeyFunWrapper(rt::Handle &handle, const Tuple &args, size_t i) { - constexpr auto Size = std::tuple_size< typename std::decay(args))>::type>::value; + static void AsyncForEachKeyFunWrapper(rt::Handle &handle, + const Tuple &args, size_t i) { + constexpr auto Size = std::tuple_size< typename std::decay< + decltype(std::get<2>(args))>::type>::value; Tuple &tuple = const_cast(args); AsyncCallForEachKeyFun(handle, i, std::get<0>(tuple), @@ -533,7 +558,8 @@ class LocalMultimap { static void AsyncCallApplyFun( rt::Handle &handle, LocalMultimap *mapPtr, - const KTYPE &key, ApplyFunT function, std::tuple &args, std::index_sequence) { + const KTYPE &key, ApplyFunT function, std::tuple &args, + std::index_sequence) { size_t bucketIdx = shad::hash{}(key) % mapPtr->numBuckets_; Bucket *bucket = &(mapPtr->buckets_array_[bucketIdx]); @@ -564,7 +590,8 @@ class LocalMultimap { template static void CallApplyFun( LocalMultimap *mapPtr, - const KTYPE &key, ApplyFunT function, std::tuple &args, std::index_sequence) { + const KTYPE &key, ApplyFunT function, std::tuple &args, + std::index_sequence) { size_t bucketIdx = shad::hash{}(key) % mapPtr->numBuckets_; Bucket *bucket = &(mapPtr->buckets_array_[bucketIdx]); @@ -594,11 +621,13 @@ class LocalMultimap { template static void AsyncApplyFunWrapper(rt::Handle &handle, const Tuple &args) { - constexpr auto Size = std::tuple_size< typename std::decay(args))>::type>::value; + constexpr auto Size = std::tuple_size< typename std::decay< + decltype(std::get<3>(args))>::type>::value; Tuple &tuple = const_cast(args); AsyncCallApplyFun(handle, std::get<0>(tuple), - std::get<1>(tuple), std::get<2>(tuple), std::get<3>(tuple), std::make_index_sequence{}); + std::get<1>(tuple), std::get<2>(tuple), + std::get<3>(tuple), std::make_index_sequence{}); } }; @@ -609,7 +638,8 @@ void LocalMultimap::AsyncLookup( using LMapPtr = LocalMultimap *; auto args = std::tuple(this, key, result); - auto lookupLambda = [](rt::Handle &, const std::tuple &t) { + auto lookupLambda = [](rt::Handle &, const std::tuple &t) { (std::get<0>(t))->Lookup(std::get<1>(t), std::get<2>(t)); }; @@ -617,12 +647,14 @@ void LocalMultimap::AsyncLookup( } template -bool LocalMultimap::Lookup(const KTYPE & key, LookupResult * result) { +bool LocalMultimap::Lookup(const KTYPE & key, + LookupResult * result) { size_t bucketIdx = shad::hash{}(key) % numBuckets_; Bucket * bucket = &(buckets_array_[bucketIdx]); - allow_inserter(bucketIdx); // concurrent inserts okay; concurrent delete not okay - + // concurrent inserts okay; concurrent delete not okay + allow_inserter(bucketIdx); + while (bucket != nullptr) { for (size_t i = 0; i < bucket->BucketSize(); ++i) { @@ -636,7 +668,10 @@ bool LocalMultimap::Lookup(const KTYPE & key, LookupR // if key matches this entry's key, return entry's value if (KeyComp_(&entry->key, &key) == 0) { - while (!__sync_bool_compare_and_swap(&entry->state, USED, PENDING_INSERT)) rt::impl::yield(); + while (!__sync_bool_compare_and_swap(&entry->state, + USED, PENDING_INSERT)) { + rt::impl::yield(); + } result->found = true; result->size = entry->value.size(); @@ -658,11 +693,13 @@ bool LocalMultimap::Lookup(const KTYPE & key, LookupR } template -void LocalMultimap::LookupFromRemote(KTYPE & key, LookupRemoteResult * result) { +void LocalMultimap::LookupFromRemote(KTYPE & key, + LookupRemoteResult * result) { size_t bucketIdx = shad::hash{}(key) % numBuckets_; Bucket * bucket = &(buckets_array_[bucketIdx]); - allow_inserter(bucketIdx); // concurrent inserts okay; concurrent delete not okay + // concurrent inserts okay; concurrent delete not okay + allow_inserter(bucketIdx); while (bucket != nullptr) { @@ -677,17 +714,21 @@ void LocalMultimap::LookupFromRemote(KTYPE & key, Loo } // Wait for some other thread to finish with this entry - while (entry->state == PENDING_INSERT) rt::impl::yield(); - + while (entry->state == PENDING_INSERT) { + rt::impl::yield(); + } // if key matches this entry's key, return entry's value if (KeyComp_(&entry->key, &key) == 0) { - while (!__sync_bool_compare_and_swap(&entry->state, USED, PENDING_INSERT)) rt::impl::yield(); - + while (!__sync_bool_compare_and_swap(&entry->state, + USED, PENDING_INSERT)) { + rt::impl::yield(); + } result->found = true; result->size = entry->value.size(); result->remote_elems = (VTYPE *) malloc(result->size * sizeof(VTYPE)); - memcpy(result->remote_elems, entry->value.data(), result->size * sizeof(VTYPE)); + memcpy(result->remote_elems, entry->value.data(), + result->size * sizeof(VTYPE)); entry->state = USED; release_inserter(bucketIdx); @@ -731,18 +772,19 @@ void LocalMultimap::Erase(const KTYPE &key) { Bucket *bucket = &(buckets_array_[bucketIdx]); std::vector emptyValue; allow_deleter(bucketIdx); - - for (;;) { // loop over linked buckets - for (size_t i = 0; i < bucket->BucketSize(); ++i) { // loop over entries in this bucket + // loop over linked buckets + for (;;) { + // loop over entries in this bucket + for (size_t i = 0; i < bucket->BucketSize(); ++i) { Entry * entry = &bucket->getEntry(i); -// Reached first unused entry, key not found, return + // Reached first unused entry, key not found, return if (entry->state == EMPTY) { release_deleter(bucketIdx); return; } -// If key does not match this entry's key, continue inner for loop + // If key does not match this entry's key, continue inner for loop if (KeyComp_(&entry->key, &key) != 0) continue; -// Key found + // Key found size_ -= entry->value.size(); // find last USED entry in this bucket and swap with this entry @@ -752,9 +794,10 @@ void LocalMultimap::Erase(const KTYPE &key) { Entry * lastEntry = entry; size_t j = i + 1; - - for (;;) { // loop over linked buckets - for ( ; j < bucket->BucketSize(); ++j) { // loop over entries in this bucket + // loop over linked buckets + for (;;) { + // loop over entries in this bucket + for ( ; j < bucket->BucketSize(); ++j) { Entry * nextEntry = & bucket->getEntry(j); if (nextEntry->state == USED) {lastEntry = nextEntry; continue;} @@ -765,7 +808,8 @@ void LocalMultimap::Erase(const KTYPE &key) { release_deleter(bucketIdx); return; - // set entry {key, value} to lastEntry {key, value} and set lastEntry to empty + // set entry {key, value} to lastEntry {key, value} + // and set lastEntry to empty } else { entry->key = std::move(lastEntry->key); entry->value = std::move(lastEntry->value); @@ -776,8 +820,8 @@ void LocalMultimap::Erase(const KTYPE &key) { return; } } // Second inner for loop - - if (bucket->next == nullptr) { // Exhausted linked buckets, so lastEntry is last USED entry + // Exhausted linked buckets, so lastEntry is last USED entry + if (bucket->next == nullptr) { entry->key = std::move(lastEntry->key); entry->value = std::move(lastEntry->value); @@ -803,7 +847,8 @@ void LocalMultimap::Erase(const KTYPE &key) { } template -void LocalMultimap::AsyncErase(rt::Handle &handle, const KTYPE &key) { +void LocalMultimap::AsyncErase(rt::Handle &handle, + const KTYPE &key) { using LMapPtr = LocalMultimap *; auto args = std::tuple(this, key); @@ -816,13 +861,15 @@ void LocalMultimap::AsyncErase(rt::Handle &handle, co template std::pair::iterator, bool> -LocalMultimap::Insert(const KTYPE &key, const VTYPE &value) { +LocalMultimap::Insert(const KTYPE &key, + const VTYPE &value) { size_t bucketIdx = shad::hash{}(key) % numBuckets_; Bucket * bucket = &(buckets_array_[bucketIdx]); allow_inserter(bucketIdx); - - for (;;) { // loop over linked buckets - for (size_t i = 0; i < bucket->BucketSize(); ++i) { // loop over entries in this bucket + // loop over linked buckets + for (;;) { + // loop over entries in this bucket + for (size_t i = 0; i < bucket->BucketSize(); ++i) { Entry *entry = & bucket->getEntry(i); // Reached end of used entries without finding key, so new key @@ -833,7 +880,8 @@ LocalMultimap::Insert(const KTYPE &key, const VTYPE & size_ += 1; entry->state = USED; release_inserter(bucketIdx); - return std::make_pair(iterator(this, bucketIdx, i, bucket, entry, entry->value.end() - 1), true); + return std::make_pair(iterator(this, bucketIdx, i, bucket, entry, + entry->value.end() - 1), true); } // Wait for some other thread to finish with this entry @@ -841,23 +889,31 @@ LocalMultimap::Insert(const KTYPE &key, const VTYPE & // if key matches this entry's key, insert value; else continue inner for loop if (KeyComp_(&entry->key, &key) == 0) { - while (!__sync_bool_compare_and_swap(&entry->state, USED, PENDING_INSERT)) rt::impl::yield(); + while (!__sync_bool_compare_and_swap(&entry->state, + USED, PENDING_INSERT)) { + rt::impl::yield(); + } entry->value.push_back(value); size_ += 1; entry->state = USED; release_inserter(bucketIdx); - return std::make_pair(iterator(this, bucketIdx, i, bucket, entry, entry->value.end() - 1), true); + return std::make_pair(iterator(this, bucketIdx, i, bucket, entry, + entry->value.end() - 1), true); } } // Inner for loop // Exhausted entries in this buckets // ... if no more buckets, link new bucket if (bucket->next == nullptr) { - if (__sync_bool_compare_and_swap(&bucket->isNextAllocated, false, true)) { // Allocate new bucket - std::shared_ptr newBucket(new Bucket(constants::kDefaultNumEntriesPerBucket)); + if (__sync_bool_compare_and_swap(&bucket->isNextAllocated, + false, true)) { + // Allocate new bucket + std::shared_ptr newBucket( + new Bucket(constants::kMMapDefaultNumEntriesPerBucket)); bucket->next.swap(newBucket); - } else { // Wait for pending allocation to finish + } else { + // Wait for pending allocation to finish while (bucket->next == nullptr) rt::impl::yield(); } } @@ -874,7 +930,8 @@ void LocalMultimap::AsyncInsert( using LMapPtr = LocalMultimap *; auto args = std::tuple(this, key, value); - auto insertLambda = [](rt::Handle &, const std::tuple &t) { + auto insertLambda = [](rt::Handle &, + const std::tuple &t) { (std::get<0>(t))->Insert(std::get<1>(t), std::get<2>(t)); }; @@ -883,7 +940,8 @@ void LocalMultimap::AsyncInsert( template template -void LocalMultimap::ForEachEntry(ApplyFunT &&function, Args &... args) { +void LocalMultimap::ForEachEntry(ApplyFunT &&function, + Args &... args) { using FunctionTy = void (*)(const KTYPE &, VTYPE &, Args &...); FunctionTy fn = std::forward(function); @@ -891,7 +949,9 @@ void LocalMultimap::ForEachEntry(ApplyFunT &&function using ArgsTuple = std::tuple>; ArgsTuple argsTuple(this, fn, std::tuple(args...)); - rt::forEachAt(rt::thisLocality(), ForEachEntryFunWrapper, argsTuple, numBuckets_); + rt::forEachAt(rt::thisLocality(), + ForEachEntryFunWrapper, + argsTuple, numBuckets_); } template @@ -911,7 +971,8 @@ void LocalMultimap::AsyncForEachEntry( template template -void LocalMultimap::ForEachKey(ApplyFunT &&function, Args &... args) { +void LocalMultimap::ForEachKey(ApplyFunT &&function, + Args &... args) { using FunctionTy = void (*)(const KTYPE &, Args &...); FunctionTy fn = std::forward(function); @@ -919,7 +980,8 @@ void LocalMultimap::ForEachKey(ApplyFunT &&function, using ArgsTuple = std::tuple>; ArgsTuple argsTuple(this, fn, std::tuple(args...)); - rt::forEachAt(rt::thisLocality(), ForEachKeyFunWrapper, argsTuple, numBuckets_); + rt::forEachAt(rt::thisLocality(), ForEachKeyFunWrapper, + argsTuple, numBuckets_); } template @@ -948,19 +1010,22 @@ void LocalMultimap::AsyncApply( using ArgsTuple = std::tuple>; ArgsTuple argsTuple(this, key, fn, std::tuple(args...)); - rt::asyncExecuteAt(handle, rt::thisLocality(), AsyncApplyFunWrapper, argsTuple); + rt::asyncExecuteAt(handle, rt::thisLocality(), + AsyncApplyFunWrapper, argsTuple); } template template std::pair::iterator, bool> -LocalMultimap::Insert(const KTYPE &key, const ELTYPE &value) { +LocalMultimap::Insert(const KTYPE &key, + const ELTYPE &value) { size_t bucketIdx = shad::hash{}(key) % numBuckets_; Bucket *bucket = &(buckets_array_[bucketIdx]); allow_inserter(bucketIdx); - - for (;;) { // loop over linked buckets - for (size_t i = 0; i < bucket->BucketSize(); ++i) { // loop over entries in this bucket + // loop over linked buckets + for (;;) { + // loop over entries in this bucket + for (size_t i = 0; i < bucket->BucketSize(); ++i) { Entry *entry = &bucket->getEntry(i); // Reached end of used entries without finding key, so new key @@ -979,7 +1044,10 @@ LocalMultimap::Insert(const KTYPE &key, const ELTYPE //if key matches entry's key, insert value; else continue inner for loop if (KeyComp_(&entry->key, &key) == 0) { - while (!__sync_bool_compare_and_swap(&entry->state, USED, PENDING_INSERT)) rt::impl::yield(); + while (!__sync_bool_compare_and_swap(&entry->state, + USED, PENDING_INSERT)) { + rt::impl::yield(); + } entry->value.push_back(value); size_ += 1; @@ -993,10 +1061,14 @@ LocalMultimap::Insert(const KTYPE &key, const ELTYPE // Exhausted entries in this buckets // ... if no more buckets, link new bucket if (bucket->next == nullptr) { - if (__sync_bool_compare_and_swap(&bucket->isNextAllocated, false, true)) { // Allocate new bucket - std::shared_ptr newBucket( new Bucket(constants::kDefaultNumEntriesPerBucket)); + if (__sync_bool_compare_and_swap(&bucket->isNextAllocated, + false, true)) { + // Allocate new bucket + std::shared_ptr newBucket( + new Bucket(constants::kMMapDefaultNumEntriesPerBucket)); bucket->next.swap(newBucket); - } else { // Wait for pending allocation to finish + } else { + // Wait for pending allocation to finish while (bucket->next == nullptr) rt::impl::yield(); } } @@ -1086,12 +1158,14 @@ class lmultimap_iterator : public std::iterator { // if there is another entry in this bucket ... //FIXME - if (position_ < constants::kDefaultNumEntriesPerBucket) { + if (position_ < constants::kMMapDefaultNumEntriesPerBucket) { entryPtr_ ++; // if this entry is used, return begin of its value array // ... else no more entries in this bucket or buckets in this bucket list - if (entryPtr_->state == LMap::USED) {valueItr_ = entryPtr_->value.begin(); return * this;} + if (entryPtr_->state == LMap::USED) { + valueItr_ = entryPtr_->value.begin(); return * this; + } // ... else move to next bucket in this bucket list } else { @@ -1102,7 +1176,9 @@ class lmultimap_iterator : public std::iterator { // ... else no more entries in this bucket or buckets in this bucket list if (currBucket_ != nullptr) { entryPtr_ = &currBucket_->getEntry(position_); - if (entryPtr_->state == LMap::USED) {valueItr_ = entryPtr_->value.begin(); return * this;} + if (entryPtr_->state == LMap::USED) { + valueItr_ = entryPtr_->value.begin(); return * this; + } } } } @@ -1115,7 +1191,9 @@ class lmultimap_iterator : public std::iterator { for ( ; bucketId_ < mapPtr_->numBuckets_; ++bucketId_) { currBucket_ = & const_cast(mapPtr_)->buckets_array_[bucketId_]; entryPtr_ = & currBucket_->getEntry(position_); - if (entryPtr_->state == LMap::USED) {valueItr_ = entryPtr_->value.begin(); return *this;} + if (entryPtr_->state == LMap::USED) { + valueItr_ = entryPtr_->value.begin(); return *this; + } } // next is not found, return end iterator @@ -1145,15 +1223,19 @@ class lmultimap_iterator : public std::iterator { }; // split a range into at most n_parts non-empty sub-ranges - static std::vector partitions(lmultimap_iterator begin, lmultimap_iterator end, size_t n_parts) { + static std::vector partitions(lmultimap_iterator begin, + lmultimap_iterator end, + size_t n_parts) { std::vector res; auto n_buckets = n_spanned_buckets(begin, end); if (n_buckets && n_parts) { - auto part_step = (n_buckets >= n_parts) ? (n_buckets + n_parts - 1) / n_parts : 1; + auto part_step = (n_buckets >= n_parts) + ? (n_buckets + n_parts - 1) / n_parts : 1; auto map_ptr = begin.mapPtr_; auto &buckets = map_ptr->buckets_array_; - auto b_end = (end != lmultimap_end(map_ptr)) ? end.bucketId_ : map_ptr->numBuckets_; + auto b_end = (end != lmultimap_end(map_ptr)) + ? end.bucketId_ : map_ptr->numBuckets_; auto bi = begin.bucketId_; auto pbegin = begin; @@ -1182,7 +1264,8 @@ class lmultimap_iterator : public std::iterator { typename std::vector::iterator valueItr_; // returns a pointer to the first entry of a bucket - static typename LMap::Entry &first_bucket_entry(const LMap *mapPtr_, size_t bi) { + static typename LMap::Entry &first_bucket_entry(const LMap *mapPtr_, + size_t bi) { return const_cast(mapPtr_)->buckets_array_[bi].getEntry(0); } @@ -1192,7 +1275,8 @@ class lmultimap_iterator : public std::iterator { auto &entry = first_bucket_entry(mapPtr_, bi); return lmultimap_iterator(mapPtr_, bi, 0, - &const_cast(mapPtr_)->buckets_array_[bi], &entry, entry.value.begin()); + &const_cast(mapPtr_)->buckets_array_[bi], + &entry, entry.value.begin()); } // returns the index of the first active bucket, starting from the input @@ -1207,7 +1291,8 @@ class lmultimap_iterator : public std::iterator { } // returns the number of buckets spanned by the input range - static size_t n_spanned_buckets(const lmultimap_iterator &begin, const lmultimap_iterator &end) { + static size_t n_spanned_buckets(const lmultimap_iterator &begin, + const lmultimap_iterator &end) { if (begin != end) { auto map_ptr = begin.mapPtr_; @@ -1219,7 +1304,8 @@ class lmultimap_iterator : public std::iterator { if (end != lmultimap_end(map_ptr)) { // count one more if end is not on a bucket edge return end.bucketId_ - begin.bucketId_ + - (end.entryPtr_ != &first_bucket_entry(end.mapPtr_, end.bucketId_)); + (end.entryPtr_ != &first_bucket_entry(end.mapPtr_, + end.bucketId_)); } return map_ptr->numBuckets_ - begin.bucketId_; @@ -1229,7 +1315,8 @@ class lmultimap_iterator : public std::iterator { }; template -class lmultimap_key_iterator : public std::iterator { +class lmultimap_key_iterator : + public std::iterator { template friend class multimap_key_iterator; @@ -1240,7 +1327,8 @@ class lmultimap_key_iterator : public std::iterator partitions(lmultimap_key_iterator begin, - lmultimap_key_iterator end, size_t n_parts) { + lmultimap_key_iterator end, + size_t n_parts) { std::vector res; auto n_buckets = n_spanned_buckets(begin, end); if (n_buckets && n_parts) { - auto part_step = (n_buckets >= n_parts) ? (n_buckets + n_parts - 1) / n_parts : 1; + auto part_step = (n_buckets >= n_parts) + ? (n_buckets + n_parts - 1) / n_parts : 1; auto map_ptr = begin.mapPtr_; auto &buckets = map_ptr->buckets_array_; - auto b_end = (end != lmultimap_key_end(map_ptr)) ? end.bucketId_ : map_ptr->numBuckets_; + auto b_end = (end != lmultimap_key_end(map_ptr)) + ? end.bucketId_ : map_ptr->numBuckets_; auto bi = begin.bucketId_; auto pbegin = begin; @@ -1357,7 +1450,9 @@ class lmultimap_key_iterator : public std::iterator(mapPtr_)->buckets_array_[bi].getEntry(0); } - // returns an iterator pointing to the beginning of the first active bucket - // from the input bucket (included) - static lmultimap_key_iterator first_in_bucket(const LMap *mapPtr_, size_t bi) { + // returns an iterator pointing to the beginning + // of the first active bucket from the input bucket (included) + static lmultimap_key_iterator first_in_bucket(const LMap *mapPtr_, + size_t bi) { auto &entry = first_bucket_entry(mapPtr_, bi); - return lmultimap_key_iterator(mapPtr_, bi, 0, &const_cast(mapPtr_)->buckets_array_[bi], &entry); + return lmultimap_key_iterator(mapPtr_, bi, 0, + &const_cast(mapPtr_)->buckets_array_[bi], + &entry); } // returns the index of the first active bucket, starting from the input @@ -1398,7 +1497,8 @@ class lmultimap_key_iterator : public std::iteratornumBuckets_ - begin.bucketId_;