From a3463d19323e5ff7a4f6b8c1313f1dd1978311e4 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 7 Jul 2011 09:20:15 +0200 Subject: [PATCH] Refactor NameIndexIterator into template class Create template class GenericIndexIterator from NameIndexIterator. --- .../kernel/file_systems/packagefs/IndexImpl.h | 157 ++++++++++++++++++ .../file_systems/packagefs/NameIndex.cpp | 155 ++--------------- .../kernel/file_systems/packagefs/NameIndex.h | 7 +- 3 files changed, 175 insertions(+), 144 deletions(-) diff --git a/src/add-ons/kernel/file_systems/packagefs/IndexImpl.h b/src/add-ons/kernel/file_systems/packagefs/IndexImpl.h index 1805d9fb86..c337aee24d 100644 --- a/src/add-ons/kernel/file_systems/packagefs/IndexImpl.h +++ b/src/add-ons/kernel/file_systems/packagefs/IndexImpl.h @@ -8,6 +8,7 @@ #include "Index.h" #include "Node.h" +#include "NodeListener.h" class AbstractIndexIterator { @@ -23,4 +24,160 @@ public: }; +template +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 +GenericIndexIterator::GenericIndexIterator() + : + AbstractIndexIterator(), + fIndex(NULL), + fNextTreeNode(NULL), + fSuspended(false) +{ +} + + +template +GenericIndexIterator::~GenericIndexIterator() +{ + SetTo(NULL, NULL); +} + + +template +bool +GenericIndexIterator::HasNext() const +{ + return fNextTreeNode != NULL; +} + + +template +Node* +GenericIndexIterator::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 +status_t +GenericIndexIterator::Suspend() +{ + if (fSuspended) + return B_BAD_VALUE; + + if (fNextTreeNode != NULL) + fIndex->GetVolume()->AddNodeListener(this, _ToNode()); + + fSuspended = true; + return B_OK; +} + + +template +status_t +GenericIndexIterator::Resume() +{ + if (!fSuspended) + return B_BAD_VALUE; + + if (fNextTreeNode != NULL) + fIndex->GetVolume()->RemoveNodeListener(this); + + fSuspended = false; + return B_OK; +} + + +template +bool +GenericIndexIterator::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 +void +GenericIndexIterator::NodeRemoved(Node* node) +{ + Resume(); + Next(NULL, NULL); + Suspend(); +} + + +template +Node* +GenericIndexIterator::_ToNode() const +{ +// return NodeTree::NodeStrategy().GetValue(fNextTreeNode); + typename NodeTree::NodeStrategy strategy; + return strategy.GetValue(fNextTreeNode); +} + + #endif // INDEX_IMPL_H diff --git a/src/add-ons/kernel/file_systems/packagefs/NameIndex.cpp b/src/add-ons/kernel/file_systems/packagefs/NameIndex.cpp index 601f965c3e..9504b69061 100644 --- a/src/add-ons/kernel/file_systems/packagefs/NameIndex.cpp +++ b/src/add-ons/kernel/file_systems/packagefs/NameIndex.cpp @@ -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 { }; @@ -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); -} diff --git a/src/add-ons/kernel/file_systems/packagefs/NameIndex.h b/src/add-ons/kernel/file_systems/packagefs/NameIndex.h index 7e8ed7bfc6..76766371e6 100644 --- a/src/add-ons/kernel/file_systems/packagefs/NameIndex.h +++ b/src/add-ons/kernel/file_systems/packagefs/NameIndex.h @@ -10,7 +10,7 @@ #include "NodeListener.h" -class NameIndexIterator; +template 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);