Implemented a very simple hash-table cache for property lookup using

relative paths.
This commit is contained in:
david
2002-04-06 21:47:22 +00:00
parent bbf4b54613
commit 96474823b5
2 changed files with 188 additions and 20 deletions

View File

@@ -679,7 +679,7 @@ SGPropertyNode::~SGPropertyNode ()
for (int i = 0; i < (int)_children.size(); i++) {
delete _children[i];
}
// delete _path_cache;
delete _path_cache;
clear_value();
}
@@ -1598,22 +1598,19 @@ SGPropertyNode::getRootNode () const
SGPropertyNode *
SGPropertyNode::getNode (const char * relative_path, bool create)
{
// if (_path_cache == 0)
// _path_cache = new cache_map;
if (_path_cache == 0)
_path_cache = new hash_table;
// SGPropertyNode * result = (*_path_cache)[relative_path];
// if (result == 0) {
// vector<PathComponent> components;
// parse_path(relative_path, components);
// result = find_node(this, components, 0, create);
// if (result != 0)
// (*_path_cache)[relative_path] = result;
// }
SGPropertyNode * result = _path_cache->get(relative_path);
if (result == 0) {
vector<PathComponent> components;
parse_path(relative_path, components);
result = find_node(this, components, 0, create);
if (result != 0)
_path_cache->put(relative_path, result);
}
// return result;
vector<PathComponent> components;
parse_path(relative_path, components);
return find_node(this, components, 0, create);
return result;
}
SGPropertyNode *
@@ -1902,4 +1899,129 @@ SGPropertyNode::untie (const char * relative_path)
return (node == 0 ? false : node->untie());
}
////////////////////////////////////////////////////////////////////////
// Simplified hash table for caching paths.
////////////////////////////////////////////////////////////////////////
#define HASH_TABLE_SIZE 199
SGPropertyNode::hash_table::entry::entry ()
: _key(0),
_value(0)
{
}
SGPropertyNode::hash_table::entry::~entry ()
{
// Don't delete the value; we don't own
// the pointer.
delete _key;
}
void
SGPropertyNode::hash_table::entry::set_key (const char * key)
{
_key = copy_string(key);
}
void
SGPropertyNode::hash_table::entry::set_value (SGPropertyNode * value)
{
_value = value;
}
SGPropertyNode::hash_table::bucket::bucket ()
: _length(0),
_entries(0)
{
}
SGPropertyNode::hash_table::bucket::~bucket ()
{
for (int i = 0; i < _length; i++)
delete _entries[i];
}
SGPropertyNode::hash_table::entry *
SGPropertyNode::hash_table::bucket::get_entry (const char * key, bool create)
{
int i;
for (i = 0; i < _length; i++) {
if (!strcmp(_entries[i]->get_key(), key))
return _entries[i];
}
if (create) {
entry ** new_entries = new entry*[_length+1];
for (i = 0; i < _length; i++) {
new_entries[i] = _entries[i];
}
delete _entries;
_entries = new_entries;
_entries[_length] = new entry;
_entries[_length]->set_key(key);
_length++;
return _entries[_length - 1];
} else {
return 0;
}
}
SGPropertyNode::hash_table::hash_table ()
: _data_length(0),
_data(0)
{
}
SGPropertyNode::hash_table::~hash_table ()
{
for (int i = 0; i < _data_length; i++)
delete _data[i];
}
SGPropertyNode *
SGPropertyNode::hash_table::get (const char * key)
{
if (_data_length == 0)
return 0;
unsigned int index = hashcode(key) % _data_length;
if (_data[index] == 0)
return 0;
entry * e = _data[index]->get_entry(key);
if (e == 0)
return 0;
else
return e->get_value();
}
void
SGPropertyNode::hash_table::put (const char * key, SGPropertyNode * value)
{
if (_data_length == 0) {
_data = new bucket*[HASH_TABLE_SIZE];
_data_length = HASH_TABLE_SIZE;
for (unsigned int i = 0; i < HASH_TABLE_SIZE; i++)
_data[i] = 0;
}
unsigned int index = hashcode(key) % _data_length;
if (_data[index] == 0) {
_data[index] = new bucket;
}
entry * e = _data[index]->get_entry(key, true);
e->set_value(value);
}
unsigned int
SGPropertyNode::hash_table::hashcode (const char * key)
{
unsigned int hash = 0;
while (*key != 0) {
hash = 31 * hash + *key;
key++;
}
return hash;
}
// end of props.cxx

View File

@@ -17,7 +17,6 @@
#endif
#include <vector>
#include <map>
#if PROPS_STANDALONE
@@ -26,7 +25,6 @@
using std::string;
using std::vector;
using std::map;
using std::istream;
using std::ostream;
@@ -38,7 +36,6 @@ using std::ostream;
#include STL_IOSTREAM
SG_USING_STD(string);
SG_USING_STD(vector);
SG_USING_STD(map);
#if !defined(SG_HAVE_NATIVE_SGI_COMPILERS)
SG_USING_STD(istream);
SG_USING_STD(ostream);
@@ -1082,12 +1079,13 @@ private:
mutable char _buffer[MAX_STRING_LEN+1];
class hash_table;
const char * _name;
int _index;
SGPropertyNode * _parent;
vector<SGPropertyNode *> _children;
typedef map<const string,SGPropertyNode *> cache_map;
cache_map * _path_cache;
hash_table * _path_cache;
Type _type;
bool _tied;
int _attr;
@@ -1113,6 +1111,54 @@ private:
} _local_val;
/**
* A very simple hash table with no remove functionality.
*/
class hash_table {
public:
/**
* An entry in a bucket in a hash table.
*/
class entry {
public:
entry ();
virtual ~entry ();
virtual const char * get_key () { return _key; }
virtual void set_key (const char * key);
virtual SGPropertyNode * get_value () { return _value; }
virtual void set_value (SGPropertyNode * value);
private:
const char * _key;
SGPropertyNode * _value;
};
/**
* A bucket in a hash table.
*/
class bucket {
public:
bucket ();
virtual ~bucket ();
virtual entry * get_entry (const char * key, bool create = false);
private:
int _length;
entry ** _entries;
};
hash_table ();
virtual ~hash_table ();
virtual SGPropertyNode * get (const char * key);
virtual void put (const char * key, SGPropertyNode * value);
private:
unsigned int hashcode (const char * key);
unsigned int _data_length;
bucket ** _data;
};
};
#endif // __PROPS_HXX