ssize_t APCArray::indexOf(const StringData* key) const { strhash_t h = key->hash(); ssize_t bucket = hash()[h & m.m_capacity_mask]; Bucket* b = buckets(); while (bucket != -1) { if (!IS_REFCOUNTED_TYPE(b[bucket].key->getType())) { APCTypedValue *k = APCTypedValue::fromHandle(b[bucket].key); if (!b[bucket].key->is(KindOfInt64) && key->same(k->getStringData())) { return bucket; } } else { assert(b[bucket].key->is(KindOfString)); APCString *k = APCString::fromHandle(b[bucket].key); if (key->same(k->getStringData())) { return bucket; } } bucket = b[bucket].next; } return -1; }
void APCArray::add(APCHandle *key, APCHandle *val) { int pos = m.m_num; // NOTE: no check on duplication because we assume the original array has no // duplication Bucket* bucket = buckets() + pos; bucket->key = key; bucket->val = val; m.m_num++; int hash_pos; if (!IS_REFCOUNTED_TYPE(key->getType())) { APCTypedValue *k = APCTypedValue::fromHandle(key); hash_pos = (key->is(KindOfInt64) ? k->getInt64() : k->getStringData()->hash()) & m.m_capacity_mask; } else { assert(key->is(KindOfString)); APCString *k = APCString::fromHandle(key); hash_pos = k->getStringData()->hash() & m.m_capacity_mask; } int& hp = hash()[hash_pos]; bucket->next = hp; hp = pos; }