#ifndef SHARDED_SET_INL_H_ #error "Direct inclusion of this file is not allowed, include sharded_set.h" // For the sake of sane code completion. #include "sharded_set.h" #endif #include namespace NYT { //////////////////////////////////////////////////////////////////////////////// template class TShardedSet::const_iterator { private: friend class TShardedSet; using TOwner = TShardedSet; using TShardIterator = typename S::const_iterator; const TOwner* const Owner_; int ShardIndex_; TShardIterator ShardIterator_; const_iterator( const TOwner* owner, int shardIndex, TShardIterator shardIterator) : Owner_(owner) , ShardIndex_(shardIndex) , ShardIterator_(shardIterator) { } bool IsValid() const { return ShardIterator_ != Owner_->Shards_[ShardIndex_].end(); } void FastForward() { while (ShardIndex_ != N - 1 && !IsValid()) { ++ShardIndex_; ShardIterator_ = Owner_->Shards_[ShardIndex_].begin(); } } public: using difference_type = typename std::iterator_traits::difference_type; using value_type = typename std::iterator_traits::value_type; using pointer = typename std::iterator_traits::pointer; using reference = typename std::iterator_traits::reference; using iterator_category = std::forward_iterator_tag; const_iterator& operator++() { ++ShardIterator_; FastForward(); return *this; } const_iterator operator++(int) { auto result = *this; ++ShardIterator_; FastForward(); return result; } bool operator==(const const_iterator& rhs) const { return ShardIndex_ == rhs.ShardIndex_ && ShardIterator_ == rhs.ShardIterator_; } bool operator!=(const const_iterator& rhs) const { return !(*this == rhs); } const T& operator*() const { return *ShardIterator_; } const T* operator->() const { return &operator*(); } }; //////////////////////////////////////////////////////////////////////////////// template TShardedSet::TShardedSet(F elementToShard) : ElementToShard_(elementToShard) { } template bool TShardedSet::empty() const { return size() == 0; } template typename TShardedSet::size_type TShardedSet::size() const { size_type result = 0; for (const auto& shard : Shards_) { result += shard.size(); } return result; } template const T& TShardedSet::front() const { return *begin(); } template typename TShardedSet::size_type TShardedSet::count(const T& value) const { return GetShard(value).count(value); } template bool TShardedSet::contains(const T& value) const { return GetShard(value).contains(value); } template std::pair::const_iterator, bool> TShardedSet::insert(const T& value) { auto shardIndex = ElementToShard_(value); auto& shard = Shards_[shardIndex]; auto [shardIterator, inserted] = shard.insert(value); const_iterator iterator(this, shardIndex, shardIterator); return {iterator, inserted}; } template bool TShardedSet::erase(const T& value) { return GetShard(value).erase(value); } template void TShardedSet::clear() { for (auto& shard : Shards_) { shard.clear(); } } template typename TShardedSet::const_iterator TShardedSet::begin() const { const_iterator iterator(this, /*shardIndex*/ 0, /*shardIterator*/ Shards_[0].begin()); iterator.FastForward(); return iterator; } template typename TShardedSet::const_iterator TShardedSet::cbegin() const { return begin(); } template typename TShardedSet::const_iterator TShardedSet::end() const { return const_iterator(this, /*shardIndex*/ N - 1, /*shardIterator*/ Shards_[N - 1].end()); } template typename TShardedSet::const_iterator TShardedSet::cend() const { return end(); } template const S& TShardedSet::Shard(int shardIndex) const { return Shards_[shardIndex]; } template S& TShardedSet::MutableShard(int shardIndex) { return Shards_[shardIndex]; } template S& TShardedSet::GetShard(const T& value) { return Shards_[ElementToShard_(value)]; } template const S& TShardedSet::GetShard(const T& value) const { return Shards_[ElementToShard_(value)]; } //////////////////////////////////////////////////////////////////////////////// } // namespace NYT