Class: Innodb::Index::IndexCursor

Inherits:
Object
  • Object
show all
Defined in:
lib/innodb/index.rb

Overview

A cursor to walk the index (cursor) forwards or backward starting with a given record, or the minimum (:min) or maximum (:max) record in the index.

Instance Method Summary collapse

Constructor Details

#initialize(index, record, direction) ⇒ IndexCursor

Returns a new instance of IndexCursor.



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/innodb/index.rb', line 262

def initialize(index, record, direction)
  Innodb::Stats.increment :index_cursor_create
  @initial = true
  @index = index
  @direction = direction
  case record
  when :min
    # Start at the minimum record on the minimum page in the index.
    @page = index.min_page_at_level(0)
    @page_cursor = @page.record_cursor(:min, direction)
  when :max
    # Start at the maximum record on the maximum page in the index.
    @page = index.max_page_at_level(0)
    @page_cursor = @page.record_cursor(:max, direction)
  else
    # Start at the record provided.
    @page = record.page
    @page_cursor = @page.record_cursor(record.offset, direction)
  end
  @record = @page_cursor.record
end

Instance Method Details

#current_record ⇒ Object

Return the current record, mostly as a helper.



285
286
287
# File 'lib/innodb/index.rb', line 285

def current_record
  @record
end

#each_record ⇒ Object

Iterate through all records in the cursor.



352
353
354
355
356
357
358
359
360
# File 'lib/innodb/index.rb', line 352

def each_record
  unless block_given?
    return enum_for(:each_record)
  end

  while rec = record
    yield rec
  end
end

#next_record ⇒ Object

Move to the next record in the forward direction and return it.



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/innodb/index.rb', line 290

def next_record
  Innodb::Stats.increment :index_cursor_next_record

  while true
    if rec = @page_cursor.record
      return rec
    end

    unless next_page = @page.next
      return nil
    end

    unless @page = @index.page(next_page)
      raise "Failed to load next page"
    end

    unless @page_cursor = @page.record_cursor(:min, @direction)
      raise "Failed to position cursor"
    end
  end
end

#prev_record ⇒ Object

Move to the previous record in the backward direction and return it.



313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/innodb/index.rb', line 313

def prev_record
  Innodb::Stats.increment :index_cursor_prev_record

  while true
    if rec = @page_cursor.record
      return rec
    end

    unless prev_page = @page.prev
      return nil
    end

    unless @page = @index.page(prev_page)
      raise "Failed to load prev page"
    end

    unless @page_cursor = @page.record_cursor(:max, @direction)
      raise "Failed to position cursor"
    end
  end
  raise "Not implemented"
end

#record ⇒ Object

Return the next record in the order defined when the cursor was created.



337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/innodb/index.rb', line 337

def record
  if @initial
    @initial = false
    return current_record
  end

  case @direction
  when :forward
    next_record
  when :backward
    prev_record
  end
end