Skip to content
This repository
tag: v3.1.13
Fetching contributors…

Cannot retrieve contributors at this time

file 97 lines (82 sloc) 2.807 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 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 64 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 91 92 93 94 95 96 97
module Picky

  module Backends

    #
    #
    class Redis < Backend

      attr_reader :client

      def initialize options = {}
        @client = options[:client] || ::Redis.new(:db => (options[:db] || 15))
      end

      # Returns an object that on #initial, #load returns an object that responds to:
      # [:token] # => [id, id, id, id, id] (an array of ids)
      #
      def create_inverted bundle
        List.new client, "#{bundle.identifier}:inverted"
      end
      # Returns an object that on #initial, #load returns an object that responds to:
      # [:token] # => 1.23 (a weight)
      #
      def create_weights bundle
        Float.new client, "#{bundle.identifier}:weights"
      end
      # Returns an object that on #initial, #load returns an object that responds to:
      # [:encoded] # => [:original, :original] (an array of original symbols this similarity encoded thing maps to)
      #
      def create_similarity bundle
        List.new client, "#{bundle.identifier}:similarity"
      end
      # Returns an object that on #initial, #load returns an object that responds to:
      # [:key] # => value (a value for this config key)
      #
      def create_configuration bundle
        String.new client, "#{bundle.identifier}:configuration"
      end

      # Returns the result ids for the allocation.
      #
      # Developers wanting to program fast intersection
      # routines, can do so analogue to this in their own
      # backend implementations.
      #
      # Note: We use the amount and offset hints to speed Redis up.
      #
      def ids combinations, amount, offset
        identifiers = combinations.inject([]) do |identifiers, combination|
          identifiers << "#{combination.identifier}"
        end

        result_id = generate_intermediate_result_id

        # Intersect and store.
        #
        client.zinterstore result_id, identifiers

        # Get the stored result.
        #
        results = client.zrange result_id, offset, (offset + amount)

        # Delete the stored result as it was only for temporary purposes.
        #
        # Note: I could also not delete it, but that would not be clean at all.
        #
        client.del result_id

        results
      end

      # Generate a multiple host/process safe result id.
      #
      # Note: Generated when this class loads.
      #
      require 'socket'
      def self.extract_host
        @host ||= Socket.gethostname
      end
      def host
        self.class.extract_host
      end
      extract_host
      def pid
        @pid ||= Process.pid
      end
      # Use the host and pid (generated lazily in child processes) for the result.
      #
      def generate_intermediate_result_id
        :"#{host}:#{pid}:picky:result"
      end

    end

  end

end
Something went wrong with that request. Please try again.