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