github.com/bingoohuang/gg@v0.0.0-20240325092523-45da7dee9335/pkg/sqlparse/tidbparser/dependency/util/chunk/iterator.go (about)

     1  // Copyright 2017 PingCAP, 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  )
    22  
    23  // Iterator is used to iterate a number of rows.
    24  //
    25  //	for row := it.Begin(); row != it.End(); row = it.Next() {
    26  //	    ...
    27  //	}
    28  type Iterator interface {
    29  	// Begin resets the cursor of the iterator and returns the first Row.
    30  	Begin() Row
    31  
    32  	// Next returns the next Row.
    33  	Next() Row
    34  
    35  	// End returns the invalid end Row.
    36  	End() Row
    37  
    38  	// Len returns the length.
    39  	Len() int
    40  
    41  	// Current returns the current Row.
    42  	Current() Row
    43  
    44  	// ReachEnd reaches the end of iterator.
    45  	ReachEnd()
    46  }
    47  
    48  // NewIterator4Slice returns a Iterator for Row slice.
    49  func NewIterator4Slice(rows []Row) Iterator {
    50  	return &iterator4Slice{rows: rows}
    51  }
    52  
    53  type iterator4Slice struct {
    54  	rows   []Row
    55  	cursor int
    56  }
    57  
    58  // Begin implements the Iterator interface.
    59  func (it *iterator4Slice) Begin() Row {
    60  	if it.Len() == 0 {
    61  		return it.End()
    62  	}
    63  	it.cursor = 1
    64  	return it.rows[0]
    65  }
    66  
    67  // Next implements the Iterator interface.
    68  func (it *iterator4Slice) Next() Row {
    69  	if len := it.Len(); it.cursor >= len {
    70  		it.cursor = len + 1
    71  		return it.End()
    72  	}
    73  	row := it.rows[it.cursor]
    74  	it.cursor++
    75  	return row
    76  }
    77  
    78  // Current implements the Iterator interface.
    79  func (it *iterator4Slice) Current() Row {
    80  	if it.cursor == 0 || it.cursor > it.Len() {
    81  		return it.End()
    82  	}
    83  	return it.rows[it.cursor-1]
    84  }
    85  
    86  // End implements the Iterator interface.
    87  func (it *iterator4Slice) End() Row {
    88  	return Row{}
    89  }
    90  
    91  // ReachEnd implements the Iterator interface.
    92  func (it *iterator4Slice) ReachEnd() {
    93  	it.cursor = it.Len() + 1
    94  }
    95  
    96  // Len implements the Iterator interface.
    97  func (it *iterator4Slice) Len() int {
    98  	return len(it.rows)
    99  }
   100  
   101  // NewIterator4Chunk returns a iterator for Chunk.
   102  func NewIterator4Chunk(chk *Chunk) *Iterator4Chunk {
   103  	return &Iterator4Chunk{chk: chk}
   104  }
   105  
   106  // Iterator4Chunk is used to iterate rows inside a chunk.
   107  type Iterator4Chunk struct {
   108  	chk    *Chunk
   109  	cursor int
   110  }
   111  
   112  // Begin implements the Iterator interface.
   113  func (it *Iterator4Chunk) Begin() Row {
   114  	if it.chk.NumRows() == 0 {
   115  		return it.End()
   116  	}
   117  	it.cursor = 1
   118  	return it.chk.GetRow(0)
   119  }
   120  
   121  // Next implements the Iterator interface.
   122  func (it *Iterator4Chunk) Next() Row {
   123  	if it.cursor >= it.chk.NumRows() {
   124  		it.cursor = it.chk.NumRows() + 1
   125  		return it.End()
   126  	}
   127  	row := it.chk.GetRow(it.cursor)
   128  	it.cursor++
   129  	return row
   130  }
   131  
   132  // Current implements the Iterator interface.
   133  func (it *Iterator4Chunk) Current() Row {
   134  	if it.cursor == 0 || it.cursor > it.Len() {
   135  		return it.End()
   136  	}
   137  	return it.chk.GetRow(it.cursor - 1)
   138  }
   139  
   140  // End implements the Iterator interface.
   141  func (it *Iterator4Chunk) End() Row {
   142  	return Row{}
   143  }
   144  
   145  // ReachEnd implements the Iterator interface.
   146  func (it *Iterator4Chunk) ReachEnd() {
   147  	it.cursor = it.Len() + 1
   148  }
   149  
   150  // Len implements the Iterator interface
   151  func (it *Iterator4Chunk) Len() int {
   152  	return it.chk.NumRows()
   153  }
   154  
   155  // NewIterator4List returns a Iterator for List.
   156  func NewIterator4List(li *List) Iterator {
   157  	return &iterator4List{li: li}
   158  }
   159  
   160  type iterator4List struct {
   161  	li        *List
   162  	chkCursor int
   163  	rowCursor int
   164  }
   165  
   166  // Begin implements the Iterator interface.
   167  func (it *iterator4List) Begin() Row {
   168  	if it.li.NumChunks() == 0 {
   169  		return it.End()
   170  	}
   171  	chk := it.li.GetChunk(0)
   172  	row := chk.GetRow(0)
   173  	if chk.NumRows() == 1 {
   174  		it.chkCursor = 1
   175  		it.rowCursor = 0
   176  	} else {
   177  		it.chkCursor = 0
   178  		it.rowCursor = 1
   179  	}
   180  	return row
   181  }
   182  
   183  // Next implements the Iterator interface.
   184  func (it *iterator4List) Next() Row {
   185  	if it.chkCursor >= it.li.NumChunks() {
   186  		it.chkCursor = it.li.NumChunks() + 1
   187  		return it.End()
   188  	}
   189  	chk := it.li.GetChunk(it.chkCursor)
   190  	row := chk.GetRow(it.rowCursor)
   191  	it.rowCursor++
   192  	if it.rowCursor == chk.NumRows() {
   193  		it.rowCursor = 0
   194  		it.chkCursor++
   195  	}
   196  	return row
   197  }
   198  
   199  // Current implements the Iterator interface.
   200  func (it *iterator4List) Current() Row {
   201  	if (it.chkCursor == 0 && it.rowCursor == 0) || it.chkCursor > it.li.NumChunks() {
   202  		return it.End()
   203  	}
   204  	if it.rowCursor == 0 {
   205  		curChk := it.li.GetChunk(it.chkCursor - 1)
   206  		return curChk.GetRow(curChk.NumRows() - 1)
   207  	}
   208  	curChk := it.li.GetChunk(it.chkCursor)
   209  	return curChk.GetRow(it.rowCursor - 1)
   210  }
   211  
   212  // End implements the Iterator interface.
   213  func (it *iterator4List) End() Row {
   214  	return Row{}
   215  }
   216  
   217  // ReachEnd implements the Iterator interface.
   218  func (it *iterator4List) ReachEnd() {
   219  	it.chkCursor = it.li.NumChunks() + 1
   220  }
   221  
   222  // Len implements the Iterator interface.
   223  func (it *iterator4List) Len() int {
   224  	return it.li.Len()
   225  }
   226  
   227  // NewIterator4RowPtr returns a Iterator for RowPtrs.
   228  func NewIterator4RowPtr(li *List, ptrs []RowPtr) Iterator {
   229  	return &iterator4RowPtr{li: li, ptrs: ptrs}
   230  }
   231  
   232  type iterator4RowPtr struct {
   233  	li     *List
   234  	ptrs   []RowPtr
   235  	cursor int
   236  }
   237  
   238  // Begin implements the Iterator interface.
   239  func (it *iterator4RowPtr) Begin() Row {
   240  	if it.Len() == 0 {
   241  		return it.End()
   242  	}
   243  	it.cursor = 1
   244  	return it.li.GetRow(it.ptrs[0])
   245  }
   246  
   247  // Next implements the Iterator interface.
   248  func (it *iterator4RowPtr) Next() Row {
   249  	if len := it.Len(); it.cursor >= len {
   250  		it.cursor = len + 1
   251  		return it.End()
   252  	}
   253  	row := it.li.GetRow(it.ptrs[it.cursor])
   254  	it.cursor++
   255  	return row
   256  }
   257  
   258  // Current implements the Iterator interface.
   259  func (it *iterator4RowPtr) Current() Row {
   260  	if it.cursor == 0 || it.cursor > it.Len() {
   261  		return it.End()
   262  	}
   263  	return it.li.GetRow(it.ptrs[it.cursor-1])
   264  }
   265  
   266  // End implements the Iterator interface.
   267  func (it *iterator4RowPtr) End() Row {
   268  	return Row{}
   269  }
   270  
   271  // ReachEnd implements the Iterator interface.
   272  func (it *iterator4RowPtr) ReachEnd() {
   273  	it.cursor = it.Len() + 1
   274  }
   275  
   276  // Len implements the Iterator interface.
   277  func (it *iterator4RowPtr) Len() int {
   278  	return len(it.ptrs)
   279  }