bitcoinleveldb_duplex/two_level_iterator.rs
1crate::ix!();
2
3//-------------------------------------------[.cpp/bitcoin/src/leveldb/table/two_level_iterator.h]
4//-------------------------------------------[.cpp/bitcoin/src/leveldb/table/two_level_iterator.cc]
5
6pub type BlockFunction = fn(*mut c_void,&ReadOptions,&Slice);
7
8pub struct TwoLevelIterator {
9 base: LevelDBIterator,
10 block_function: BlockFunction,
11 arg: *mut c_void,
12 options: ReadOptions,
13 status: Status,
14 index_iter: LevelDBIteratorWrapper,
15
16 /**
17 May be nullptr
18 */
19 data_iter: LevelDBIteratorWrapper,
20
21 /**
22 | If data_iter_ is non-null, then
23 | "data_block_handle_" holds the
24 | "index_value" passed to block_function_ to
25 | create the data_iter_.
26 |
27 */
28 data_block_handle: String,
29}
30
31impl TwoLevelIterator {
32
33 pub fn valid(&self) -> bool {
34
35 todo!();
36 /*
37 return data_iter_.Valid();
38 */
39 }
40
41 pub fn key(&self) -> Slice {
42
43 todo!();
44 /*
45 assert(Valid());
46 return data_iter_.key();
47 */
48 }
49
50 pub fn value(&self) -> Slice {
51
52 todo!();
53 /*
54 assert(Valid());
55 return data_iter_.value();
56 */
57 }
58
59 pub fn status(&self) -> crate::Status {
60
61 todo!();
62 /*
63 // It'd be nice if status() returned a const Status& instead of a Status
64 if (!index_iter_.status().ok()) {
65 return index_iter_.status();
66 } else if (data_iter_.iter() != nullptr && !data_iter_.status().ok()) {
67 return data_iter_.status();
68 } else {
69 return status_;
70 }
71 */
72 }
73
74 pub fn save_error(&mut self, s: &Status) {
75
76 todo!();
77 /*
78 if (status_.ok() && !s.ok()) status_ = s;
79 */
80 }
81
82 pub fn new(
83 index_iter: *mut LevelDBIterator,
84 block_function: BlockFunction,
85 arg: *mut c_void,
86 options: &ReadOptions) -> Self {
87
88 todo!();
89 /*
90 : block_function(block_function),
91 : arg(arg),
92 : options(options),
93 : index_iter(index_iter),
94 : data_iter(nullptr),
95
96
97 */
98 }
99
100 pub fn seek(&mut self, target: &Slice) {
101
102 todo!();
103 /*
104 index_iter_.Seek(target);
105 InitDataBlock();
106 if (data_iter_.iter() != nullptr) data_iter_.Seek(target);
107 SkipEmptyDataBlocksForward();
108 */
109 }
110
111 pub fn seek_to_first(&mut self) {
112
113 todo!();
114 /*
115 index_iter_.SeekToFirst();
116 InitDataBlock();
117 if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
118 SkipEmptyDataBlocksForward();
119 */
120 }
121
122 pub fn seek_to_last(&mut self) {
123
124 todo!();
125 /*
126 index_iter_.SeekToLast();
127 InitDataBlock();
128 if (data_iter_.iter() != nullptr) data_iter_.SeekToLast();
129 SkipEmptyDataBlocksBackward();
130 */
131 }
132
133 pub fn next(&mut self) {
134
135 todo!();
136 /*
137 assert(Valid());
138 data_iter_.Next();
139 SkipEmptyDataBlocksForward();
140 */
141 }
142
143 pub fn prev(&mut self) {
144
145 todo!();
146 /*
147 assert(Valid());
148 data_iter_.Prev();
149 SkipEmptyDataBlocksBackward();
150 */
151 }
152
153 pub fn skip_empty_data_blocks_forward(&mut self) {
154
155 todo!();
156 /*
157 while (data_iter_.iter() == nullptr || !data_iter_.Valid()) {
158 // Move to next block
159 if (!index_iter_.Valid()) {
160 SetDataIterator(nullptr);
161 return;
162 }
163 index_iter_.Next();
164 InitDataBlock();
165 if (data_iter_.iter() != nullptr) data_iter_.SeekToFirst();
166 }
167 */
168 }
169
170 pub fn skip_empty_data_blocks_backward(&mut self) {
171
172 todo!();
173 /*
174 while (data_iter_.iter() == nullptr || !data_iter_.Valid()) {
175 // Move to next block
176 if (!index_iter_.Valid()) {
177 SetDataIterator(nullptr);
178 return;
179 }
180 index_iter_.Prev();
181 InitDataBlock();
182 if (data_iter_.iter() != nullptr) data_iter_.SeekToLast();
183 }
184 */
185 }
186
187 pub fn set_data_iterator(&mut self, data_iter: *mut LevelDBIterator) {
188
189 todo!();
190 /*
191 if (data_iter_.iter() != nullptr) SaveError(data_iter_.status());
192 data_iter_.Set(data_iter);
193 */
194 }
195
196 pub fn init_data_block(&mut self) {
197
198 todo!();
199 /*
200 if (!index_iter_.Valid()) {
201 SetDataIterator(nullptr);
202 } else {
203 Slice handle = index_iter_.value();
204 if (data_iter_.iter() != nullptr &&
205 handle.compare(data_block_handle_) == 0) {
206 // data_iter_ is already constructed with this iterator, so
207 // no need to change anything
208 } else {
209 Iterator* iter = (*block_function_)(arg_, options_, handle);
210 data_block_handle_.assign(handle.data(), handle.size());
211 SetDataIterator(iter);
212 }
213 }
214 */
215 }
216}
217
218/**
219 | Return a new two level iterator. A two-level
220 | iterator contains an index iterator whose
221 | values point to a sequence of blocks where each
222 | block is itself a sequence of key,value pairs.
223 | The returned two-level iterator yields the
224 | concatenation of all key/value pairs in the
225 | sequence of blocks. Takes ownership of
226 | "index_iter" and will delete it when no longer
227 | needed.
228 |
229 | Uses a supplied function to convert an
230 | index_iter value into an iterator over the
231 | contents of the corresponding block.
232 */
233pub fn new_two_level_iterator(
234 index_iter: *mut LevelDBIterator,
235 block_function: BlockFunction,
236 arg: *mut c_void,
237 options: &ReadOptions) -> *mut LevelDBIterator {
238
239 todo!();
240 /*
241 return new TwoLevelIterator(index_iter, block_function, arg, options);
242 */
243}