Tracker's OpenHashTable.h which it should eventually replace. We've renamed the class to BOpenHashTable and changed the interface slightly so that HashTableLink became superfluous. Adapted all the code that used it. Since the OpenHashTables no longer clash, this should fix the GCC4 build. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31791 a95241bf-73f2-0310-859d-f6bbb57e9c96
185 lines
3.0 KiB
C++
185 lines
3.0 KiB
C++
/*
|
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
|
* Distributed under the terms of the MIT License.
|
|
*/
|
|
|
|
|
|
#include "StackFrameValues.h"
|
|
|
|
#include <new>
|
|
|
|
#include "FunctionID.h"
|
|
#include "TypeComponentPath.h"
|
|
|
|
|
|
struct StackFrameValues::Key {
|
|
ObjectID* variable;
|
|
TypeComponentPath* path;
|
|
|
|
Key(ObjectID* variable, TypeComponentPath* path)
|
|
:
|
|
variable(variable),
|
|
path(path)
|
|
{
|
|
}
|
|
|
|
uint32 HashValue() const
|
|
{
|
|
return variable->HashValue() ^ path->HashValue();
|
|
}
|
|
|
|
bool operator==(const Key& other) const
|
|
{
|
|
return *variable == *other.variable && *path == *other.path;
|
|
}
|
|
};
|
|
|
|
|
|
struct StackFrameValues::ValueEntry : Key {
|
|
BVariant value;
|
|
ValueEntry* next;
|
|
|
|
ValueEntry(ObjectID* variable, TypeComponentPath* path)
|
|
:
|
|
Key(variable, path)
|
|
{
|
|
variable->AcquireReference();
|
|
path->AcquireReference();
|
|
}
|
|
|
|
~ValueEntry()
|
|
{
|
|
variable->ReleaseReference();
|
|
path->ReleaseReference();
|
|
}
|
|
};
|
|
|
|
|
|
struct StackFrameValues::ValueEntryHashDefinition {
|
|
typedef Key KeyType;
|
|
typedef ValueEntry ValueType;
|
|
|
|
size_t HashKey(const Key& key) const
|
|
{
|
|
return key.HashValue();
|
|
}
|
|
|
|
size_t Hash(const ValueEntry* value) const
|
|
{
|
|
return value->HashValue();
|
|
}
|
|
|
|
bool Compare(const Key& key, const ValueEntry* value) const
|
|
{
|
|
return key == *value;
|
|
}
|
|
|
|
ValueEntry*& GetLink(ValueEntry* value) const
|
|
{
|
|
return value->next;
|
|
}
|
|
};
|
|
|
|
|
|
StackFrameValues::StackFrameValues()
|
|
:
|
|
fValues(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
StackFrameValues::StackFrameValues(const StackFrameValues& other)
|
|
:
|
|
fValues(NULL)
|
|
{
|
|
try {
|
|
// init
|
|
if (Init() != B_OK)
|
|
throw std::bad_alloc();
|
|
|
|
// clone all values
|
|
for (ValueTable::Iterator it = other.fValues->GetIterator();
|
|
ValueEntry* entry = it.Next();) {
|
|
if (SetValue(entry->variable, entry->path, entry->value) != B_OK)
|
|
throw std::bad_alloc();
|
|
}
|
|
} catch (...) {
|
|
_Cleanup();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
|
|
StackFrameValues::~StackFrameValues()
|
|
{
|
|
_Cleanup();
|
|
}
|
|
|
|
|
|
status_t
|
|
StackFrameValues::Init()
|
|
{
|
|
fValues = new(std::nothrow) ValueTable;
|
|
if (fValues == NULL)
|
|
return B_NO_MEMORY;
|
|
|
|
return fValues->Init();
|
|
}
|
|
|
|
|
|
bool
|
|
StackFrameValues::GetValue(ObjectID* variable, const TypeComponentPath* path,
|
|
BVariant& _value) const
|
|
{
|
|
ValueEntry* entry = fValues->Lookup(
|
|
Key(variable, (TypeComponentPath*)path));
|
|
if (entry == NULL)
|
|
return false;
|
|
|
|
_value = entry->value;
|
|
return true;
|
|
}
|
|
|
|
|
|
bool
|
|
StackFrameValues::HasValue(ObjectID* variable, const TypeComponentPath* path)
|
|
const
|
|
{
|
|
return fValues->Lookup(Key(variable, (TypeComponentPath*)path)) != NULL;
|
|
}
|
|
|
|
|
|
status_t
|
|
StackFrameValues::SetValue(ObjectID* variable, TypeComponentPath* path,
|
|
const BVariant& value)
|
|
{
|
|
ValueEntry* entry = fValues->Lookup(Key(variable, path));
|
|
if (entry == NULL) {
|
|
entry = new(std::nothrow) ValueEntry(variable, path);
|
|
if (entry == NULL)
|
|
return B_NO_MEMORY;
|
|
fValues->Insert(entry);
|
|
}
|
|
|
|
entry->value = value;
|
|
return B_OK;
|
|
}
|
|
|
|
|
|
void
|
|
StackFrameValues::_Cleanup()
|
|
{
|
|
if (fValues != NULL) {
|
|
ValueEntry* entry = fValues->Clear(true);
|
|
|
|
while (entry != NULL) {
|
|
ValueEntry* next = entry->next;
|
|
delete entry;
|
|
entry = next;
|
|
}
|
|
|
|
delete fValues;
|
|
fValues = NULL;
|
|
}
|
|
}
|