Class: LargeObjectStore::RailsWrapper

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(store, serializer: Marshal, max_slice_size: MAX_OBJECT_SIZE) ⇒ RailsWrapper

Returns a new instance of RailsWrapper.



32
33
34
35
36
37
# File 'lib/large_object_store.rb', line 32

def initialize(store, serializer: Marshal, max_slice_size: MAX_OBJECT_SIZE)
  @store = store
  @serializer = serializer
  @max_slice_size = [max_slice_size, MAX_OBJECT_SIZE].min
  @namespace = (store.respond_to?(:options) && store.options[:namespace]) || ""
end

Instance Attribute Details

#storeObject (readonly)

Returns the value of attribute store.



30
31
32
# File 'lib/large_object_store.rb', line 30

def store
  @store
end

Instance Method Details

#delete(key) ⇒ Object



106
107
108
# File 'lib/large_object_store.rb', line 106

def delete(key)
  @store.delete(key(key, 0))
end

#exist?(key) ⇒ Boolean

Returns:

  • (Boolean)


102
103
104
# File 'lib/large_object_store.rb', line 102

def exist?(key)
  @store.exist?(key(key, 0))
end

#fetch(key, **options) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/large_object_store.rb', line 94

def fetch(key, **options)
  value = read(key)
  return value unless value.nil?
  value = yield
  write(key, value, **options)
  value
end

#read(key) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/large_object_store.rb', line 67

def read(key)
  # read pages
  pages, uuid = @store.read(key(key, 0))
  return if pages.nil?

  data = if pages.is_a?(Integer)
    # read sliced data
    keys = (1..pages).map { |i| key(key, i) }
    # use values_at to enforce key order because read_multi doesn't guarantee a return order
    slices = @store.read_multi(*keys, raw: true).values_at(*keys)
    return nil if slices.compact.size != pages

    slices = slices.map do |slice|
      s = slice.dup
      [s.slice!(0, UUID_SIZE), s]
    end

    return nil unless slices.map(&:first).uniq == [uuid]

    slices.map!(&:last).join("")
  else
    pages
  end

  deserialize(data)
end

#write(key, value, **options) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/large_object_store.rb', line 39

def write(key, value, **options)
  options = options.dup
  value = serialize(value, options)

  slice_size = safe_slice_size(key)
  # store number of pages
  pages = (value.size / slice_size.to_f).ceil

  if pages == 1
    !!@store.write(key(key, 0), value, **options)
  else
    # store meta
    uuid = SecureRandom.hex(UUID_BYTES)
    return false unless @store.write(key(key, 0), [pages, uuid], **options) # invalidates the old cache

    # store object
    page = 1
    loop do
      slice = value.slice!(0, slice_size)
      break if slice.size == 0

      return false unless @store.write(key(key, page), slice.prepend(uuid), raw: true, **options)
      page += 1
    end
    true
  end
end