Refactor NameIndexIterator into template class
Create template class GenericIndexIterator from NameIndexIterator.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "Index.h"
|
#include "Index.h"
|
||||||
#include "Node.h"
|
#include "Node.h"
|
||||||
|
#include "NodeListener.h"
|
||||||
|
|
||||||
|
|
||||||
class AbstractIndexIterator {
|
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
|
#endif // INDEX_IMPL_H
|
||||||
|
|||||||
@@ -82,38 +82,22 @@ class NameIndex::EntryTree : public _EntryTree {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - NameIndexIterator
|
// #pragma mark - Iterator
|
||||||
|
|
||||||
|
|
||||||
class NameIndexIterator : public AbstractIndexIterator,
|
struct NameIndex::IteratorPolicy {
|
||||||
public NodeListener {
|
typedef NameIndex Index;
|
||||||
public:
|
typedef const char* Value;
|
||||||
NameIndexIterator();
|
typedef NameIndex::EntryTree NodeTree;
|
||||||
virtual ~NameIndexIterator();
|
|
||||||
|
|
||||||
virtual bool HasNext() const;
|
static NodeTree* GetNodeTree(Index* index)
|
||||||
virtual Node* Next(void* buffer, size_t* _keyLength);
|
{
|
||||||
|
return index->fEntries;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
virtual status_t Suspend();
|
|
||||||
virtual status_t Resume();
|
|
||||||
|
|
||||||
bool SetTo(NameIndex* index, const char* name,
|
struct NameIndex::Iterator : public GenericIndexIterator<IteratorPolicy> {
|
||||||
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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -196,7 +180,7 @@ NameIndex::NodeChanged(Node* node, uint32 statFields,
|
|||||||
AbstractIndexIterator*
|
AbstractIndexIterator*
|
||||||
NameIndex::InternalGetIterator()
|
NameIndex::InternalGetIterator()
|
||||||
{
|
{
|
||||||
NameIndexIterator* iterator = new(std::nothrow) NameIndexIterator;
|
Iterator* iterator = new(std::nothrow) Iterator;
|
||||||
if (iterator != NULL) {
|
if (iterator != NULL) {
|
||||||
if (!iterator->SetTo(this, NULL, true)) {
|
if (!iterator->SetTo(this, NULL, true)) {
|
||||||
delete iterator;
|
delete iterator;
|
||||||
@@ -227,7 +211,7 @@ NameIndex::InternalFind(const void* _key, size_t length)
|
|||||||
key = clonedKey;
|
key = clonedKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
NameIndexIterator* iterator = new(std::nothrow) NameIndexIterator;
|
Iterator* iterator = new(std::nothrow) Iterator;
|
||||||
if (iterator != NULL) {
|
if (iterator != NULL) {
|
||||||
if (!iterator->SetTo(this, (const char*)key)) {
|
if (!iterator->SetTo(this, (const char*)key)) {
|
||||||
delete iterator;
|
delete iterator;
|
||||||
@@ -246,116 +230,3 @@ NameIndex::_UpdateLiveQueries(Node* entry, const char* oldName,
|
|||||||
oldName, oldName ? strlen(oldName) : 0,
|
oldName, oldName ? strlen(oldName) : 0,
|
||||||
newName, newName ? strlen(newName) : 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"
|
#include "NodeListener.h"
|
||||||
|
|
||||||
|
|
||||||
class NameIndexIterator;
|
template<typename Policy> class GenericIndexIterator;
|
||||||
|
|
||||||
|
|
||||||
class NameIndex : public Index, private NodeListener {
|
class NameIndex : public Index, private NodeListener {
|
||||||
@@ -35,7 +35,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
class EntryTree;
|
class EntryTree;
|
||||||
friend class NameIndexIterator;
|
struct IteratorPolicy;
|
||||||
|
struct Iterator;
|
||||||
|
|
||||||
|
friend class IteratorPolicy;
|
||||||
|
|
||||||
void _UpdateLiveQueries(Node* entry,
|
void _UpdateLiveQueries(Node* entry,
|
||||||
const char* oldName, const char* newName);
|
const char* oldName, const char* newName);
|
||||||
|
|||||||
Reference in New Issue
Block a user