diff options
author | Ryan <ry@tinyclouds.org> | 2009-04-22 19:35:47 +0200 |
---|---|---|
committer | Ryan <ry@tinyclouds.org> | 2009-04-22 19:35:47 +0200 |
commit | 40c0f755c998d2615fe8466aab20c6d81bd463e7 (patch) | |
tree | 51fcb08ba1bd3f745ceb43fd5f814a5700079881 /deps/v8/src/hashmap.cc | |
parent | a93cf503073ba0258c55dec4dc325bdc1509b739 (diff) | |
download | node-40c0f755c998d2615fe8466aab20c6d81bd463e7.tar.gz |
import full versions of dependency libraries!
Diffstat (limited to 'deps/v8/src/hashmap.cc')
-rw-r--r-- | deps/v8/src/hashmap.cc | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/deps/v8/src/hashmap.cc b/deps/v8/src/hashmap.cc new file mode 100644 index 000000000..126f73924 --- /dev/null +++ b/deps/v8/src/hashmap.cc @@ -0,0 +1,170 @@ +// Copyright 2008 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "v8.h" + +#include "hashmap.h" + +namespace v8 { namespace internal { + + +static inline bool IsPowerOf2(uint32_t x) { + ASSERT(x != 0); + return (x & (x - 1)) == 0; +} + + +Allocator HashMap::DefaultAllocator; + + +HashMap::HashMap() { + allocator_ = NULL; + match_ = NULL; +} + + +HashMap::HashMap(MatchFun match, + Allocator* allocator, + uint32_t initial_capacity) { + allocator_ = allocator; + match_ = match; + Initialize(initial_capacity); +} + + +HashMap::~HashMap() { + if (allocator_) { + allocator_->Delete(map_); + } +} + + +HashMap::Entry* HashMap::Lookup(void* key, uint32_t hash, bool insert) { + // Find a matching entry. + Entry* p = Probe(key, hash); + if (p->key != NULL) { + return p; + } + + // No entry found; insert one if necessary. + if (insert) { + p->key = key; + p->value = NULL; + p->hash = hash; + occupancy_++; + + // Grow the map if we reached >= 80% occupancy. + if (occupancy_ + occupancy_/4 >= capacity_) { + Resize(); + p = Probe(key, hash); + } + + return p; + } + + // No entry found and none inserted. + return NULL; +} + + +void HashMap::Clear() { + // Mark all entries as empty. + const Entry* end = map_end(); + for (Entry* p = map_; p < end; p++) { + p->key = NULL; + } + occupancy_ = 0; +} + + +HashMap::Entry* HashMap::Start() const { + return Next(map_ - 1); +} + + +HashMap::Entry* HashMap::Next(Entry* p) const { + const Entry* end = map_end(); + ASSERT(map_ - 1 <= p && p < end); + for (p++; p < end; p++) { + if (p->key != NULL) { + return p; + } + } + return NULL; +} + + +HashMap::Entry* HashMap::Probe(void* key, uint32_t hash) { + ASSERT(key != NULL); + + ASSERT(IsPowerOf2(capacity_)); + Entry* p = map_ + (hash & (capacity_ - 1)); + const Entry* end = map_end(); + ASSERT(map_ <= p && p < end); + + ASSERT(occupancy_ < capacity_); // guarantees loop termination + while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) { + p++; + if (p >= end) { + p = map_; + } + } + + return p; +} + + +void HashMap::Initialize(uint32_t capacity) { + ASSERT(IsPowerOf2(capacity)); + map_ = reinterpret_cast<Entry*>(allocator_->New(capacity * sizeof(Entry))); + if (map_ == NULL) V8::FatalProcessOutOfMemory("HashMap::Initialize"); + capacity_ = capacity; + Clear(); +} + + +void HashMap::Resize() { + Entry* map = map_; + uint32_t n = occupancy_; + + // Allocate larger map. + Initialize(capacity_ * 2); + + // Rehash all current entries. + for (Entry* p = map; n > 0; p++) { + if (p->key != NULL) { + Lookup(p->key, p->hash, true)->value = p->value; + n--; + } + } + + // Delete old map. + allocator_->Delete(map); +} + + +} } // namespace v8::internal |