Class: FFI::RadixTree::Tree

Inherits:
Object
  • Object
show all
Defined in:
lib/ffi/radix_tree.rb

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeTree

Returns a new instance of Tree.



95
96
97
98
# File 'lib/ffi/radix_tree.rb', line 95

def initialize
  @ptr = ::FFI::RadixTree.create
  @first_character_present = {}
end

Class Method Details

.destroy!(tree) ⇒ Object



91
92
93
# File 'lib/ffi/radix_tree.rb', line 91

def self.destroy!(tree)
  tree.destroy! unless tree.nil?
end

Instance Method Details

#destroy!Object



100
101
102
103
# File 'lib/ffi/radix_tree.rb', line 100

def destroy!
  ::FFI::RadixTree.destroy(@ptr) unless @ptr.nil?
  @ptr = nil
end

#erase(key) ⇒ Object



138
139
140
# File 'lib/ffi/radix_tree.rb', line 138

def erase(key)
  ::FFI::RadixTree.erase(@ptr, key)
end

#get(key) ⇒ Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/ffi/radix_tree.rb', line 142

def get(key)
  return nil unless @first_character_present[key[0]]
  byte_pointer = get_response = nil

  ::FFI::MemoryPointer.new(:int) do |byte_length|
    byte_pointer = ::FFI::RadixTree.fetch(@ptr, key, byte_length)
    bytesize = byte_length.read_int

    if bytesize && bytesize > 0
      bytes = byte_pointer.get_bytes(0, bytesize)
      get_response = ::MessagePack.unpack(bytes)
    end
  end

  get_response
ensure
  ::FFI::RadixTree.match_free(byte_pointer) if byte_pointer
end

#greedy_match(string) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/ffi/radix_tree.rb', line 208

def greedy_match(string)
  return [] unless @first_character_present[string[0]]
  array_pointer = nil
  match_sizes_pointer = nil
  array_size = 0
  get_response = []

  ::FFI::MemoryPointer.new(:pointer) do |match_array|
    ::FFI::MemoryPointer.new(:pointer) do |match_sizes_array|
      array_size = ::FFI::RadixTree.greedy_match(@ptr, string, match_array, match_sizes_array)
      if array_size > 0
        array_sizes_pointer = match_sizes_array.read_pointer
        match_sizes = array_sizes_pointer.get_array_of_int(0, array_size)
        array_pointer = match_array.read_pointer
        char_arrays = array_pointer.get_array_of_pointer(0, array_size)
        char_arrays.each_with_index do |ptr, index|
          get_response << ::MessagePack.unpack(ptr.get_bytes(0, match_sizes[index]))
        end
      end
    end
  end

  get_response
ensure
  ::FFI::RadixTree.multi_match_free(array_pointer, array_size) if array_pointer
  ::FFI::RadixTree.match_free(match_sizes_pointer) if match_sizes_pointer
end

#greedy_substring_match(string) ⇒ Object



236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
# File 'lib/ffi/radix_tree.rb', line 236

def greedy_substring_match(string)
  array_pointer = nil
  match_sizes_pointer = nil
  array_size = 0
  get_response = []

  ::FFI::MemoryPointer.new(:pointer) do |match_array|
    ::FFI::MemoryPointer.new(:pointer) do |match_sizes_array|
      array_size = ::FFI::RadixTree.greedy_substring_match(@ptr, string, match_array, match_sizes_array)
      if array_size > 0
        array_sizes_pointer = match_sizes_array.read_pointer
        match_sizes = array_sizes_pointer.get_array_of_int(0, array_size)
        array_pointer = match_array.read_pointer
        char_arrays = array_pointer.get_array_of_pointer(0, array_size)
        char_arrays.each_with_index do |ptr, index|
          get_response << ::MessagePack.unpack(ptr.get_bytes(0, match_sizes[index]))
        end
      end
    end
  end

  get_response
ensure
  ::FFI::RadixTree.multi_match_free(array_pointer, array_size) if array_pointer
  ::FFI::RadixTree.match_free(match_sizes_pointer) if match_sizes_pointer
end

#has_key?(key) ⇒ Boolean

Returns:

  • (Boolean)


105
106
107
# File 'lib/ffi/radix_tree.rb', line 105

def has_key?(key)
  ::FFI::RadixTree.has_key(@ptr, key)
end

#longest_prefix(string) ⇒ Object



161
162
163
164
165
166
167
168
# File 'lib/ffi/radix_tree.rb', line 161

def longest_prefix(string)
  return nil unless @first_character_present[string[0]]
  value, p_out = ::FFI::RadixTree.longest_prefix(@ptr, string)
  value.force_encoding("UTF-8") if value
  value
ensure
  ::FFI::RadixTree.match_free(p_out) if p_out
end

#longest_prefix_and_value(string) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
# File 'lib/ffi/radix_tree.rb', line 170

def longest_prefix_and_value(string)
  return [nil, nil] unless @first_character_present[string[0]]
  byte_pointer = prefix_response = get_response = nil

  ::FFI::MemoryPointer.new(:int) do |byte_length|
    ::FFI::MemoryPointer.new(:int) do |prefix_length|
      byte_pointer = ::FFI::RadixTree.longest_prefix_and_value(@ptr, string, byte_length, prefix_length)
      bytesize = byte_length.read_int

      if bytesize && bytesize > 0
        prefix_size = prefix_length.read_int
        get_response = byte_pointer.get_bytes(0, bytesize)
        prefix_response = get_response[0..(prefix_size - 1)]
        get_response = ::MessagePack.unpack(get_response[prefix_size..-1])
      end
    end
  end

  [prefix_response, get_response]
ensure
  ::FFI::RadixTree.match_free(byte_pointer) if byte_pointer
end

#longest_prefix_value(string) ⇒ Object



193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/ffi/radix_tree.rb', line 193

def longest_prefix_value(string)
  return nil unless @first_character_present[string[0]]
  byte_pointer = get_response = nil

  ::FFI::MemoryPointer.new(:int) do |byte_length|
    byte_pointer = ::FFI::RadixTree.longest_prefix_value(@ptr, string, byte_length)
    bytesize = byte_length.read_int
    get_response = ::MessagePack.unpack(byte_pointer.get_bytes(0, bytesize)) if bytesize && bytesize > 0
  end

  get_response
ensure
  ::FFI::RadixTree.match_free(byte_pointer) if byte_pointer
end

#push(key, value) ⇒ Object



109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ffi/radix_tree.rb', line 109

def push(key, value)
  push_response = nil
  @first_character_present[key[0]] = true
  storage_data = ::MessagePack.pack(value)
  bytesize = storage_data.bytesize

  ::FFI::MemoryPointer.new(:char, bytesize, true) do |memory_buffer|
    memory_buffer.put_bytes(0, storage_data)
    push_response = ::FFI::RadixTree.insert(@ptr, key, memory_buffer, bytesize)
  end

  push_response
end

#push_or_update(key, value) ⇒ Object



123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/ffi/radix_tree.rb', line 123

def push_or_update(key, value)
  response = nil
  @first_character_present[key[0]] = true
  storage_data = ::MessagePack.pack(value)
  bytesize = storage_data.bytesize

  ::FFI::MemoryPointer.new(:char, bytesize, true) do |memory_buffer|
    memory_buffer.put_bytes(0, storage_data)
    response = ::FFI::RadixTree.update(@ptr, key, memory_buffer, bytesize)
    response ||= ::FFI::RadixTree.insert(@ptr, key, memory_buffer, bytesize)
  end

  response
end