Refactor NameIndexIterator into template class

Create template class GenericIndexIterator from NameIndexIterator.
This commit is contained in:
Ingo Weinhold
2011-07-17 16:55:05 +02:00
parent 773005292a
commit a3463d1932
3 changed files with 175 additions and 144 deletions
@@ -8,6 +8,7 @@
#include "Index.h"
#include "Node.h"
#include "NodeListener.h"
class AbstractIndexIterator {
@@ -23,4 +24,160 @@ public:
};
template<typename Policy>
class GenericIndexIterator : public AbstractIndexIterator,
public NodeListener {
public:
typedef typename Policy::Index Index;
typedef typename Policy::Value Value;
typedef typename Policy::NodeTree NodeTree;
typedef typename NodeTree::Node TreeNode;
public:
GenericIndexIterator();
virtual ~GenericIndexIterator();
virtual bool HasNext() const;
virtual Node* Next(void* buffer, size_t* _keyLength);
virtual status_t Suspend();
virtual status_t Resume();
bool SetTo(Index* index, const Value& name,
bool ignoreValue = false);
virtual void NodeRemoved(Node* node);
protected:
inline Node* _ToNode() const;
protected:
Index* fIndex;
TreeNode* fNextTreeNode;
bool fSuspended;
};
template<typename Policy>
GenericIndexIterator<Policy>::GenericIndexIterator()
:
AbstractIndexIterator(),
fIndex(NULL),
fNextTreeNode(NULL),
fSuspended(false)
{
}
template<typename Policy>
GenericIndexIterator<Policy>::~GenericIndexIterator()
{
SetTo(NULL, NULL);
}
template<typename Policy>
bool
GenericIndexIterator<Policy>::HasNext() const
{
return fNextTreeNode != NULL;
}
template<typename Policy>
Node*
GenericIndexIterator<Policy>::Next(void* buffer, size_t* _keyLength)
{
if (fSuspended || fNextTreeNode == NULL)
return NULL;
Node* node = _ToNode();
if (node != NULL) {
if (buffer != NULL) {
strlcpy((char*)buffer, node->Name(), kMaxIndexKeyLength);
*_keyLength = strlen(node->Name());
}
fNextTreeNode = Policy::GetNodeTree(fIndex)->Next(fNextTreeNode);
}
return node;
}
template<typename Policy>
status_t
GenericIndexIterator<Policy>::Suspend()
{
if (fSuspended)
return B_BAD_VALUE;
if (fNextTreeNode != NULL)
fIndex->GetVolume()->AddNodeListener(this, _ToNode());
fSuspended = true;
return B_OK;
}
template<typename Policy>
status_t
GenericIndexIterator<Policy>::Resume()
{
if (!fSuspended)
return B_BAD_VALUE;
if (fNextTreeNode != NULL)
fIndex->GetVolume()->RemoveNodeListener(this);
fSuspended = false;
return B_OK;
}
template<typename Policy>
bool
GenericIndexIterator<Policy>::SetTo(Index* index, const Value& value,
bool ignoreValue)
{
Resume();
fIndex = index;
fSuspended = false;
fNextTreeNode = NULL;
if (fIndex == NULL)
return false;
typename NodeTree::Iterator iterator;
if (ignoreValue)
Policy::GetNodeTree(fIndex)->GetIterator(&iterator);
else if (Policy::GetNodeTree(fIndex)->FindFirst(value, &iterator) == NULL)
return false;
fNextTreeNode = iterator.CurrentNode();
return fNextTreeNode != NULL;
}
template<typename Policy>
void
GenericIndexIterator<Policy>::NodeRemoved(Node* node)
{
Resume();
Next(NULL, NULL);
Suspend();
}
template<typename Policy>
Node*
GenericIndexIterator<Policy>::_ToNode() const
{
// return NodeTree::NodeStrategy().GetValue(fNextTreeNode);
typename NodeTree::NodeStrategy strategy;
return strategy.GetValue(fNextTreeNode);
}
#endif // INDEX_IMPL_H
@@ -82,38 +82,22 @@ class NameIndex::EntryTree : public _EntryTree {
};
// #pragma mark - NameIndexIterator
// #pragma mark - Iterator
class NameIndexIterator : public AbstractIndexIterator,
public NodeListener {
public:
NameIndexIterator();
virtual ~NameIndexIterator();
struct NameIndex::IteratorPolicy {
typedef NameIndex Index;
typedef const char* Value;
typedef NameIndex::EntryTree NodeTree;
virtual bool HasNext() const;
virtual Node* Next(void* buffer, size_t* _keyLength);
static NodeTree* GetNodeTree(Index* index)
{
return index->fEntries;
}
};
virtual status_t Suspend();
virtual status_t Resume();
bool SetTo(NameIndex* index, const char* name,
bool ignoreValue = false);
virtual void NodeRemoved(Node* node);
private:
friend class NameIndex;
typedef NameIndex::EntryTree EntryTree;
private:
inline Node* _ToNode() const;
private:
NameIndex* fIndex;
EntryTree::Node* fNextTreeNode;
bool fSuspended;
struct NameIndex::Iterator : public GenericIndexIterator<IteratorPolicy> {
};
@@ -196,7 +180,7 @@ NameIndex::NodeChanged(Node* node, uint32 statFields,
AbstractIndexIterator*
NameIndex::InternalGetIterator()
{
NameIndexIterator* iterator = new(std::nothrow) NameIndexIterator;
Iterator* iterator = new(std::nothrow) Iterator;
if (iterator != NULL) {
if (!iterator->SetTo(this, NULL, true)) {
delete iterator;
@@ -227,7 +211,7 @@ NameIndex::InternalFind(const void* _key, size_t length)
key = clonedKey;
}
NameIndexIterator* iterator = new(std::nothrow) NameIndexIterator;
Iterator* iterator = new(std::nothrow) Iterator;
if (iterator != NULL) {
if (!iterator->SetTo(this, (const char*)key)) {
delete iterator;
@@ -246,116 +230,3 @@ NameIndex::_UpdateLiveQueries(Node* entry, const char* oldName,
oldName, oldName ? strlen(oldName) : 0,
newName, newName ? strlen(newName) : 0);
}
// #pragma mark - NameIndexIterator
NameIndexIterator::NameIndexIterator()
:
AbstractIndexIterator(),
fIndex(NULL),
fNextTreeNode(NULL),
fSuspended(false)
{
}
NameIndexIterator::~NameIndexIterator()
{
SetTo(NULL, NULL);
}
bool
NameIndexIterator::HasNext() const
{
return fNextTreeNode != NULL;
}
Node*
NameIndexIterator::Next(void* buffer, size_t* _keyLength)
{
if (fSuspended || fNextTreeNode == NULL)
return NULL;
Node* entry = _ToNode();
if (entry != NULL) {
if (buffer != NULL) {
strlcpy((char*)buffer, entry->Name(), kMaxIndexKeyLength);
*_keyLength = strlen(entry->Name());
}
fNextTreeNode = fIndex->fEntries->Next(fNextTreeNode);
}
return entry;
}
status_t
NameIndexIterator::Suspend()
{
if (fSuspended)
return B_BAD_VALUE;
if (fNextTreeNode != NULL)
fIndex->GetVolume()->AddNodeListener(this, _ToNode());
fSuspended = true;
return B_OK;
}
status_t
NameIndexIterator::Resume()
{
if (!fSuspended)
return B_BAD_VALUE;
if (fNextTreeNode != NULL)
fIndex->GetVolume()->RemoveNodeListener(this);
fSuspended = false;
return B_OK;
}
bool
NameIndexIterator::SetTo(NameIndex* index, const char* name, bool ignoreValue)
{
Resume();
fIndex = index;
fSuspended = false;
fNextTreeNode = NULL;
if (fIndex == NULL)
return false;
EntryTree::Iterator iterator;
if (ignoreValue)
fIndex->fEntries->GetIterator(&iterator);
else if (fIndex->fEntries->FindFirst(name, &iterator) == NULL)
return false;
fNextTreeNode = iterator.CurrentNode();
return fNextTreeNode != NULL;
}
void
NameIndexIterator::NodeRemoved(Node* node)
{
Resume();
Next(NULL, NULL);
Suspend();
}
Node*
NameIndexIterator::_ToNode() const
{
return EntryTree::NodeStrategy().GetValue(fNextTreeNode);
}
@@ -10,7 +10,7 @@
#include "NodeListener.h"
class NameIndexIterator;
template<typename Policy> class GenericIndexIterator;
class NameIndex : public Index, private NodeListener {
@@ -35,7 +35,10 @@ protected:
private:
class EntryTree;
friend class NameIndexIterator;
struct IteratorPolicy;
struct Iterator;
friend class IteratorPolicy;
void _UpdateLiveQueries(Node* entry,
const char* oldName, const char* newName);