Switched memory to using shared nodes, and node_data to keep only naked node pointers, not shared nodes (to break the cycle, and we don't need weak pointers because their memory is guaranteed to exist, via 'memory')

This commit is contained in:
Jesse Beder
2011-09-09 02:29:17 -05:00
parent 6ffc9ac788
commit ec95e61c04
9 changed files with 77 additions and 74 deletions

View File

@@ -15,21 +15,21 @@ namespace YAML
{ {
// indexing // indexing
template<typename Key> template<typename Key>
inline shared_node node_data::get(const Key& key, shared_memory_holder pMemory) const inline node& node_data::get(const Key& key, shared_memory_holder pMemory) const
{ {
if(m_type != ValueType::Map) if(m_type != ValueType::Map)
return pMemory->create_node(); return pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(equals(it->first, key, pMemory)) if(equals(*it->first, key, pMemory))
return it->second; return *it->second;
} }
return pMemory->create_node(); return pMemory->create_node();
} }
template<typename Key> template<typename Key>
inline shared_node node_data::get(const Key& key, shared_memory_holder pMemory) inline node& node_data::get(const Key& key, shared_memory_holder pMemory)
{ {
// TODO: check if 'key' is index-like, and we're a sequence // TODO: check if 'key' is index-like, and we're a sequence
@@ -48,14 +48,14 @@ namespace YAML
} }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(equals(it->first, key, pMemory)) if(equals(*it->first, key, pMemory))
return it->second; return *it->second;
} }
shared_node pKey = convert_to_node(key, pMemory); node& k = convert_to_node(key, pMemory);
shared_node pValue = pMemory->create_node(); node& v = pMemory->create_node();
m_map.push_back(kv_pair(pKey, pValue)); m_map.push_back(kv_pair(&k, &v));
return pValue; return v;
} }
template<typename Key> template<typename Key>
@@ -65,7 +65,7 @@ namespace YAML
return false; return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
if(equals(it->first, key, pMemory)) { if(equals(*it->first, key, pMemory)) {
m_map.erase(it); m_map.erase(it);
return true; return true;
} }
@@ -75,20 +75,20 @@ namespace YAML
} }
template<typename T> template<typename T>
inline bool node_data::equals(detail::shared_node pNode, const T& rhs, detail::shared_memory_holder pMemory) inline bool node_data::equals(node& node, const T& rhs, shared_memory_holder pMemory)
{ {
T lhs; T lhs;
if(convert<T>::decode(Value(pNode, pMemory), lhs)) if(convert<T>::decode(Value(node, pMemory), lhs))
return lhs == rhs; return lhs == rhs;
return false; return false;
} }
template<typename T> template<typename T>
inline shared_node node_data::convert_to_node(const T& rhs, detail::shared_memory_holder pMemory) inline node& node_data::convert_to_node(const T& rhs, shared_memory_holder pMemory)
{ {
Value value = convert<T>::encode(rhs); Value value = convert<T>::encode(rhs);
pMemory->merge(*value.m_pMemory); pMemory->merge(*value.m_pMemory);
return value.m_pNode; return *value.m_pNode;
} }
} }
} }

View File

