Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1901)

Unified Diff: src/hashmap.cc

Issue 113397: Add a remove method to the hash map (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hashmap.h ('k') | test/cctest/test-hashmap.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hashmap.cc
===================================================================
--- src/hashmap.cc (revision 1955)
+++ src/hashmap.cc (working copy)
@@ -59,7 +59,7 @@
HashMap::Entry* HashMap::Lookup(void* key, uint32_t hash, bool insert) {
// Find a matching entry.
Entry* p = Probe(key, hash);
- if (p->key != NULL) {
+ if (p->key != NULL) {
return p;
}
@@ -84,6 +84,64 @@
}
+void HashMap::Remove(void* key, uint32_t hash) {
+ // Lookup the entry for the key to remove.
+ Entry *p = Probe(key, hash);
+ if (p->key == NULL) {
+ // Key not found nothing to remove.
+ return;
+ }
+
+ // To remove the entry we need to ensure that it does not create an empty
+ // entry that will cause search for an entry to stop to soon. If all the
Dean McNamee 2009/05/15 07:24:00 too soon
+ // entries between the entry to remove and the next empty slot have their
+ // initial position inside this interval clearing the entry to remove will not
Dean McNamee 2009/05/15 07:24:00 interval,
+ // break the search. If while searching for the next empty entry an entry is
+ // encountered which does not have its initial position between the entry to
+ // remove and the position looked at this entry can be moved to the place of
Dean McNamee 2009/05/15 07:24:00 looked at,
+ // the entry to remove without breaking the search for it and the new entry to
+ // remove will be its previous position.
Dean McNamee 2009/05/15 07:24:00 runon :)
+ // Algorithm from http://en.wikipedia.org/wiki/Open_addressing.
+
+ // This guarantees loop termination as there is at least one empty entry so
+ // eventually the removed entyr will have an empty entry after it.
Dean McNamee 2009/05/15 07:24:00 entry
+ ASSERT(occupancy_ < capacity_);
+
+ // p is the candidate entry to clear. q is used to scan forwards.
+ Entry* q = p; // Start at the entry to remove.
+ while (true) {
+ // Move q to the next entry.
+ q = q + 1;
+ if (q == map_end()) {
+ q = map_;
+ }
+
+ // All entries between p and q have their initial position between p and q
+ // and the entry p can be cleared without breaking the search for these
+ // entries.
+ if (q->key == NULL) {
+ break;
+ }
+
+ // Find the initial position for the entry at position q.
+ Entry* r = map_ + (q->hash & (capacity_ - 1));
+
+ // If the entry at position q has its initial position outside the range
+ // between p and q it can be moved forward to position p and will still be
+ // found. There is now a new candidate entry for clearing.
+ if (q > p && (r <= p || r > q) ||
+ q < p && (r <= p && r > q)) {
+ *p = *q;
+ p = q;
+ }
+ }
+
+ // Clear the entry which is allowed to en emptied.
+ p->key = NULL;
+ occupancy_--;
+}
+
+
void HashMap::Clear() {
// Mark all entries as empty.
const Entry* end = map_end();
@@ -119,7 +177,7 @@
const Entry* end = map_end();
ASSERT(map_ <= p && p < end);
- ASSERT(occupancy_ < capacity_); // guarantees loop termination
+ ASSERT(occupancy_ < capacity_); // Guarantees loop termination.
while (p->key != NULL && (hash != p->hash || !match_(key, p->key))) {
p++;
if (p >= end) {
« no previous file with comments | « src/hashmap.h ('k') | test/cctest/test-hashmap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698