More abstraction in GenericIndexIterator

* Move tree node operations to a subpolicy TreePolicy.
* Add a GenericIndexIteratorTreePolicy templatized over the policy,
  implementing the tree policy for the standard indices.
This commit is contained in:
Ingo Weinhold
2011-11-25 06:19:27 +01:00
parent af1cc77849
commit 1cf4d082ab
4 changed files with 68 additions and 44 deletions
@@ -31,6 +31,7 @@ public:
typedef typename Policy::Index Index; typedef typename Policy::Index Index;
typedef typename Policy::Value Value; typedef typename Policy::Value Value;
typedef typename Policy::NodeTree NodeTree; typedef typename Policy::NodeTree NodeTree;
typedef typename Policy::TreePolicy TreePolicy;
typedef typename NodeTree::Node TreeNode; typedef typename NodeTree::Node TreeNode;
public: public:
@@ -51,9 +52,6 @@ public:
virtual void NodeRemoved(Node* node); virtual void NodeRemoved(Node* node);
protected:
inline Node* _ToNode() const;
protected: protected:
Index* fIndex; Index* fIndex;
TreeNode* fNextTreeNode; TreeNode* fNextTreeNode;
@@ -75,7 +73,7 @@ GenericIndexIterator<Policy>::GenericIndexIterator()
template<typename Policy> template<typename Policy>
GenericIndexIterator<Policy>::~GenericIndexIterator() GenericIndexIterator<Policy>::~GenericIndexIterator()
{ {
SetTo(NULL, NULL); SetTo(NULL, Value());
} }
@@ -94,15 +92,14 @@ GenericIndexIterator<Policy>::Next(void* buffer, size_t* _keyLength)
if (fSuspended || fNextTreeNode == NULL) if (fSuspended || fNextTreeNode == NULL)
return NULL; return NULL;
Node* node = _ToNode();
if (node != NULL) {
if (buffer != NULL)
Policy::GetNodeValue(node, buffer, _keyLength);
fNextTreeNode = Policy::GetNodeTree(fIndex)->Next(fNextTreeNode); if (buffer != NULL)
} TreePolicy::GetTreeNodeValue(fNextTreeNode, buffer, _keyLength);
return node; TreeNode* treeNode = fNextTreeNode;
fNextTreeNode = Policy::GetNodeTree(fIndex)->Next(fNextTreeNode);
return TreePolicy::GetNode(treeNode);
} }
@@ -113,8 +110,10 @@ GenericIndexIterator<Policy>::Suspend()
if (fSuspended) if (fSuspended)
return B_BAD_VALUE; return B_BAD_VALUE;
if (fNextTreeNode != NULL) if (fNextTreeNode != NULL) {
fIndex->GetVolume()->AddNodeListener(this, _ToNode()); fIndex->GetVolume()->AddNodeListener(this,
TreePolicy::GetNode(fNextTreeNode));
}
fSuspended = true; fSuspended = true;
return B_OK; return B_OK;
@@ -150,15 +149,11 @@ GenericIndexIterator<Policy>::SetTo(Index* index, const Value& value,
if (fIndex == NULL) if (fIndex == NULL)
return false; return false;
typename NodeTree::Iterator iterator; if (ignoreValue)
if (ignoreValue) { fNextTreeNode = TreePolicy::GetFirstTreeNode(fIndex);
Policy::GetNodeTree(fIndex)->GetIterator(&iterator); else
} else if (Policy::GetNodeTree(fIndex)->FindFirstClosest(value, false, fNextTreeNode = TreePolicy::FindClosestTreeNode(fIndex, value);
&iterator) == NULL) {
return false;
}
fNextTreeNode = iterator.CurrentNode();
return fNextTreeNode != NULL; return fNextTreeNode != NULL;
} }
@@ -182,20 +177,17 @@ template<typename Policy>
void void
GenericIndexIterator<Policy>::NodeChangeEnd(Node* node) GenericIndexIterator<Policy>::NodeChangeEnd(Node* node)
{ {
if (fNextTreeNode != NULL) { if (fNextTreeNode != NULL)
fNextTreeNode = Policy::GetNodeTree(fIndex)->Next(fNextTreeNode); fNextTreeNode = Policy::GetNodeTree(fIndex)->Next(fNextTreeNode);
} else { else
typename NodeTree::Iterator iterator; fNextTreeNode = TreePolicy::GetFirstTreeNode(fIndex);
Policy::GetNodeTree(fIndex)->GetIterator(&iterator);
fNextTreeNode = iterator.CurrentNode();
}
// If the node is no longer the one we originally pointed to, re-register // If the node is no longer the one we originally pointed to, re-register
// the node listener. // the node listener.
if (fNextTreeNode == NULL) { if (fNextTreeNode == NULL) {
fIndex->GetVolume()->RemoveNodeListener(this); fIndex->GetVolume()->RemoveNodeListener(this);
} else { } else {
Node* newNode = _ToNode(); Node* newNode = TreePolicy::GetNode(fNextTreeNode);
if (newNode != node) { if (newNode != node) {
fIndex->GetVolume()->RemoveNodeListener(this); fIndex->GetVolume()->RemoveNodeListener(this);
fIndex->GetVolume()->AddNodeListener(this, newNode); fIndex->GetVolume()->AddNodeListener(this, newNode);
@@ -215,13 +207,42 @@ GenericIndexIterator<Policy>::NodeRemoved(Node* node)
template<typename Policy> template<typename Policy>
Node* struct GenericIndexIteratorTreePolicy {
GenericIndexIterator<Policy>::_ToNode() const typedef typename Policy::Index Index;
{ typedef typename Policy::Value Value;
// return NodeTree::NodeStrategy().GetValue(fNextTreeNode); typedef typename Policy::NodeTree NodeTree;
typename NodeTree::NodeStrategy strategy; typedef typename NodeTree::Node TreeNode;
return strategy.GetValue(fNextTreeNode);
} static Node* GetNode(TreeNode* treeNode)
{
typename Policy::NodeTree::NodeStrategy strategy;
return strategy.GetValue(treeNode);
}
static TreeNode* GetFirstTreeNode(Index* index)
{
typename NodeTree::Iterator iterator;
Policy::GetNodeTree(index)->GetIterator(&iterator);
return iterator.CurrentNode();
}
static TreeNode* FindClosestTreeNode(Index* index, const Value& value)
{
typename NodeTree::Iterator iterator;
if (Policy::GetNodeTree(index)->FindFirstClosest(value, false,
&iterator) == NULL) {
return NULL;
}
return iterator.CurrentNode();
}
static void GetTreeNodeValue(TreeNode* treeNode, void* buffer,
size_t* _keyLength)
{
Policy::GetNodeValue(GetNode(treeNode), buffer, _keyLength);
}
};
#endif // INDEX_IMPL_H #endif // INDEX_IMPL_H
@@ -105,9 +105,10 @@ class LastModifiedIndex::IteratorList : public SinglyLinkedList<Iterator> {};
struct LastModifiedIndex::IteratorPolicy { struct LastModifiedIndex::IteratorPolicy {
typedef LastModifiedIndex Index; typedef LastModifiedIndex Index;
typedef time_t Value; typedef time_t Value;
typedef LastModifiedIndex::NodeTree NodeTree; typedef LastModifiedIndex::NodeTree NodeTree;
typedef GenericIndexIteratorTreePolicy<IteratorPolicy> TreePolicy;
static NodeTree* GetNodeTree(Index* index) static NodeTree* GetNodeTree(Index* index)
{ {
@@ -85,9 +85,10 @@ class NameIndex::EntryTree : public _EntryTree {
struct NameIndex::IteratorPolicy { struct NameIndex::IteratorPolicy {
typedef NameIndex Index; typedef NameIndex Index;
typedef const char* Value; typedef const char* Value;
typedef NameIndex::EntryTree NodeTree; typedef NameIndex::EntryTree NodeTree;
typedef GenericIndexIteratorTreePolicy<IteratorPolicy> TreePolicy;
static NodeTree* GetNodeTree(Index* index) static NodeTree* GetNodeTree(Index* index)
{ {
@@ -104,9 +104,10 @@ class SizeIndex::IteratorList : public SinglyLinkedList<Iterator> {};
struct SizeIndex::IteratorPolicy { struct SizeIndex::IteratorPolicy {
typedef SizeIndex Index; typedef SizeIndex Index;
typedef off_t Value; typedef off_t Value;
typedef SizeIndex::NodeTree NodeTree; typedef SizeIndex::NodeTree NodeTree;
typedef GenericIndexIteratorTreePolicy<IteratorPolicy> TreePolicy;
static NodeTree* GetNodeTree(Index* index) static NodeTree* GetNodeTree(Index* index)
{ {