Class: Commendo::RedisBacked::ContentSet
- Inherits:
-
Object
- Object
- Commendo::RedisBacked::ContentSet
- Defined in:
- lib/commendo/redis-backed/content_set.rb
Constant Summary collapse
- SET_TOO_LARGE_FOR_LUA =
999
Instance Attribute Summary collapse
-
#key_base ⇒ Object
Returns the value of attribute key_base.
-
#redis ⇒ Object
Returns the value of attribute redis.
-
#tag_set ⇒ Object
Returns the value of attribute tag_set.
Instance Method Summary collapse
- #add(resource, *groups) ⇒ Object
- #add_and_calculate(resource, *groups) ⇒ Object
- #add_by_group(group, *resources) ⇒ Object
- #add_single(resource, group, score) ⇒ Object
- #calculate_similarity(threshold = 0) ⇒ Object
- #calculate_similarity_for_resource(resource, threshold) ⇒ Object
- #delete(resource) ⇒ Object
- #filtered_similar_to(resource, options = {}) ⇒ Object
- #groups(resource) ⇒ Object
-
#initialize(key_base, tag_set = nil) ⇒ ContentSet
constructor
A new instance of ContentSet.
- #remove_from_groups(resource, *groups) ⇒ Object
- #remove_from_groups_and_calculate(resource, *groups) ⇒ Object
- #similar_to(resource, limit = 0) ⇒ Object
- #similarity_key(resource) ⇒ Object
Constructor Details
#initialize(key_base, tag_set = nil) ⇒ ContentSet
Returns a new instance of ContentSet.
8 9 10 11 12 |
# File 'lib/commendo/redis-backed/content_set.rb', line 8 def initialize(key_base, tag_set = nil) @redis = Redis.new(host: Commendo.config.host, port: Commendo.config.port, db: Commendo.config.database, timeout: 120) @key_base = key_base @tag_set = tag_set end |
Instance Attribute Details
#key_base ⇒ Object
Returns the value of attribute key_base.
6 7 8 |
# File 'lib/commendo/redis-backed/content_set.rb', line 6 def key_base @key_base end |
#redis ⇒ Object
Returns the value of attribute redis.
6 7 8 |
# File 'lib/commendo/redis-backed/content_set.rb', line 6 def redis @redis end |
#tag_set ⇒ Object
Returns the value of attribute tag_set.
6 7 8 |
# File 'lib/commendo/redis-backed/content_set.rb', line 6 def tag_set @tag_set end |
Instance Method Details
#add(resource, *groups) ⇒ Object
24 25 26 27 28 29 30 31 32 |
# File 'lib/commendo/redis-backed/content_set.rb', line 24 def add(resource, *groups) groups.each do |group| if group.kind_of?(Array) add_single(resource, group[0], group[1]) else add_single(resource, group, 1) end end end |
#add_and_calculate(resource, *groups) ⇒ Object
39 40 41 42 |
# File 'lib/commendo/redis-backed/content_set.rb', line 39 def add_and_calculate(resource, *groups) add(resource, *groups) calculate_similarity_for_resource(resource, 0) end |
#add_by_group(group, *resources) ⇒ Object
14 15 16 17 18 19 20 21 22 |
# File 'lib/commendo/redis-backed/content_set.rb', line 14 def add_by_group(group, *resources) resources.each do |resource| if resource.kind_of?(Array) add_single(resource[0], group, resource[1]) else add_single(resource, group, 1) end end end |
#add_single(resource, group, score) ⇒ Object
34 35 36 37 |
# File 'lib/commendo/redis-backed/content_set.rb', line 34 def add_single(resource, group, score) redis.zincrby(group_key(group), score, resource) redis.zincrby(resource_key(resource), score, group) end |
#calculate_similarity(threshold = 0) ⇒ Object
60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/commendo/redis-backed/content_set.rb', line 60 def calculate_similarity(threshold = 0) #TODO make this use scan for scaling keys = redis.keys("#{resource_key_base}:*") keys.each_with_index do |key, i| resource = key.gsub(/^#{resource_key_base}:/, '') similarity_key = similarity_key(resource) redis.del(similarity_key) yield(key, i, keys.length) if block_given? completed = redis.eval(similarity_lua, keys: [key], argv: [tmp_key_base, resource_key_base, similar_key_base, group_key_base, threshold]) if completed == SET_TOO_LARGE_FOR_LUA calculate_similarity_for_key_resource(key, resource, threshold) end end end |
#calculate_similarity_for_resource(resource, threshold) ⇒ Object
75 76 77 78 |
# File 'lib/commendo/redis-backed/content_set.rb', line 75 def calculate_similarity_for_resource(resource, threshold) key = resource_key(resource) calculate_similarity_for_key_resource(key, resource, threshold) end |
#delete(resource) ⇒ Object
48 49 50 51 52 53 54 55 56 |
# File 'lib/commendo/redis-backed/content_set.rb', line 48 def delete(resource) similar = similar_to(resource) similar.each do |other_resource| redis.zrem(similarity_key(other_resource[:resource]), "#{resource}") end #TODO delete from groups? redis.del(similarity_key(resource)) redis.del(resource_key(resource)) end |
#filtered_similar_to(resource, options = {}) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'lib/commendo/redis-backed/content_set.rb', line 98 def filtered_similar_to(resource, = {}) if @tag_set.nil? || ([:include].nil? && [:exclude].nil?) || @tag_set.empty? return similar_to(resource, [:limit] || 0) else similar = similar_to(resource) limit = [:limit] || similar.length filtered = [] similar.each do |s| return filtered if filtered.length >= limit filtered << s if @tag_set.matches(s[:resource], [:include], [:exclude]) end return filtered end end |
#groups(resource) ⇒ Object
44 45 46 |
# File 'lib/commendo/redis-backed/content_set.rb', line 44 def groups(resource) redis.zrange(resource_key(resource), 0, -1) end |
#remove_from_groups(resource, *groups) ⇒ Object
117 118 119 120 121 122 123 124 |
# File 'lib/commendo/redis-backed/content_set.rb', line 117 def remove_from_groups(resource, *groups) resource_key = resource_key(resource) redis.zrem(resource_key, groups) groups.each do |group| group_key = group_key(group) redis.zrem(group_key, resource) end end |
#remove_from_groups_and_calculate(resource, *groups) ⇒ Object
126 127 128 129 |
# File 'lib/commendo/redis-backed/content_set.rb', line 126 def remove_from_groups_and_calculate(resource, *groups) remove_from_groups(resource, *groups) calculate_similarity_for_resource(resource, 0) end |
#similar_to(resource, limit = 0) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/commendo/redis-backed/content_set.rb', line 80 def similar_to(resource, limit = 0) finish = limit -1 if resource.kind_of? Array keys = resource.map do |res| similarity_key(res) end tmp_key = "#{key_base}:tmp:#{SecureRandom.uuid}" redis.zunionstore(tmp_key, keys) similar_resources = redis.zrevrange(tmp_key, 0, finish, with_scores: true) redis.del(tmp_key) else similar_resources = redis.zrevrange(similarity_key(resource), 0, finish, with_scores: true) end similar_resources.map do |resource| {resource: resource[0], similarity: resource[1].to_f} end end |
#similarity_key(resource) ⇒ Object
113 114 115 |
# File 'lib/commendo/redis-backed/content_set.rb', line 113 def similarity_key(resource) "#{similar_key_base}:#{resource}" end |