Index: runtime/vm/weak_table.cc |
=================================================================== |
--- runtime/vm/weak_table.cc (revision 0) |
+++ runtime/vm/weak_table.cc (revision 0) |
@@ -0,0 +1,72 @@ |
+// Copyright (c) 2013, 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. |
+ |
+#include "vm/weak_table.h" |
+ |
+#include "platform/assert.h" |
+#include "vm/raw_object.h" |
+ |
+namespace dart { |
+ |
+WeakTable* WeakTable::SetValue(RawObject* key, intptr_t val) { |
+ intptr_t sz = size(); |
+ intptr_t idx = Hash(key) % sz; |
+ intptr_t empty_idx = -1; |
+ RawObject* obj = ObjectAt(idx); |
+ |
+ while (obj != NULL) { |
+ if (obj == key) { |
+ SetValueAt(idx, val); |
+ return this; |
+ } else if ((empty_idx < 0) && |
+ (reinterpret_cast<intptr_t>(obj) == kDeletedEntry)) { |
+ empty_idx = idx; // Insert at this location if not found. |
+ } |
+ idx = (idx + 1) % sz; |
+ obj = ObjectAt(idx); |
+ } |
+ |
+ if (val == 0) { |
+ // Do not enter an invalid value. Associating 0 with a key deletes it from |
+ // this weak table above in SetValueAt. If the key was not present in the |
+ // weak table we are done. |
+ return this; |
+ } |
+ |
+ if (empty_idx >= 0) { |
+ // We will be reusing a slot below. |
+ set_used(used() - 1); |
+ idx = empty_idx; |
+ } |
+ |
+ ASSERT(!IsValidEntryAt(idx)); |
+ // Set the key and value. |
+ SetObjectAt(idx, key); |
+ SetValueAt(idx, val); |
+ // Update the counts. |
+ set_used(used() + 1); |
+ set_count(count() + 1); |
+ |
+ // Rehash if needed to ensure that there are empty slots available. |
+ if (used_ >= limit()) { |
+ return Rehash(); |
+ } |
+ return this; |
+} |
+ |
+ |
+WeakTable* WeakTable::Rehash() { |
+ intptr_t sz = size(); |
+ WeakTable* result = NewFrom(this); |
+ |
+ for (intptr_t i = 0; i < sz; i++) { |
+ if (IsValidEntryAt(i)) { |
+ WeakTable* temp = result->SetValue(ObjectAt(i), ValueAt(i)); |
+ ASSERT(temp == result); |
+ } |
+ } |
+ return result; |
+} |
+ |
+} // namespace dart |