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.



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

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.



28
29
30
# File 'lib/large_object_store.rb', line 28

def store
  @store
end

Instance Method Details

#delete(key) ⇒ Object



104
105
106
# File 'lib/large_object_store.rb', line 104

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

#exist?(key) ⇒ Boolean

Returns:



100
101
102
# File 'lib/large_object_store.rb', line 100

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

#fetch(key, **options) ⇒ Object



92
93
94
95
96
97
98
# File 'lib/large_object_store.rb', line 92

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

#read(key) ⇒ Object



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

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).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



37
38
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
# File 'lib/large_object_store.rb', line 37

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