Class: CorrectHorseBatteryStaple::Backend::Redis::DRange

Inherits:
Object
  • Object
show all
Includes:
Memoize
Defined in:
lib/correct_horse_battery_staple/backend/redis/d_range.rb

Overview

Represents a list of items corresponding to a square area of items formed by a range on axis 1 and a range on axis 2 of numbers associated with an item. In other words, this composes two different data about an item into a single score in a Redis sorted set, and allow that area to be treated as a single logical ordered list of items.

This is used to construct a single score out of a word’s length and percentile ranking. The length is the “outer” score and ranges (generally) from 3..18 or thereabouts in integral steps. Percentiles exist as fractional parts of the score added to the base word length. So, to address the items in a sorted set with the word length from 5..8 and percentile range 20..30, you would (in the Writer::Redis class) generate a Sorted set in which every word has a score with an integer and fractional part. The word “the” which appeared in the 95th percentile would have a score of 3.95.

Once defined, this class allows the following operations:

  • counting the total # of items in the 2d bounding box

  • picking the nth item from the (virtual) sorted list

Instance Method Summary collapse

Methods included from Memoize

included

Constructor Details

#initialize(db, key, outer, inner, divisor = 100) ⇒ DRange

Returns a new instance of DRange.



29
30
31
32
33
34
35
36
# File 'lib/correct_horse_battery_staple/backend/redis/d_range.rb', line 29

def initialize(db, key, outer, inner, divisor=100)
  @db = db
  @key = key
  @outer = outer
  @inner = inner
  @divisor = divisor
  @counts = {}
end

Instance Method Details

#countObject



45
46
47
48
# File 'lib/correct_horse_battery_staple/backend/redis/d_range.rb', line 45

def count
  precache_counts
  @counts.values.reduce(:+)
end

#dumpObject



38
39
40
41
42
43
# File 'lib/correct_horse_battery_staple/backend/redis/d_range.rb', line 38

def dump
  iterate_ranges do |min, max|
    cnt = @db.zcount(@key, min, max)
    [min, max, cnt]
  end
end

#pick_nth(n) ⇒ Object



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/correct_horse_battery_staple/backend/redis/d_range.rb', line 51

def pick_nth(n)
  precache_counts
  return nil if n > count-1

  pos = 0
  @outer.each do |base|
    cib = count_in_base(base)
    minpos = pos
    maxpos = pos + cib
    if cib > 0 && n >= minpos && n <= maxpos
      (min, max) = minmax_for_base(base)
      return @db.zrangebyscore(@key, min, max,
                               :limit => [n-pos, 1])[0]
    end
    pos += cib
  end
  return nil
end