Class: VinaryTree::Libdictenstein::EntryCursorState

Inherits:
Object
  • Object
show all
Defined in:
lib/vinary_tree/libdictenstein.rb

Overview

Shared low-level adapter over one opaque native entry cursor. Every key is copied before a leased batch is released.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(handle, max_entries:, max_units:, max_values:) ⇒ EntryCursorState

Returns a new instance of EntryCursorState.

Raises:

  • (ArgumentError)


72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/vinary_tree/libdictenstein.rb', line 72

def initialize(handle, max_entries:, max_units:, max_values:)
  raise ArgumentError, "max_entries must be positive" unless max_entries.positive?
  raise ArgumentError, "entry batch limits must be nonnegative" if max_units.negative? || max_values.negative?

  @mutex = Mutex.new
  @cursor = 0
  @leased = false
  @ended = false
  @index = 0
  @limits_memory = Fiddle::Pointer.malloc(Native::EntryBatchLimits.size, Fiddle::RUBY_FREE)
  @limits = Native::EntryBatchLimits.new(@limits_memory)
  @limits.max_entries = max_entries
  @limits.max_units = max_units
  @limits.max_values = max_values
  @limits.reserved = 0
  @batch_memory = Fiddle::Pointer.malloc(Native::EntryBatch.size, Fiddle::RUBY_FREE)
  @batch = Native::EntryBatch.new(@batch_memory)
  info_memory = Fiddle::Pointer.malloc(Native::EntriesInfo.size, Fiddle::RUBY_FREE)
  native_info = Native::EntriesInfo.new(info_memory)
  cursor_output = Native.pointer_output
  handle.with_pointer do |dictionary|
    Libdictenstein.check(
      Native.ldict_dictionary_entries_open(dictionary, cursor_output, info_memory)
    )
  end
  @cursor = Native.read_pointer(cursor_output)
  flags = native_info.flags
  @info = EntryInfo.new(
    native_info.unit_domain,
    flags.anybits?(1) ? native_info.exact_len : nil,
    flags.anybits?(2) ? [native_info.identity_producer, native_info.identity_revision].freeze : nil
  )
end

Instance Attribute Details

#infoObject (readonly)

Returns the value of attribute info.



70
71
72
# File 'lib/vinary_tree/libdictenstein.rb', line 70

def info
  @info
end

Instance Method Details

#cancelObject



132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/vinary_tree/libdictenstein.rb', line 132

def cancel
  @mutex.synchronize do
    return nil if @cursor.zero? || @ended
    first_error = native_error(Native.ldict_entry_cursor_cancel(@cursor))
    begin
      release_locked
    rescue Exception => error
      first_error ||= error
    end
    @ended = true
    raise first_error if first_error
  end
  nil
end

#closeObject



147
148
149
# File 'lib/vinary_tree/libdictenstein.rb', line 147

def close
  @mutex.synchronize { close_locked(cancel: true) }
end

#closed?Boolean

Returns:

  • (Boolean)


151
152
153
# File 'lib/vinary_tree/libdictenstein.rb', line 151

def closed?
  @mutex.synchronize { @cursor.zero? }
end

#next_entryObject



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/vinary_tree/libdictenstein.rb', line 106

def next_entry
  @mutex.synchronize do
    return nil if @cursor.zero? || @ended
    begin
      unless @leased
        status = Native.ldict_entry_cursor_next(@cursor, @limits_memory, @batch_memory)
        if status == 1
          @ended = true
          close_locked(cancel: false)
          return nil
        end
        Libdictenstein.check(status)
        @leased = true
        @index = 0
      end
      result = copy_entry(@index)
      @index += 1
      release_locked if @index == @batch.entry_count
      result
    rescue Exception
      close_locked(cancel: true) rescue nil
      raise
    end
  end
end