void test_fetch_returns_given_when_not_found() { TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0); tbl->store(state, cNil, Fixnum::from(47)); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1); Object* out = tbl->fetch(state, cTrue, cUndef); TS_ASSERT_EQUALS(cUndef, out); }
void test_store_fetch() { TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0); tbl->store(state, cNil, Fixnum::from(47)); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1); Object* out = tbl->aref(state, cNil); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47); }
void test_fetch_returns_found() { TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0); tbl->store(state, Qnil, Fixnum::from(47)); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1); Object* out = tbl->fetch(state, Qnil, Qundef); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47); }
void test_store_overwrites_previous() { TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0); tbl->store(state, Qnil, Fixnum::from(47)); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1); Object* out = tbl->aref(state, Qnil); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 47); tbl->store(state, Qnil, Fixnum::from(42)); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 1); out = tbl->aref(state, Qnil); TS_ASSERT_EQUALS(as<Integer>(out)->to_native(), 42); }
/* Look at this class and it's superclass contents (which includes * included modules) and calculate out how to allocate the slots. * * This locks the class so that construction is serialized. */ void Class::auto_pack(STATE, GCToken gct) { Class* self = this; OnStack<1> os(state, self); hard_lock(state, gct); // If another thread did this work while we were waiting on the lock, // don't redo it. if(self->type_info_->type == PackedObject::type) { hard_unlock(state, gct); return; } size_t slots = 0; LookupTable* lt = LookupTable::create(state); // If autopacking is enabled, figure out how many slots to use. if(state->shared().config.gc_autopack) { Module* mod = self; int slot = 0; while(!mod->nil_p()) { Array* info = 0; if(Class* cls = try_as<Class>(mod)) { info = cls->seen_ivars(); } else if(IncludedModule* im = try_as<IncludedModule>(mod)) { info = im->module()->seen_ivars(); } if(info && !info->nil_p()) { for(size_t i = 0; i < info->size(); i++) { if(Symbol* sym = try_as<Symbol>(info->get(state, i))) { bool found = false; lt->fetch(state, sym, &found); if(!found) { lt->store(state, sym, Fixnum::from(slot++)); } } // Limit the number of packed ivars to 25. if(slot > 25) break; } } mod = mod->superclass(); } slots = lt->entries()->to_native(); } packed_size_ = sizeof(Object) + (slots * sizeof(Object*)); self->packed_ivar_info(state, lt); self->set_object_type(state, PackedObject::type); self->hard_unlock(state, gct); }
void test_remove_works_for_chained_bins() { Object* k1 = Fixnum::from((4 << 5) | 31); Object* k2 = Fixnum::from((10 << 5) | 31); Object* k3 = Fixnum::from((11 << 5) | 31); tbl->store(state, k1, cNil); tbl->store(state, k2, cTrue); tbl->store(state, k3, cFalse); TS_ASSERT_EQUALS(tbl->remove(state, k3), cFalse); TS_ASSERT_EQUALS(tbl->remove(state, k2), cTrue); TS_ASSERT_EQUALS(tbl->remove(state, k1), cNil); TS_ASSERT_EQUALS(0, as<Integer>(tbl->entries())->to_native()); }
void test_remove() { Object* k = Fixnum::from(47); tbl->store(state, k, cTrue); Object* out = tbl->find(state, k); TS_ASSERT_EQUALS(out, cTrue); out = tbl->remove(state, k); TS_ASSERT_EQUALS(out, cTrue); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 0); out = tbl->fetch(state, k); TS_ASSERT_EQUALS(out, cNil); }
void test_store_resizes_table() { size_t i; size_t bins = tbl-> bins()->to_native(); for(i = 0; i < bins; i++) { tbl->store(state, Fixnum::from(i), Fixnum::from(i)); } TS_ASSERT_EQUALS(i, (size_t)as<Integer>(tbl->entries())->to_native()); TS_ASSERT((size_t)(tbl-> bins()->to_native()) > bins); for(i = 0; i < bins; i++) { TS_ASSERT_EQUALS(Fixnum::from(i), tbl->aref(state, Fixnum::from(i))); } }
void LookupTable::Info::show(STATE, Object* self, int level) { LookupTable* tbl = as<LookupTable>(self); size_t size = tbl->entries()->to_native(); Array* keys = tbl->all_keys(state); if(size == 0) { class_info(state, self, true); return; } class_info(state, self); std::cout << ": " << size << std::endl; indent(++level); for(size_t i = 0; i < size; i++) { std::cout << ":" << as<Symbol>(keys->get(state, i))->c_str(state); if(i < size - 1) std::cout << ", "; } std::cout << std::endl; close_body(level); }
void test_store_handles_entries_in_same_bin() { Object* k1 = Fixnum::from((4 << 4) | 15); Object* k2 = Fixnum::from((10 << 4) | 15); Object* k3 = Fixnum::from((11 << 4) | 15); Object* v1 = cTrue; Object* v2 = cFalse; Object* v3 = cTrue; tbl->store(state, k1, v1); tbl->store(state, k2, v2); tbl->store(state, k3, v3); TS_ASSERT_EQUALS(as<Integer>(tbl->entries())->to_native(), 3); LookupTableBucket* entry = tbl->find_entry(state, k1); TS_ASSERT(entry != cNil); TS_ASSERT(entry->next() != cNil); TS_ASSERT_EQUALS(entry->next()->key(), k2); entry = tbl->find_entry(state, k3); TS_ASSERT(entry != cNil); TS_ASSERT_EQUALS(entry->key(), k3); }