Refactor NameIndexIterator into template class
Create template class GenericIndexIterator from NameIndexIterator.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user