| // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| #ifndef VM_HASH_SET_H_ |
| #define VM_HASH_SET_H_ |
| |
| #include "vm/allocation.h" |
| #include "platform/utils.h" |
| |
| namespace dart { |
| |
| class HashSet { |
| public: |
| HashSet(intptr_t size, intptr_t fill_ratio) |
| : keys_(new uword[size]), |
| size_mask_(size - 1), |
| growth_limit_((size * fill_ratio) / 100), |
| count_(0), |
| fill_ratio_(fill_ratio) { |
| ASSERT(Utils::IsPowerOfTwo(size)); |
| ASSERT(fill_ratio < 100); |
| memset(keys_, 0, size * sizeof(*keys_)); |
| } |
| |
| ~HashSet() { |
| delete[] keys_; |
| } |
| |
| intptr_t Size() const { |
| return size_mask_ + 1; |
| } |
| |
| intptr_t Count() const { |
| return count_; |
| } |
| |
| uword At(intptr_t i) const { |
| ASSERT(i >= 0); |
| ASSERT(i < Size()); |
| return keys_[i]; |
| } |
| |
| // Returns false if the caller should stop adding entries to this HashSet. |
| bool Add(uword value) { |
| ASSERT(value != 0); |
| ASSERT(count_ < growth_limit_); |
| intptr_t hash = Hash(value); |
| while (true) { |
| if (keys_[hash] == value) { |
| return true; |
| } else if (SlotIsEmpty(hash)) { |
| keys_[hash] = value; |
| count_++; |
| return (count_ < growth_limit_); |
| } |
| hash = (hash + 1) & size_mask_; |
| // Ensure that we do not end up looping forever. |
| ASSERT(hash != Hash(value)); |
| } |
| UNREACHABLE(); |
| } |
| |
| bool Contains(uword value) const { |
| if (value == 0) { |
| return false; |
| } |
| intptr_t hash = Hash(value); |
| while (true) { |
| if (keys_[hash] == value) { |
| return true; |
| } else if (SlotIsEmpty(hash)) { |
| return false; |
| } |
| hash = (hash + 1) & size_mask_; |
| // Ensure that we do not end up looping forever. |
| ASSERT(hash != Hash(value)); |
| } |
| UNREACHABLE(); |
| } |
| |
| private: |
| intptr_t Hash(uword value) const { |
| return value & size_mask_; |
| } |
| |
| // Returns true if the given slot does not contain a value. |
| bool SlotIsEmpty(intptr_t index) const { |
| return keys_[index] == 0; |
| } |
| |
| uword* keys_; |
| intptr_t size_mask_; |
| intptr_t growth_limit_; |
| intptr_t count_; |
| intptr_t fill_ratio_; |
| |
| DISALLOW_IMPLICIT_CONSTRUCTORS(HashSet); |
| }; |
| |
| } // namespace dart |
| |
| #endif // VM_HASH_SET_H_ |