APCHandle* APCObject::MakeShared( ObjectData* objectData, size_t& size, bool inner, bool createFromSer) { if (!canOptimize(objectData)) { return createFromSer ? MakeShared(apc_serialize(objectData), size) : nullptr; } if (objectData->isCollection()) { return APCCollection::MakeShared(objectData, size, inner); } bool serialize = false; if (!inner) { PointerSet visited; visited.insert(reinterpret_cast<void*>(objectData)); traverseDataRecursive(objectData, [&](const Variant& var) { if (var.isReferenced()) { Variant *pvar = var.getRefData(); if (chekVisited(visited, pvar)) { serialize = true; return true; } } DataType type = var.getType(); if (type == KindOfObject) { auto data = var.getObjectData(); if (chekVisited(visited, reinterpret_cast<void*>(data))) { serialize = true; return true; } } else if (type == KindOfResource) { serialize = true; return true; } return false; } ); } if (serialize) { return createFromSer ? MakeShared(apc_serialize(objectData), size) : nullptr; } return Construct(objectData, size); }
APCHandle* APCObject::MakeAPCObject( APCHandle* obj, size_t& size, const Variant& value) { if (!value.is(KindOfObject) || obj->objAttempted()) { return nullptr; } obj->setObjAttempted(); ObjectData *o = value.getObjectData(); if (apcExtension::OptimizeSerialization) { return MakeShared(o, size, false, false); } DataWalker walker(DataWalker::LookupFeature::DetectSerializable); DataWalker::DataFeature features = walker.traverseData(o); if (features.isCircular() || features.hasCollection() || features.hasSerializableReference()) { return nullptr; } APCHandle* tmp = APCHandle::Create(value, size, false, true, true); tmp->setObjAttempted(); return tmp; }
StringData* StringData::MakeUncounted(StringSlice sl) { return MakeShared(sl, false); }
StringData* StringData::MakeStatic(StringSlice sl) { return MakeShared(sl, true); }
StringData* StringData::MakeUncounted(folly::StringPiece sl) { return MakeShared(sl, false); }
StringData* StringData::MakeStatic(folly::StringPiece sl) { return MakeShared(sl, true); }