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  }