ALWAYS_INLINE void BaseSet::addImpl(StringData *key) { if (!raw) { mutate(); } strhash_t h = key->hash(); auto p = findForInsert(key, h); assert(p); if (validPos(*p)) { return; } if (UNLIKELY(isFull())) { makeRoom(); p = findForInsert(key, h); } auto& e = allocElm(p); // This increments the string's refcount twice, once for // the key and once for the value e.setStrKey(key, h); cellDup(make_tv<KindOfString>(key), e.data); updateIntLikeStrKeys(key); if (!raw) { ++m_version; } }
ALWAYS_INLINE void BaseMap::setImpl(StringData* key, const TypedValue* val) { if (!raw) { mutate(); } assert(val->m_type != KindOfRef); assert(canMutateBuffer()); retry: strhash_t h = key->hash(); auto* p = findForInsert(key, h); assert(p); if (validPos(*p)) { auto& e = data()[*p]; TypedValue old = e.data; cellDup(*val, e.data); tvRefcountedDecRef(old); return; } if (UNLIKELY(isFull())) { makeRoom(); goto retry; } if (!raw) { ++m_version; } auto& e = allocElm(p); cellDup(*val, e.data); e.setStrKey(key, h); updateIntLikeStrKeys(key); }
ALWAYS_INLINE void BaseSet::addImpl(int64_t k) { if (!raw) { mutate(); } auto h = hashint(k); auto p = findForInsert(k, h); assert(p); if (validPos(*p)) { // When there is a conflict, the add() API is supposed to replace the // existing element with the new element in place. However since Sets // currently only support integer and string elements, there is no way // user code can really tell whether the existing element was replaced // so for efficiency we do nothing. return; } if (UNLIKELY(isFull())) { makeRoom(); p = findForInsert(k, h); } auto& e = allocElm(p); e.setIntKey(k, h); e.data.m_type = KindOfInt64; e.data.m_data.num = k; updateNextKI(k); if (!raw) { ++m_version; } }
ALWAYS_INLINE void BaseMap::setImpl(int64_t h, const TypedValue* val) { if (!raw) { mutate(); } assert(val->m_type != KindOfRef); assert(canMutateBuffer()); retry: auto p = findForInsert(h); assert(p); if (validPos(*p)) { auto& e = data()[*p]; TypedValue old = e.data; cellDup(*val, e.data); tvRefcountedDecRef(old); return; } if (UNLIKELY(isFull())) { makeRoom(); goto retry; } if (!raw) { ++m_version; } auto& e = allocElm(p); cellDup(*val, e.data); e.setIntKey(h); updateNextKI(h); }