1/* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * All rights reserved. Distributed under the terms of the MIT license. 4 */ 5#ifndef INDEX_IMPL_H 6#define INDEX_IMPL_H 7 8#include "Index.h" 9#include "Node.h" 10 11// AbstractIndexEntryIterator 12class AbstractIndexEntryIterator { 13public: 14 AbstractIndexEntryIterator(); 15 virtual ~AbstractIndexEntryIterator(); 16 17 virtual Entry *GetCurrent() = 0; 18 virtual Entry *GetCurrent(uint8 *buffer, size_t *keyLength) = 0; 19 virtual Entry *GetPrevious() = 0; 20 virtual Entry *GetNext() = 0; 21 22 virtual status_t Suspend(); 23 virtual status_t Resume(); 24}; 25 26 27// NodeEntryIterator 28template<typename NodeIterator> 29class NodeEntryIterator : public AbstractIndexEntryIterator { 30public: 31 NodeEntryIterator(); 32 virtual ~NodeEntryIterator(); 33 34 void Unset(); 35 36 virtual Entry *GetCurrent(); 37 virtual Entry *GetCurrent(uint8 *buffer, size_t *keyLength) = 0; 38 virtual Entry *GetPrevious(); 39 virtual Entry *GetNext(); 40 41 virtual status_t Suspend(); 42 virtual status_t Resume(); 43 44 Node *GetCurrentNode() const { return fNode; } 45 46protected: 47 NodeIterator fIterator; 48 Node *fNode; 49 Entry *fEntry; 50 bool fInitialized; 51 bool fIsNext; 52 bool fSuspended; 53}; 54 55// constructor 56template<typename NodeIterator> 57NodeEntryIterator<NodeIterator>::NodeEntryIterator() 58 : AbstractIndexEntryIterator(), 59 fIterator(), 60 fNode(NULL), 61 fEntry(NULL), 62 fInitialized(false), 63 fIsNext(false), 64 fSuspended(false) 65{ 66} 67 68// destructor 69template<typename NodeIterator> 70NodeEntryIterator<NodeIterator>::~NodeEntryIterator() 71{ 72} 73 74// Unset 75template<typename NodeIterator> 76void 77NodeEntryIterator<NodeIterator>::Unset() 78{ 79 fNode = NULL; 80 fEntry = NULL; 81 fInitialized = false; 82 fIsNext = false; 83 fSuspended = false; 84} 85 86// GetCurrent 87template<typename NodeIterator> 88Entry * 89NodeEntryIterator<NodeIterator>::GetCurrent() 90{ 91 return fEntry; 92} 93 94// GetPrevious 95template<typename NodeIterator> 96Entry * 97NodeEntryIterator<NodeIterator>::GetPrevious() 98{ 99 return NULL; // backwards iteration not implemented 100} 101 102// GetNext 103template<typename NodeIterator> 104Entry * 105NodeEntryIterator<NodeIterator>::GetNext() 106{ 107 if (!fInitialized || !fNode || fSuspended) 108 return NULL; 109 if (!(fEntry && fIsNext)) { 110 while (fNode) { 111 if (fEntry) 112 fEntry = fNode->GetNextReferrer(fEntry); 113 while (fNode && !fEntry) { 114 fNode = NULL; 115 if (Node **nodeP = fIterator.GetNext()) { 116 fNode = *nodeP; 117 fEntry = fNode->GetFirstReferrer(); 118 } 119 } 120 if (fEntry) 121 break; 122 } 123 } 124 fIsNext = false; 125 return fEntry; 126} 127 128// Suspend 129template<typename NodeIterator> 130status_t 131NodeEntryIterator<NodeIterator>::Suspend() 132{ 133 status_t error = (fInitialized && !fSuspended ? B_OK : B_BAD_VALUE); 134 if (error == B_OK) 135 fSuspended = true; 136 return error; 137} 138 139// Resume 140template<typename NodeIterator> 141status_t 142NodeEntryIterator<NodeIterator>::Resume() 143{ 144 status_t error = (fInitialized && fSuspended ? B_OK : B_BAD_VALUE); 145 if (error == B_OK) 146 fSuspended = false; 147 return error; 148} 149 150#endif // INDEX_IMPL_H 151