@@ -15,11 +15,11 @@ namespace YAML
{ {
class memory { class memory {
public: public:
shared_node create_node(); node& create_node();
void merge(const memory& rhs); void merge(const memory& rhs);
private: private:
typedef std::set<shared_node_ref> Nodes; typedef std::set<shared_node> Nodes;
Nodes m_nodes; Nodes m_nodes;
}; };
@@ -27,7 +27,7 @@ namespace YAML
public: public:
memory_holder(): m_pMemory(new memory) {} memory_holder(): m_pMemory(new memory) {}
shared_node create_node() { return m_pMemory->create_node(); } node& create_node() { return m_pMemory->create_node(); }
void merge(memory_holder& rhs); void merge(memory_holder& rhs);
private: private:

View File

@@ -10,15 +10,16 @@
#include "yaml-cpp/value/type.h" #include "yaml-cpp/value/type.h"
#include "yaml-cpp/value/ptr.h" #include "yaml-cpp/value/ptr.h"
#include "yaml-cpp/value/detail/node_ref.h" #include "yaml-cpp/value/detail/node_ref.h"
#include <boost/utility.hpp>
namespace YAML namespace YAML
{ {
namespace detail namespace detail
{ {
class node class node: private boost::noncopyable
{ {
public: public:
explicit node(shared_node_ref pRef): m_pRef(pRef) {} node(): m_pRef(new node_ref) {}
bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; } bool is(const node& rhs) const { return m_pRef == rhs.m_pRef; }
ValueType::value type() const { return m_pRef->type(); } ValueType::value type() const { return m_pRef->type(); }
@@ -33,13 +34,13 @@ namespace YAML
void set_scalar(const std::string& scalar) { m_pRef->set_scalar(scalar); } void set_scalar(const std::string& scalar) { m_pRef->set_scalar(scalar); }
// indexing // indexing
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory) { return m_pRef->get(key, pMemory); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pRef->get(key, pMemory); }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); } template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
shared_node get(shared_node pKey, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(pKey, pMemory); } node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_ref&>(*m_pRef).get(key, pMemory); }
shared_node get(shared_node pKey, shared_memory_holder pMemory) { return m_pRef->get(pKey, pMemory); } node& get(node& key, shared_memory_holder pMemory) { return m_pRef->get(key, pMemory); }
bool remove(shared_node pKey, shared_memory_holder pMemory) { return m_pRef->remove(pKey, pMemory); } bool remove(node& key, shared_memory_holder pMemory) { return m_pRef->remove(key, pMemory); }
private: private:
shared_node_ref m_pRef; shared_node_ref m_pRef;

View File

@@ -9,6 +9,7 @@
#include "yaml-cpp/dll.h" #include "yaml-cpp/dll.h"
#include "yaml-cpp/value/ptr.h" #include "yaml-cpp/value/ptr.h"
#include "yaml-cpp/value/type.h" #include "yaml-cpp/value/type.h"
#include <boost/utility.hpp>
#include <list> #include <list>
#include <utility> #include <utility>
#include <vector> #include <vector>
@@ -17,7 +18,7 @@ namespace YAML
{ {
namespace detail namespace detail
{ {
class node_data class node_data: private boost::noncopyable
{ {
public: public:
node_data(); node_data();
@@ -30,22 +31,22 @@ namespace YAML
const std::string& scalar() const { return m_scalar; } const std::string& scalar() const { return m_scalar; }
// indexing // indexing
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory) const; template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const;
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory); template<typename Key> node& get(const Key& key, shared_memory_holder pMemory);
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory); template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory);
shared_node get(shared_node pKey, shared_memory_holder pMemory) const; node& get(node& key, shared_memory_holder pMemory) const;
shared_node get(shared_node pKey, shared_memory_holder pMemory); node& get(node& key, shared_memory_holder pMemory);
bool remove(shared_node pKey, shared_memory_holder pMemory); bool remove(node& key, shared_memory_holder pMemory);
private: private:
void convert_sequence_to_map(shared_memory_holder pMemory); void convert_sequence_to_map(shared_memory_holder pMemory);
template<typename T> template<typename T>
static bool equals(detail::shared_node pNode, const T& rhs, detail::shared_memory_holder pMemory); static bool equals(node& node, const T& rhs, shared_memory_holder pMemory);
template<typename T> template<typename T>
static shared_node convert_to_node(const T& rhs, detail::shared_memory_holder pMemory); static node& convert_to_node(const T& rhs, shared_memory_holder pMemory);
private: private:
bool m_isDefined; bool m_isDefined;
@@ -55,11 +56,11 @@ namespace YAML
std::string m_scalar; std::string m_scalar;
// sequence // sequence
typedef std::vector<shared_node> node_seq; typedef std::vector<node *> node_seq;
node_seq m_sequence; node_seq m_sequence;
// map // map
typedef std::pair<shared_node, shared_node> kv_pair; typedef std::pair<node *, node *> kv_pair;
typedef std::list<kv_pair> node_map; typedef std::list<kv_pair> node_map;
node_map m_map; node_map m_map;
}; };

View File

@@ -10,12 +10,13 @@
#include "yaml-cpp/value/type.h" #include "yaml-cpp/value/type.h"
#include "yaml-cpp/value/ptr.h" #include "yaml-cpp/value/ptr.h"
#include "yaml-cpp/value/detail/node_data.h" #include "yaml-cpp/value/detail/node_data.h"
#include <boost/utility.hpp>
namespace YAML namespace YAML
{ {
namespace detail namespace detail
{ {
class node_ref class node_ref: private boost::noncopyable
{ {
public: public:
node_ref(): m_pData(new node_data) {} node_ref(): m_pData(new node_data) {}
@@ -30,13 +31,13 @@ namespace YAML
void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); } void set_scalar(const std::string& scalar) { m_pData->set_scalar(scalar); }
// indexing // indexing
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
template<typename Key> shared_node get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); } template<typename Key> node& get(const Key& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); } template<typename Key> bool remove(const Key& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
shared_node get(shared_node pKey, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(pKey, pMemory); } node& get(node& key, shared_memory_holder pMemory) const { return static_cast<const node_data&>(*m_pData).get(key, pMemory); }
shared_node get(shared_node pKey, shared_memory_holder pMemory) { return m_pData->get(pKey, pMemory); } node& get(node& key, shared_memory_holder pMemory) { return m_pData->get(key, pMemory); }
bool remove(shared_node pKey, shared_memory_holder pMemory) { return m_pData->remove(pKey, pMemory); } bool remove(node& key, shared_memory_holder pMemory) { return m_pData->remove(key, pMemory); }
private: private:
shared_node_data m_pData; shared_node_data m_pData;

View File

@@ -13,18 +13,18 @@
namespace YAML namespace YAML
{ {
inline Value::Value(): m_pMemory(new detail::memory_holder), m_pNode(m_pMemory->create_node()) inline Value::Value(): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
{ {
m_pNode->set_null(); m_pNode->set_null();
} }
inline Value::Value(ValueType::value type): m_pMemory(new detail::memory_holder), m_pNode(m_pMemory->create_node()) inline Value::Value(ValueType::value type): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
{ {
m_pNode->set_type(type); m_pNode->set_type(type);
} }
template<typename T> template<typename T>
inline Value::Value(const T& rhs): m_pMemory(new detail::memory_holder), m_pNode(m_pMemory->create_node()) inline Value::Value(const T& rhs): m_pMemory(new detail::memory_holder), m_pNode(&m_pMemory->create_node())
{ {
Assign(rhs); Assign(rhs);
} }
@@ -33,7 +33,7 @@ namespace YAML
{ {
} }
inline Value::Value(detail::shared_node pNode, detail::shared_memory_holder pMemory): m_pMemory(pMemory), m_pNode(pNode) inline Value::Value(detail::node& node, detail::shared_memory_holder pMemory): m_pMemory(pMemory), m_pNode(&node)
{ {
} }
@@ -154,15 +154,15 @@ namespace YAML
template<typename Key> template<typename Key>
inline const Value Value::operator[](const Key& key) const inline const Value Value::operator[](const Key& key) const
{ {
detail::shared_node pValue = static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory); detail::node& value = static_cast<const detail::node&>(*m_pNode).get(key, m_pMemory);
return Value(pValue, m_pMemory); return Value(value, m_pMemory);
} }
template<typename Key> template<typename Key>
inline Value Value::operator[](const Key& key) inline Value Value::operator[](const Key& key)
{ {
detail::shared_node pValue = m_pNode->get(key, m_pMemory); detail::node& value = m_pNode->get(key, m_pMemory);
return Value(pValue, m_pMemory); return Value(value, m_pMemory);
} }
template<typename Key> template<typename Key>
@@ -173,19 +173,19 @@ namespace YAML
inline const Value Value::operator[](const Value& key) const inline const Value Value::operator[](const Value& key) const
{ {
detail::shared_node pValue = static_cast<const detail::node&>(*m_pNode).get(key.m_pNode, m_pMemory); detail::node& value = static_cast<const detail::node&>(*m_pNode).get(*key.m_pNode, m_pMemory);
return Value(pValue, m_pMemory); return Value(value, m_pMemory);
} }
inline Value Value::operator[](const Value& key) inline Value Value::operator[](const Value& key)
{ {
detail::shared_node pValue = m_pNode->get(key.m_pNode, m_pMemory); detail::node& value = m_pNode->get(*key.m_pNode, m_pMemory);
return Value(pValue, m_pMemory); return Value(value, m_pMemory);
} }
inline bool Value::remove(const Value& key) inline bool Value::remove(const Value& key)
{ {
return m_pNode->remove(key.m_pNode, m_pMemory); return m_pNode->remove(*key.m_pNode, m_pMemory);
} }
inline const Value Value::operator[](const char *key) const inline const Value Value::operator[](const char *key) const

View File

@@ -63,7 +63,7 @@ namespace YAML
bool remove(char *key); bool remove(char *key);
private: private:
explicit Value(detail::shared_node pNode, detail::shared_memory_holder pMemory); explicit Value(detail::node& node, detail::shared_memory_holder pMemory);
template<typename T> void Assign(const T& rhs); template<typename T> void Assign(const T& rhs);
void Assign(const char *rhs); void Assign(const char *rhs);
@@ -74,7 +74,7 @@ namespace YAML
private: private:
detail::shared_memory_holder m_pMemory; detail::shared_memory_holder m_pMemory;
detail::shared_node m_pNode; detail::node *m_pNode;
}; };
int compare(const Value& lhs, const Value& rhs); int compare(const Value& lhs, const Value& rhs);

View File

@@ -14,11 +14,11 @@ namespace YAML
rhs.m_pMemory = m_pMemory; rhs.m_pMemory = m_pMemory;
} }
shared_node memory::create_node() node& memory::create_node()
{ {
shared_node_ref pRef(new node_ref); shared_node pNode(new node);
m_nodes.insert(pRef); m_nodes.insert(pNode);
return shared_node(new node(pRef)); return *pNode;
} }
void memory::merge(const memory& rhs) void memory::merge(const memory& rhs)

View File

@@ -58,20 +58,20 @@ namespace YAML
} }
// indexing // indexing
shared_node node_data::get(shared_node pKey, shared_memory_holder pMemory) const node& node_data::get(node& key, shared_memory_holder pMemory) const
{ {
if(m_type != ValueType::Map) if(m_type != ValueType::Map)
return pMemory->create_node(); return pMemory->create_node();
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first == pKey) if(it->first == &key) // TODO: equality?
return it->second; return *it->second;
} }
return pMemory->create_node(); return pMemory->create_node();
} }
shared_node node_data::get(shared_node pKey, shared_memory_holder pMemory) node& node_data::get(node& key, shared_memory_holder pMemory)
{ {
switch(m_type) { switch(m_type) {
case ValueType::Undefined: case ValueType::Undefined:
@@ -88,22 +88,22 @@ namespace YAML
} }
for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::const_iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first == pKey) if(it->first == &key) // TODO: equality?
return it->second; return *it->second;
} }
shared_node pValue = pMemory->create_node(); node& value = pMemory->create_node();
m_map.push_back(kv_pair(pKey, pValue)); m_map.push_back(kv_pair(&key, &value));
return pValue; return value;
} }
bool node_data::remove(shared_node pKey, shared_memory_holder /* pMemory */) bool node_data::remove(node& key, shared_memory_holder /* pMemory */)
{ {
if(m_type != ValueType::Map) if(m_type != ValueType::Map)
return false; return false;
for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) { for(node_map::iterator it=m_map.begin();it!=m_map.end();++it) {
if(it->first == pKey) { if(it->first == &key) { // TODO: equality?
m_map.erase(it); m_map.erase(it);
return true; return true;
} }
@@ -121,9 +121,9 @@ namespace YAML
std::stringstream stream; std::stringstream stream;
stream << i; stream << i;
shared_node pKey = pMemory->create_node(); node& key = pMemory->create_node();
pKey->set_scalar(stream.str()); key.set_scalar(stream.str());
m_map.push_back(kv_pair(pKey, m_sequence[i])); m_map.push_back(kv_pair(&key, m_sequence[i]));
} }
m_sequence.clear(); m_sequence.clear();