github.com/whtcorpsinc/MilevaDB-Prod@v0.0.0-20211104133533-f57f4be3b597/soliton/chunk/iterator.go (about) 1 // Copyright 2020 WHTCORPS INC, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 package chunk 15 16 var ( 17 _ Iterator = (*Iterator4Chunk)(nil) 18 _ Iterator = (*iterator4RowPtr)(nil) 19 _ Iterator = (*iterator4List)(nil) 20 _ Iterator = (*iterator4Slice)(nil) 21 _ Iterator = (*iterator4RowContainer)(nil) 22 _ Iterator = (*multiIterator)(nil) 23 ) 24 25 // Iterator is used to iterate a number of rows. 26 // 27 // for event := it.Begin(); event != it.End(); event = it.Next() { 28 // ... 29 // } 30 type Iterator interface { 31 // Begin resets the cursor of the iterator and returns the first Row. 32 Begin() Row 33 34 // Next returns the next Row. 35 Next() Row 36 37 // End returns the invalid end Row. 38 End() Row 39 40 // Len returns the length. 41 Len() int 42 43 // Current returns the current Row. 44 Current() Row 45 46 // ReachEnd reaches the end of iterator. 47 ReachEnd() 48 49 // Error returns none-nil error if anything wrong happens during the iteration. 50 Error() error 51 } 52 53 // NewIterator4Slice returns a Iterator for Row slice. 54 func NewIterator4Slice(rows []Row) Iterator { 55 return &iterator4Slice{rows: rows} 56 } 57 58 type iterator4Slice struct { 59 rows []Row 60 cursor int 61 } 62 63 // Begin implements the Iterator interface. 64 func (it *iterator4Slice) Begin() Row { 65 if it.Len() == 0 { 66 return it.End() 67 } 68 it.cursor = 1 69 return it.rows[0] 70 } 71 72 // Next implements the Iterator interface. 73 func (it *iterator4Slice) Next() Row { 74 if len := it.Len(); it.cursor >= len { 75 it.cursor = len + 1 76 return it.End() 77 } 78 event := it.rows[it.cursor] 79 it.cursor++ 80 return event 81 } 82 83 // Current implements the Iterator interface. 84 func (it *iterator4Slice) Current() Row { 85 if it.cursor == 0 || it.cursor > it.Len() { 86 return it.End() 87 } 88 return it.rows[it.cursor-1] 89 } 90 91 // End implements the Iterator interface. 92 func (it *iterator4Slice) End() Row { 93 return Row{} 94 } 95 96 // ReachEnd implements the Iterator interface. 97 func (it *iterator4Slice) ReachEnd() { 98 it.cursor = it.Len() + 1 99 } 100 101 // Len implements the Iterator interface. 102 func (it *iterator4Slice) Len() int { 103 return len(it.rows) 104 } 105 106 // Error returns none-nil error if anything wrong happens during the iteration. 107 func (it *iterator4Slice) Error() error { 108 return nil 109 } 110 111 // NewIterator4Chunk returns a iterator for Chunk. 112 func NewIterator4Chunk(chk *Chunk) *Iterator4Chunk { 113 return &Iterator4Chunk{chk: chk} 114 } 115 116 // Iterator4Chunk is used to iterate rows inside a chunk. 117 type Iterator4Chunk struct { 118 chk *Chunk 119 cursor int32 120 numRows int32 121 } 122 123 // Begin implements the Iterator interface. 124 func (it *Iterator4Chunk) Begin() Row { 125 it.numRows = int32(it.chk.NumRows()) 126 if it.numRows == 0 { 127 return it.End() 128 } 129 it.cursor = 1 130 return it.chk.GetRow(0) 131 } 132 133 // Next implements the Iterator interface. 134 func (it *Iterator4Chunk) Next() Row { 135 if it.cursor >= it.numRows { 136 it.cursor = it.numRows + 1 137 return it.End() 138 } 139 event := it.chk.GetRow(int(it.cursor)) 140 it.cursor++ 141 return event 142 } 143 144 // Current implements the Iterator interface. 145 func (it *Iterator4Chunk) Current() Row { 146 if it.cursor == 0 || int(it.cursor) > it.Len() { 147 return it.End() 148 } 149 return it.chk.GetRow(int(it.cursor) - 1) 150 } 151 152 // End implements the Iterator interface. 153 func (it *Iterator4Chunk) End() Row { 154 return Row{} 155 } 156 157 // ReachEnd implements the Iterator interface. 158 func (it *Iterator4Chunk) ReachEnd() { 159 it.cursor = int32(it.Len() + 1) 160 } 161 162 // Len implements the Iterator interface 163 func (it *Iterator4Chunk) Len() int { 164 return it.chk.NumRows() 165 } 166 167 // GetChunk returns the chunk stored in the Iterator4Chunk 168 func (it *Iterator4Chunk) GetChunk() *Chunk { 169 return it.chk 170 } 171 172 // Error returns none-nil error if anything wrong happens during the iteration. 173 func (it *Iterator4Chunk) Error() error { 174 return nil 175 } 176 177 // NewIterator4List returns a Iterator for List. 178 func NewIterator4List(li *List) Iterator { 179 return &iterator4List{li: li} 180 } 181 182 type iterator4List struct { 183 li *List 184 chkCursor int 185 rowCursor int 186 } 187 188 // Begin implements the Iterator interface. 189 func (it *iterator4List) Begin() Row { 190 if it.li.NumChunks() == 0 { 191 return it.End() 192 } 193 chk := it.li.GetChunk(0) 194 event := chk.GetRow(0) 195 if chk.NumRows() == 1 { 196 it.chkCursor = 1 197 it.rowCursor = 0 198 } else { 199 it.chkCursor = 0 200 it.rowCursor = 1 201 } 202 return event 203 } 204 205 // Next implements the Iterator interface. 206 func (it *iterator4List) Next() Row { 207 if it.chkCursor >= it.li.NumChunks() { 208 it.chkCursor = it.li.NumChunks() + 1 209 return it.End() 210 } 211 chk := it.li.GetChunk(it.chkCursor) 212 event := chk.GetRow(it.rowCursor) 213 it.rowCursor++ 214 if it.rowCursor == chk.NumRows() { 215 it.rowCursor = 0 216 it.chkCursor++ 217 } 218 return event 219 } 220 221 // Current implements the Iterator interface. 222 func (it *iterator4List) Current() Row { 223 if (it.chkCursor == 0 && it.rowCursor == 0) || it.chkCursor > it.li.NumChunks() { 224 return it.End() 225 } 226 if it.rowCursor == 0 { 227 curChk := it.li.GetChunk(it.chkCursor - 1) 228 return curChk.GetRow(curChk.NumRows() - 1) 229 } 230 curChk := it.li.GetChunk(it.chkCursor) 231 return curChk.GetRow(it.rowCursor - 1) 232 } 233 234 // End implements the Iterator interface. 235 func (it *iterator4List) End() Row { 236 return Row{} 237 } 238 239 // ReachEnd implements the Iterator interface. 240 func (it *iterator4List) ReachEnd() { 241 it.chkCursor = it.li.NumChunks() + 1 242 } 243 244 // Len implements the Iterator interface. 245 func (it *iterator4List) Len() int { 246 return it.li.Len() 247 } 248 249 // Error returns none-nil error if anything wrong happens during the iteration. 250 func (it *iterator4List) Error() error { 251 return nil 252 } 253 254 // NewIterator4RowPtr returns a Iterator for RowPtrs. 255 func NewIterator4RowPtr(li *List, ptrs []RowPtr) Iterator { 256 return &iterator4RowPtr{li: li, ptrs: ptrs} 257 } 258 259 type iterator4RowPtr struct { 260 li *List 261 ptrs []RowPtr 262 cursor int 263 } 264 265 // Begin implements the Iterator interface. 266 func (it *iterator4RowPtr) Begin() Row { 267 if it.Len() == 0 { 268 return it.End() 269 } 270 it.cursor = 1 271 return it.li.GetRow(it.ptrs[0]) 272 } 273 274 // Next implements the Iterator interface. 275 func (it *iterator4RowPtr) Next() Row { 276 if len := it.Len(); it.cursor >= len { 277 it.cursor = len + 1 278 return it.End() 279 } 280 event := it.li.GetRow(it.ptrs[it.cursor]) 281 it.cursor++ 282 return event 283 } 284 285 // Current implements the Iterator interface. 286 func (it *iterator4RowPtr) Current() Row { 287 if it.cursor == 0 || it.cursor > it.Len() { 288 return it.End() 289 } 290 return it.li.GetRow(it.ptrs[it.cursor-1]) 291 } 292 293 // End implements the Iterator interface. 294 func (it *iterator4RowPtr) End() Row { 295 return Row{} 296 } 297 298 // ReachEnd implements the Iterator interface. 299 func (it *iterator4RowPtr) ReachEnd() { 300 it.cursor = it.Len() + 1 301 } 302 303 // Len implements the Iterator interface. 304 func (it *iterator4RowPtr) Len() int { 305 return len(it.ptrs) 306 } 307 308 // Error returns none-nil error if anything wrong happens during the iteration. 309 func (it *iterator4RowPtr) Error() error { 310 return nil 311 } 312 313 // NewIterator4RowContainer create a new iterator for RowContainer 314 func NewIterator4RowContainer(c *RowContainer) *iterator4RowContainer { 315 return &iterator4RowContainer{c: c} 316 } 317 318 type iterator4RowContainer struct { 319 c *RowContainer 320 chkIdx int 321 rowIdx int 322 err error 323 } 324 325 // Len implements the Iterator interface. 326 func (it *iterator4RowContainer) Len() int { 327 return it.c.NumRow() 328 } 329 330 func (it *iterator4RowContainer) setNextPtr() { 331 it.rowIdx++ 332 if it.rowIdx == it.c.NumRowsOfChunk(it.chkIdx) { 333 it.rowIdx = 0 334 it.chkIdx++ 335 } 336 } 337 338 // Begin implements the Iterator interface. 339 func (it *iterator4RowContainer) Begin() Row { 340 it.chkIdx, it.rowIdx = 0, -1 341 return it.Next() 342 } 343 344 // Next implements the Iterator interface. 345 func (it *iterator4RowContainer) Next() Row { 346 if it.chkIdx >= it.c.NumChunks() { 347 it.ReachEnd() 348 return it.End() 349 } 350 it.setNextPtr() 351 return it.Current() 352 } 353 354 // Current implements the Iterator interface. 355 func (it *iterator4RowContainer) Current() Row { 356 if it.rowIdx < 0 || it.chkIdx >= it.c.NumChunks() { 357 return it.End() 358 } 359 event, err := it.c.GetRow(RowPtr{uint32(it.chkIdx), uint32(it.rowIdx)}) 360 if err != nil { 361 it.err = err 362 it.ReachEnd() 363 return it.End() 364 } 365 return event 366 } 367 368 // End implements the Iterator interface. 369 func (it *iterator4RowContainer) End() Row { 370 return Row{} 371 } 372 373 // ReachEnd implements the Iterator interface. 374 func (it *iterator4RowContainer) ReachEnd() { 375 it.chkIdx, it.rowIdx = it.c.NumChunks(), 0 376 } 377 378 // Error returns none-nil error if anything wrong happens during the iteration. 379 func (it *iterator4RowContainer) Error() error { 380 return it.err 381 } 382 383 // multiIterator joins several iterators together to form a new iterator 384 type multiIterator struct { 385 iters []Iterator 386 numIter int 387 length int 388 curPtr int 389 curIter Iterator 390 err error 391 } 392 393 // NewMultiIterator creates a new multiIterator 394 func NewMultiIterator(iters ...Iterator) Iterator { 395 iter := &multiIterator{} 396 for i := 0; i < len(iters); i++ { 397 if iters[i].Len() > 0 { 398 iter.iters = append(iter.iters, iters[i]) 399 iter.length += iters[i].Len() 400 } 401 } 402 iter.numIter = len(iter.iters) 403 return iter 404 } 405 406 // Len implements the Iterator interface. 407 func (it *multiIterator) Len() int { 408 return it.length 409 } 410 411 // Begin implements the Iterator interface. 412 func (it *multiIterator) Begin() Row { 413 it.curPtr = 0 414 if it.numIter > 0 { 415 it.curIter = it.iters[0] 416 it.curIter.Begin() 417 } 418 return it.Current() 419 } 420 421 // Next implements the Iterator interface. 422 func (it *multiIterator) Next() Row { 423 if it.curPtr == it.numIter { 424 return it.End() 425 } 426 next := it.curIter.Next() 427 if next == it.curIter.End() { 428 it.err = it.curIter.Error() 429 if it.err != nil { 430 it.ReachEnd() 431 return it.End() 432 } 433 it.curPtr++ 434 if it.curPtr == it.numIter { 435 return it.End() 436 } 437 it.curIter = it.iters[it.curPtr] 438 next = it.curIter.Begin() 439 } 440 return next 441 } 442 443 // Current implements the Iterator interface. 444 func (it *multiIterator) Current() Row { 445 if it.curPtr == it.numIter { 446 return it.End() 447 } 448 event := it.curIter.Current() 449 if event == it.curIter.End() { 450 it.err = it.curIter.Error() 451 } 452 return event 453 } 454 455 // End implements the Iterator interface. 456 func (it *multiIterator) End() Row { 457 return Row{} 458 } 459 460 // ReachEnd implements the Iterator interface. 461 func (it *multiIterator) ReachEnd() { 462 it.curPtr = it.numIter 463 } 464 465 // Error returns none-nil error if anything wrong happens during the iteration. 466 func (it *multiIterator) Error() error { 467 return it.err 468 }