void ThreadSharedVariant::dump(std::string &out) { out += "ref("; out += boost::lexical_cast<string>(m_ref); out += ") "; switch (m_type) { case KindOfBoolean: out += "boolean: "; out += m_data.num ? "true" : "false"; break; case KindOfInt64: out += "int: "; out += boost::lexical_cast<string>(m_data.num); break; case KindOfDouble: out += "double: "; out += boost::lexical_cast<string>(m_data.dbl); break; case KindOfString: out += "string("; out += boost::lexical_cast<string>(stringLength()); out += "): "; out += stringData(); break; case KindOfArray: if (getSerializedArray()) { out += "array: "; out += m_data.str->data(); } else { SharedMap(this).dump(out); } break; default: out += "object: "; out += m_data.str->data(); break; } out += "\n"; }
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; } }
Variant ThreadSharedVariant::toLocal() { ASSERT(getOwner()); switch (m_type) { case KindOfBoolean: { return (bool)m_data.num; } case KindOfInt64: { return m_data.num; } case KindOfDouble: { return m_data.dbl; } case KindOfString: { if (m_data.str->isStatic()) return m_data.str; return NEW(StringData)(this); } case KindOfArray: { if (getSerializedArray()) { return apc_unserialize(String(m_data.str->data(), m_data.str->size(), AttachLiteral)); } return NEW(SharedMap)(this); } default: { ASSERT(m_type == KindOfObject); return apc_unserialize(String(m_data.str->data(), m_data.str->size(), AttachLiteral)); } } }
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; } }