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