| Index: runtime/vm/hash_set.h
 | 
| ===================================================================
 | 
| --- runtime/vm/hash_set.h	(revision 0)
 | 
| +++ runtime/vm/hash_set.h	(revision 0)
 | 
| @@ -0,0 +1,97 @@
 | 
| +// 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_;
 | 
| +  }
 | 
| +
 | 
| +  // 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 contains 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_
 | 
| 
 |