Variant SharedVariant::getKey(ssize_t pos) const { assert(is(KindOfArray)); if (getIsVector()) { assert(pos < (ssize_t) m_data.vec->m_size); return pos; } return m_data.map->getKeyIndex(pos)->toLocal(); }
int SharedVariant::getIndex(int64_t key) { assert(is(KindOfArray)); if (getIsVector()) { if (key < 0 || (size_t) key >= m_data.vec->m_size) return -1; return key; } return m_data.map->indexOf(key); }
void SharedVariant::getStats(SharedVariantStats *stats) const { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfUninit: case KindOfNull: case KindOfBoolean: case KindOfInt64: case KindOfDouble: case KindOfStaticString: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(SharedVariant); break; case KindOfObject: if (getIsObj()) { SharedVariantStats childStats; m_data.obj->getSizeStats(&childStats); stats->addChildStats(&childStats); break; } // fall through case KindOfString: stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; default: assert(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(SharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (getIsVector()) { stats->dataTotalSize = sizeof(SharedVariant) + sizeof(VectorData); stats->dataTotalSize += sizeof(SharedVariant*) * m_data.vec->m_size; for (size_t i = 0; i < m_data.vec->m_size; i++) { SharedVariant *v = m_data.vec->vals()[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else { ImmutableMap *map = m_data.map; stats->dataTotalSize = sizeof(SharedVariant) + map->getStructSize(); for (int i = 0; i < map->size(); i++) { SharedVariantStats childStats; map->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); map->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }
HOT_FUNC SharedVariant* SharedVariant::getValue(ssize_t pos) const { assert(is(KindOfArray)); if (getIsVector()) { assert(pos < (ssize_t) m_data.vec->m_size); return m_data.vec->vals()[pos]; } return m_data.map->getValIndex(pos); }
void ThreadSharedVariant::getStats(SharedVariantStats *stats) { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfBoolean: case KindOfInt64: stats->dataSize = sizeof(m_data.num); stats->dataTotalSize = sizeof(ThreadSharedVariant); break; case KindOfDouble: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(ThreadSharedVariant); break; case KindOfString: case KindOfObject: if (m_data.str->isStatic()) { stats->dataSize = 0; stats->dataTotalSize = sizeof(ThreadSharedVariant); break; } stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (getIsVector()) { stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(VectorData); stats->dataTotalSize += sizeof(ThreadSharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { ThreadSharedVariant *v = m_data.vec->vals[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else { ImmutableMap *map = m_data.map; stats->dataTotalSize = sizeof(ThreadSharedVariant) + map->getStructSize(); for (int i = 0; i < map->size(); i++) { SharedVariantStats childStats; map->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); map->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }
int ThreadSharedVariant::getIndex(litstr key) { ASSERT(is(KindOfArray)); if (getIsVector()) return -1; StringData sd(key); if (RuntimeOption::ApcUseGnuMap) { StringDataToIntMap::const_iterator it = m_data.gnuMap->strMap->find(&sd); if (it == m_data.gnuMap->strMap->end()) return -1; return it->second; } return m_data.map->indexOf(&sd); }
void ThreadSharedVariant::loadElems(ArrayData *&elems, const SharedMap &sharedMap, bool keepRef /* = false */) { ASSERT(is(KindOfArray)); uint count = arrSize(); ArrayInit ai(count, getIsVector(), keepRef); for (uint i = 0; i < count; i++) { if (getIsVector()) { ai.add((int64)i, sharedMap.getValue(i), true); } else { if (RuntimeOption::ApcUseGnuMap) { ai.add(m_data.gnuMap->keys[i]->toLocal(), sharedMap.getValue(i), true); } else { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValue(i), true); } } } elems = ai.create(); if (elems->isStatic()) elems = elems->copy(); }
int ThreadSharedVariant::getIndex(int64 key) { ASSERT(is(KindOfArray)); if (getIsVector()) { if (key < 0 || (size_t) key >= m_data.vec->size) return -1; return key; } if (RuntimeOption::ApcUseGnuMap) { Int64ToIntMap::const_iterator it = m_data.gnuMap->intMap->find(key); if (it == m_data.gnuMap->intMap->end()) return -1; return it->second; } return m_data.map->indexOf(key); }
int SharedVariant::countReachable() const { int count = 1; if (getType() == KindOfArray) { int size = arrSize(); if (!getIsVector()) { count += size; // for keys } for (int i = 0; i < size; i++) { SharedVariant* p = getValue(i); count += p->countReachable(); // for values } } return count; }
HOT_FUNC int SharedVariant::getIndex(CVarRef key) { ASSERT(is(KindOfArray)); switch (key.getType()) { case KindOfInt64: { int64 num = key.getNumData(); if (getIsVector()) { if (num < 0 || (size_t) num >= m_data.vec->size) return -1; return num; } return m_data.map->indexOf(num); } case KindOfStaticString: case KindOfString: { if (getIsVector()) return -1; StringData *sd = key.getStringData(); return m_data.map->indexOf(sd); } default: // No other types are legitimate keys break; } return -1; }
int ThreadSharedVariant::getIndex(CVarRef key) { ASSERT(is(KindOfArray)); switch (key.getType()) { case KindOfByte: case KindOfInt16: case KindOfInt32: case KindOfInt64: { int64 num = key.getNumData(); if (getIsVector()) { if (num < 0 || (size_t) num >= m_data.vec->size) return -1; return num; } if (RuntimeOption::ApcUseGnuMap) { Int64ToIntMap::const_iterator it = m_data.gnuMap->intMap->find(num); if (it == m_data.gnuMap->intMap->end()) return -1; return it->second; } return m_data.map->indexOf(num); } case KindOfStaticString: case KindOfString: { if (getIsVector()) return -1; StringData *sd = key.getStringData(); if (RuntimeOption::ApcUseGnuMap) { StringDataToIntMap::const_iterator it = m_data.gnuMap->strMap->find(sd); if (it == m_data.gnuMap->strMap->end()) return -1; return it->second; } return m_data.map->indexOf(sd); } default: // No other types are legitimate keys break; } return -1; }
void SharedVariant::loadElems(ArrayData *&elems, const SharedMap &sharedMap, bool keepRef /* = false */) { ASSERT(is(KindOfArray)); uint count = arrSize(); bool isVector = getIsVector(); ArrayInit ai = isVector ? ArrayInit(count, ArrayInit::vectorInit) : ArrayInit(count, keepRef); if (isVector) { for (uint i = 0; i < count; i++) { ai.set(sharedMap.getValueRef(i)); } } else { for (uint i = 0; i < count; i++) { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValueRef(i), true); } } elems = ai.create(); if (elems->isStatic()) elems = elems->copy(); }
ArrayData* SharedVariant::loadElems(const SharedMap &sharedMap) { assert(is(KindOfArray)); auto count = arrSize(); ArrayData* elems; if (getIsVector()) { VectorInit ai(count); for (uint i = 0; i < count; i++) { ai.add(sharedMap.getValueRef(i)); } elems = ai.create(); } else { ArrayInit ai(count); for (uint i = 0; i < count; i++) { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValueRef(i), true); } elems = ai.create(); } if (elems->isStatic()) elems = elems->copy(); return elems; }
int32 ThreadSharedVariant::getSpaceUsage() { int32 size = sizeof(ThreadSharedVariant); if (m_type <= KindOfDouble) return size; switch (m_type) { case KindOfObject: if (getIsObj()) { return size + m_data.obj->getSpaceUsage(); } // fall through case KindOfString: if (m_data.str->isStatic()) { break; } size += sizeof(StringData) + m_data.str->size(); break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { size += sizeof(StringData) + m_data.str->size(); } else if (getIsVector()) { size += sizeof(VectorData) + sizeof(ThreadSharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { size += m_data.vec->vals[i]->getSpaceUsage(); } } else if (RuntimeOption::ApcUseGnuMap) { // Not accurate size += sizeof(MapData); } else { ImmutableMap *map = m_data.map; size += map->getStructSize(); for (int i = 0; i < map->size(); i++) { size += map->getKeyIndex(i)->getSpaceUsage(); size += map->getValIndex(i)->getSpaceUsage(); } } break; } return size; }
ArrayData* SharedVariant::loadElems(const SharedMap &sharedMap, bool mapInit /* = false */) { assert(is(KindOfArray)); uint count = arrSize(); bool isVector = getIsVector(); ArrayInit ai = mapInit ? ArrayInit(count, ArrayInit::mapInit) : isVector ? ArrayInit(count, ArrayInit::vectorInit) : ArrayInit(count); if (isVector) { for (uint i = 0; i < count; i++) { ai.set(sharedMap.getValueRef(i)); } } else { for (uint i = 0; i < count; i++) { ai.add(m_data.map->getKeyIndex(i)->toLocal(), sharedMap.getValueRef(i), true); } } ArrayData* elems = ai.create(); if (elems->isStatic()) elems = elems->copy(); return elems; }
ThreadSharedVariant::~ThreadSharedVariant() { switch (m_type) { case KindOfObject: if (getIsObj()) { delete m_data.obj; break; } // otherwise fall through case KindOfString: if (getOwner()) { m_data.str->destruct(); } break; case KindOfArray: { if (getSerializedArray()) { if (getOwner()) { m_data.str->destruct(); } break; } ASSERT(getOwner()); if (getIsVector()) { delete m_data.vec; } else if (RuntimeOption::ApcUseGnuMap) { delete m_data.gnuMap; } else { delete m_data.map; } } break; default: break; } }
size_t ThreadSharedVariant::arrSize() const { ASSERT(is(KindOfArray)); if (getIsVector()) return m_data.vec->size; if (RuntimeOption::ApcUseGnuMap) return m_data.gnuMap->size; return m_data.map->size(); }
int SharedVariant::getIndex(litstr key) { ASSERT(is(KindOfArray)); if (getIsVector()) return -1; StringData sd(key); return m_data.map->indexOf(&sd); }
int SharedVariant::getIndex(CStrRef key) { ASSERT(is(KindOfArray)); if (getIsVector()) return -1; StringData *sd = key.get(); return m_data.map->indexOf(sd); }
size_t SharedVariant::arrSize() const { ASSERT(is(KindOfArray)); if (getIsVector()) return m_data.vec->size; return m_data.map->size(); }
void ThreadSharedVariant::getStats(SharedVariantStats *stats) { stats->initStats(); stats->variantCount = 1; switch (m_type) { case KindOfNull: case KindOfBoolean: case KindOfInt64: case KindOfDouble: stats->dataSize = sizeof(m_data.dbl); stats->dataTotalSize = sizeof(ThreadSharedVariant); break; case KindOfObject: if (getIsObj()) { SharedVariantStats childStats; m_data.obj->getSizeStats(&childStats); stats->addChildStats(&childStats); break; } // fall through case KindOfString: if (m_data.str->isStatic()) { stats->dataSize = 0; stats->dataTotalSize = sizeof(ThreadSharedVariant); break; } stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; default: ASSERT(is(KindOfArray)); if (getSerializedArray()) { stats->dataSize = m_data.str->size(); stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(StringData) + stats->dataSize; break; } if (getIsVector()) { stats->dataTotalSize = sizeof(ThreadSharedVariant) + sizeof(VectorData); stats->dataTotalSize += sizeof(ThreadSharedVariant*) * m_data.vec->size; for (size_t i = 0; i < m_data.vec->size; i++) { ThreadSharedVariant *v = m_data.vec->vals[i]; SharedVariantStats childStats; v->getStats(&childStats); stats->addChildStats(&childStats); } } else if (RuntimeOption::ApcUseGnuMap) { // There is no way to calculate this accurately, and this should be only // used if ImmutableMap is seriously broken, when profiling is less // important. Just not do basic thing here: stats->dataTotalSize = sizeof(MapData); } else { ImmutableMap *map = m_data.map; stats->dataTotalSize = sizeof(ThreadSharedVariant) + map->getStructSize(); for (int i = 0; i < map->size(); i++) { SharedVariantStats childStats; map->getKeyIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); map->getValIndex(i)->getStats(&childStats); stats->addChildStats(&childStats); } } break; } }
HOT_FUNC int SharedVariant::getIndex(const StringData* key) { assert(is(KindOfArray)); if (getIsVector()) return -1; return m_data.map->indexOf(key); }