More smart containers

And use them for VariableSerializer/VariableUnserializer
Esse commit está contido em:
mwilliams
2013-02-15 11:49:33 -08:00
commit de Sara Golemon
commit 39ba801ffc
4 arquivos alterados com 66 adições e 20 exclusões
+58 -13
Ver Arquivo
@@ -398,6 +398,22 @@ void* smart_calloc(size_t count, size_t bytes);
void* smart_realloc(void* ptr, size_t nbytes);
void smart_free(void* ptr);
namespace smart {
namespace do_not_use_directly {
/*
* We are deriving from the std::collection classes to get
* smart::collection classes that use smart allocation.
* To avoid the various issues involved with deriving
* from value types, we want to make sure that there are
* no references to std::collection<...,SmartStlAlloc<>>
* other than the ones below. That way we know that
* a pointer to a smart::collection can never decay
* to a pointer to a std::collection.
*
* The namespace do_not_use_directly should remind us
* of that.
*
*/
template <class T>
class SmartStlAlloc {
public:
@@ -460,21 +476,50 @@ bool operator!= (const SmartStlAlloc<T1>&,
return false;
}
namespace smart {
template <class Key, class T, class Compare = std::less<Key>,
class Alloc = HPHP::SmartStlAlloc<std::pair<const Key, T> > >
class map : public std::map<Key, T, Compare, Alloc> {};
template <class T, class Alloc = HPHP::SmartStlAlloc<T> >
class deque : public std::deque<T, Alloc> {};
template <class T, class Alloc = HPHP::SmartStlAlloc<T> >
class vector : public std::vector<T, Alloc> {};
template <class T, class Container = deque<T> >
class queue : public std::queue<T, Container> {};
}
/*
* Derivation from value types is generally bad.
* Here, we derive from classes that do not exist anywhere
* else in the code base (see comments above).
*
* We also add no functionality to the derived class. Your
* code will not get past code review if you try to do so.
*/
template <class Key, class T, class Compare = std::less<Key> >
class map : public std::map<
Key, T, Compare,
do_not_use_directly::SmartStlAlloc<std::pair<const Key, T> > > {};
template <class T>
class deque : public std::deque<T, do_not_use_directly::SmartStlAlloc<T> > {};
template <class T>
class vector : public std::vector<T, do_not_use_directly::SmartStlAlloc<T> > {};
template <class T>
class list : public std::list<T, do_not_use_directly::SmartStlAlloc<T> > {};
template <class T>
class queue : public std::queue<T, deque<T> > {};
template <class _T, class _U,
class _V = hphp_hash<_T>,class _W = std::equal_to<_T> >
struct hash_map : std::tr1::unordered_map<
_T, _U, _V, _W, do_not_use_directly::SmartStlAlloc<std::pair<_T, _U> > > {
hash_map() : std::tr1::unordered_map<
_T, _U, _V, _W, do_not_use_directly::SmartStlAlloc<std::pair<_T, _U> >
>(0) {}
};
template <class _T,
class _V = hphp_hash<_T>,class _W = std::equal_to<_T> >
struct hash_set : std::tr1::unordered_set<
_T, _V, _W, do_not_use_directly::SmartStlAlloc<_T> > {
hash_set() : std::tr1::unordered_set<
_T, _V, _W, do_not_use_directly::SmartStlAlloc<_T> >(0) {}
};
}
///////////////////////////////////////////////////////////////////////////////
}
+2 -2
Ver Arquivo
@@ -45,7 +45,7 @@ VariableSerializer::VariableSerializer(Type type, int option /* = 0 */,
m_levelDebugger(0) {
m_maxLevelDebugger = g_context->getDebuggerPrintLevel();
if (type == Serialize || type == APCSerialize || type == DebuggerSerialize) {
m_arrayIds = new PointerCounterMap();
m_arrayIds = new SmartPtrCtrMap();
} else {
m_arrayIds = nullptr;
}
@@ -477,7 +477,7 @@ void VariableSerializer::writeOverflow(void* ptr, bool isObject /* = false */) {
case APCSerialize:
{
assert(m_arrayIds);
PointerCounterMap::const_iterator iter = m_arrayIds->find(ptr);
SmartPtrCtrMap::const_iterator iter = m_arrayIds->find(ptr);
assert(iter != m_arrayIds->end());
int id = iter->second;
if (isObject) {
+4 -3
Ver Arquivo
@@ -108,12 +108,13 @@ public:
void getResourceInfo(String &rsrcName, int &rsrcId);
Type getType() const { return m_type; }
private:
typedef smart::hash_map<void*, int, pointer_hash<void> > SmartPtrCtrMap;
Type m_type;
int m_option; // type specific extra options
StringBuffer *m_buf;
int m_indent;
PointerCounterMap m_counts; // counting seen arrays for recursive levels
PointerCounterMap *m_arrayIds; // reference ids for objs/arrays
SmartPtrCtrMap m_counts; // counting seen arrays for recursive levels
SmartPtrCtrMap *m_arrayIds; // reference ids for objs/arrays
int m_valueCount; // Current ref index
bool m_referenced; // mark current array element as reference
int m_refCount; // current variable's reference count
@@ -132,7 +133,7 @@ private:
bool first_element; // whether this is first array element
int indent_delta; // the extra indent to serialize this object
};
std::vector<ArrayInfo> m_arrayInfos;
smart::vector<ArrayInfo> m_arrayInfos;
void writePropertyKey(CStrRef prop);
};
+2 -2
Ver Arquivo
@@ -120,8 +120,8 @@ public:
Type m_type;
const char *m_buf;
const char *m_end;
std::vector<RefInfo> m_refs;
std::list<Variant> m_vars;
smart::vector<RefInfo> m_refs;
smart::list<Variant> m_vars;
bool m_unknownSerializable;
void check() {