예제 #1
0
  Object* LookupTable::store(STATE, Object* key, Object* val) {
    unsigned int num_entries, num_bins, bin;
    LookupTableBucket* entry;
    LookupTableBucket* last = NULL;

    num_entries = entries_->to_native();
    num_bins = bins_->to_native();

    if(max_density_p(num_entries, num_bins)) {
      redistribute(state, num_bins <<= 1);
    }

    key_to_sym(key);
    bin = find_bin(key_hash(key), num_bins);
    entry = try_as<LookupTableBucket>(values_->at(state, bin));

    while(entry) {
      if(entry->key() == key) {
        entry->value(state, val);
        return val;
      }
      last = entry;
      entry = try_as<LookupTableBucket>(entry->next());
    }

    if(last) {
      last->next(state, LookupTableBucket::create(state, key, val));
    } else {
      values_->put(state, bin, LookupTableBucket::create(state, key, val));
    }

    entries(state, Fixnum::from(num_entries + 1));
    return val;
  }
예제 #2
0
 /* lookuptable_find returns Qundef if there is not entry
  * referenced by 'key' in the LookupTable. This is useful
  * to distinguish x = {} from x = {:a => nil} and is used
  * in cpu.c in e.g. cpu_const_get_in_context.
  */
 Object* LookupTable::find(STATE, Object* key) {
   LookupTableBucket* entry = find_entry(state, key);
   if(entry == Qnil) {
     return Qundef;
   }
   return entry->value();
 }
예제 #3
0
  Object* LookupTable::remove(STATE, Object* key, bool* removed) {
    hashval bin;
    LookupTableBucket* entry;
    LookupTableBucket* last = NULL;

    size_t num_entries = entries_->to_native();
    size_t num_bins = bins_->to_native();

    if(min_density_p(num_entries, num_bins) && (num_bins >> 1) >= LOOKUPTABLE_MIN_SIZE) {
      redistribute(state, num_bins >>= 1);
    }

    key_to_sym(key);
    bin = find_bin(key_hash(key), num_bins);
    entry = try_as<LookupTableBucket>(values_->at(state, bin));

    while(entry) {
      if(entry->key() == key) {
        Object *val = entry->value();
        if(last) {
          last->next(state, entry->next());
        } else {
          values_->put(state, bin, entry->next());
        }
        entries(state, Fixnum::from(entries_->to_native() - 1));
        if(removed) *removed = true;
        return val;
      }

      last = entry;
      entry = try_as<LookupTableBucket>(entry->next());
    }

    return Qnil;
  }
예제 #4
0
  LookupTableBucket* LookupTableBucket::create(STATE, Object *key, Object *value) {
    LookupTableBucket *entry =
      state->new_object<LookupTableBucket>(G(lookuptablebucket));

    entry->key(state, key);
    entry->value(state, value);
    return entry;
  }
예제 #5
0
  Object* LookupTable::fetch(STATE, Object* key, Object* return_on_failure) {
    LookupTableBucket* entry = find_entry(state, key);

    if(entry == Qnil) {
      return return_on_failure;
    }

    return entry->value();
  }
예제 #6
0
  Object* LookupTable::fetch(STATE, Object* key, bool* found) {
    LookupTableBucket* entry = find_entry(state, key);
    if(entry == Qnil) {
      *found = false;
      return Qnil;
    }

    *found = true;
    return entry->value();
  }
예제 #7
0
  void test_find_entry() {
    Object* k = Fixnum::from(47);
    tbl->store(state, k, cTrue);

    LookupTableBucket* entry = tbl->find_entry(state, k);
    TS_ASSERT(entry != cNil);
    TS_ASSERT_EQUALS(entry->key(),k);
    TS_ASSERT_EQUALS(entry->value(),cTrue);

    entry = tbl->find_entry(state, Fixnum::from(40));
    TS_ASSERT(entry == cNil);
  }
예제 #8
0
  LookupTable* LookupTable::duplicate(STATE) {
    size_t size, i;
    LookupTable *dup;

    size = bins_->to_native();
    dup = LookupTable::create(state, size);

    // Allow for subclassing.
    dup->klass(state, class_object(state));

    size_t num = entries_->to_native();

    Array* entries = all_entries(state);
    for(i = 0; i < num; i++) {
      LookupTableBucket* entry = as<LookupTableBucket>(entries->get(state, i));
      dup->store(state, entry->key(), entry->value());
    }
    return dup;
  }
예제 #9
0
 /** Same as aref(state, key). */
 Object* LookupTable::fetch(STATE, Object* key) {
   LookupTableBucket* entry = find_entry(state, key);
   if(entry == Qnil) return Qnil;
   return entry->value();
 }
예제 #10
0
/** Same as fetch(state, key). */
Object* LookupTable::aref(STATE, Object* key) {
    LookupTableBucket* entry = find_entry(state, key);
    if(entry == cNil) return cNil;
    return entry->value();
}