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 }