Module: Store::Digest::Meta::LMDB

Includes:
Store::Digest::Meta, Trait::RootDir
Included in:
Driver::LMDB
Defined in:
lib/store/digest/meta/lmdb.rb,
lib/store/digest/meta/lmdb/v0.rb,
lib/store/digest/meta/lmdb/v1.rb

Overview

Symas LMDB Metadata driver.

Defined Under Namespace

Modules: V0, V1

Constant Summary collapse

PARAMS =

Return a list of objects matching the given criteria. The result set will be the intersection of all supplied parameters. :type, :charset, :encoding, and :language are treated like discrete sets, while the rest of the parameters are treated like ranges (two-element arrays). Single values will be coerced into arrays; single range values will be interpreted as an inclusive lower bound. To bound only at the top, use a two-element array with its first value nil, like so: size: [nil, 31337]. The sorting criteria are the symbols of the other parameters.

Returns:

  • (Array)

    the list

%i[type charset encoding language
size ctime mtime ptime dtime].freeze

Instance Attribute Summary

Attributes included from Trait::RootDir

#dir, #umask

Instance Method Summary collapse

Instance Method Details

#algorithmsArray

Return the set of algorithms initialized in the database.

Returns:

  • (Array)

    the algorithms



151
152
153
154
155
156
157
# File 'lib/store/digest/meta/lmdb.rb', line 151

def algorithms
  @algorithms ||= lmdb.transaction? true do
    if ret = lmdb[:control]['algorithms']
      ret.strip.downcase.split(/\s*,+\s*/).map(&:to_sym)
    end
  end
end

#bytesInteger

Return the number of bytes stored in the database (notwithstanding the database itself).

Returns:

  • (Integer)


193
194
195
196
197
198
199
# File 'lib/store/digest/meta/lmdb.rb', line 193

def bytes
  lmdb.transaction? true do
    if ret = lmdb[:control]['bytes']
      db_decode ret, :bytes
    end
  end
end

#deletedInteger

Return the number of objects whose payloads are deleted but are still on record.

Returns:

  • (Integer)


182
183
184
185
186
187
188
# File 'lib/store/digest/meta/lmdb.rb', line 182

def deleted
  lmdb.transaction? true do
    if ret = lmdb[:control]['deleted']
      db_decode ret, :deleted
    end
  end
end

#list(type: nil, charset: nil, encoding: nil, language: nil, size: nil, ctime: nil, mtime: nil, ptime: nil, dtime: nil, sort: nil) ⇒ Object



226
227
228
229
230
231
232
233
234
235
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
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
# File 'lib/store/digest/meta/lmdb.rb', line 226

def list type: nil, charset: nil, encoding: nil, language: nil,
  size: nil, ctime: nil, mtime: nil, ptime: nil, dtime: nil, sort: nil
# coerce all the inputs
params = begin
           b  = binding
           ph = {}
           PARAMS.each do |key|
             val = b.local_variable_get key
             val = case val
                   when nil then []
                   when Time then [val]
                   when DateTime then [val.to_time]
                   when -> (v) { v.respond_to? :to_a } then val.to_a
                   else [val]
                   end
             ph[key] = val unless val.empty?
           end
           ph
         end
# find the smallest denominator
index = params.keys.map do |k|
  [k, lmdb[k].size]
end.sort { |a, b| a[1] <=> b[1] }.map(&:first).first
out = {}
lmdb.transaction? true do
  if index
    # warn params.inspect
    if INTS[index]
      index_get index, *params[index], range: true do |_, v|
        u = URI("ni:///#{primary};")
        u.digest = v
        out[u] ||= get u
      end
    else
      params[index].each do |val|
        index_get index, val do |_, v|
          u = URI("ni:///#{primary};")
          u.digest = v
          out[u] ||= get u
        end
      end
    end
    rest = params.keys - [index]
    unless rest.empty?
      out.select! do |_, obj|
        rest.map do |param|
          if val = obj.send(param)
            # warn "#{param} #{params[param]} <=> #{val}"
            if INTS[param]
              min, max = params[param]
              if min && max
                val >= min && val <= max
              elsif min
                val >= min
              elsif max
                val <= max
              end
            else
              params[param].include? val
            end
          else
            false
          end
        end.all?(true)
      end
    end
  else
    # if we aren't filtering at all we can just obtain everything
    lmdb[primary].cursor do |c|
      while rec = c.next
        u = URI("ni:///#{primary};")
        u.digest = rec.first
        out[u] ||= get u
      end
    end
  end
end

# now we sort
out.values
end

#lmdbLMDB::Environment

Return the LMDB handle for the given process.

Returns:

  • (LMDB::Environment)


130
131
132
# File 'lib/store/digest/meta/lmdb.rb', line 130

def lmdb
  (@lmdb ||= {})[Process.pid] ||= ::LMDB.new dir, @lmdb_opts
end

#objectsInteger

Return the number of objects in the database.

Returns:

  • (Integer)


171
172
173
174
175
176
177
# File 'lib/store/digest/meta/lmdb.rb', line 171

def objects
  lmdb.transaction? true do
    if ret = lmdb[:control]['objects']
      db_decode ret, :objects
    end
  end
end

#primarySymbol

Return the primary digest algorithm.

Returns:

  • (Symbol)

    the primary algorithm



161
162
163
164
165
166
167
# File 'lib/store/digest/meta/lmdb.rb', line 161

def primary
  @primary ||= lmdb.transaction? true do
    if ret = lmdb[:control]['primary']
      ret.strip.downcase.to_sym
    end
  end
end

#transaction(readonly: false, &block) ⇒ Object

Wrap the block in a transaction. Trying to start a read-write transaction (or do a write operation, as they are wrapped by transactions internally) within a read-only transaction will almost certainly break.

Parameters:

  • readonly (false, true) (defaults to: false)

    whether the transaction is read-only

  • block (Proc)

    the code to run.



142
143
144
145
146
147
# File 'lib/store/digest/meta/lmdb.rb', line 142

def transaction readonly: false, &block
  lmdb.transaction?(readonly) do
    # we do not want to transmit the transaction
    block.call
  end
end