Sha256: f756b943aafa4ed5fadb3cb151768c4e507dcab15ae14d3a7eb2dc85981c992e

Contents?: true

Size: 1.36 KB

Versions: 1

Compression:

Stored size: 1.36 KB

Contents

require "large_object_store/version"

module LargeObjectStore

  def self.wrap(store)
    RailsWrapper.new(store)
  end

  class RailsWrapper
    attr_reader :store

    LIMIT = 1024**2 - 100

    def initialize(store)
      @store = store
    end

    def write(key, value, options = {})
      value = Marshal.dump(value)
      
      # store number of pages
      pages = (value.size / LIMIT.to_f).ceil

      if pages == 1
        @store.write("#{key}_0", value, options)
      else
        @store.write("#{key}_0", pages, options)

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

          @store.write("#{key}_#{page}", slice, options)
          page += 1
        end
      end
      true
    end

    def read(key)
      # read pages
      pages = @store.read("#{key}_0")
      return if pages.nil?

      data = if pages.is_a?(String)
        pages
      else
        # read sliced data
        keys = Array.new(pages).each_with_index.map{|_,i| "#{key}_#{i+1}" }
        slices = @store.read_multi(*keys).values
        return nil if slices.compact.size < pages
        slices.join("")
      end
      Marshal.load(data)
    end

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

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
large_object_store-1.0.0 lib/large_object_store.rb