Skip to content

Commit

Permalink
head_tag
Browse files Browse the repository at this point in the history
  • Loading branch information
seki committed Sep 13, 2011
1 parent 2b3ffd7 commit 9aaaf8b
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 9 deletions.
33 changes: 31 additions & 2 deletions lib/drip.rb
Expand Up @@ -8,6 +8,26 @@ class Drip
def inspect; to_s; end def inspect; to_s; end


class ImmutableDrip class ImmutableDrip
class Generator
def initialize(pool=[], tag=[])
@pool = pool
@tag = tag
end

def add(key, value, *tag)
@pool << [key, value]
tag.uniq.each do |t|
@tag << [[t, key], value]
end
end

def generate
ImmutableDrip.new(@pool.sort, @tag.sort)
end
end

INF = 1.0/0

def initialize(pool=[], tag=[]) def initialize(pool=[], tag=[])
@pool = pool @pool = pool
@tag = tag @tag = tag
Expand Down Expand Up @@ -35,6 +55,15 @@ def read_tag(key, tag, n=1)
} }
end end


def head_tag(n, tag)
lower = lower_boundary(@tag, [tag, 0])
upper = upper_boundary(@tag, [tag, INF])
lower = [lower, upper - n].max
@tag[lower ... upper].collect {|kv|
[kv[0][1], *kv[1].to_a]
}
end

def head(n=1, tag=nil) def head(n=1, tag=nil)
return head_tag(n, tag) if tag return head_tag(n, tag) if tag
n = @pool.size < n ? @pool.size : n n = @pool.size < n ? @pool.size : n
Expand All @@ -61,7 +90,7 @@ def lower_boundary(ary, key)
upper = ary.size upper = ary.size
while lower + 1 != upper while lower + 1 != upper
mid = (lower + upper).div(2) mid = (lower + upper).div(2)
if key > ary[mid][0] if (ary[mid][0] <=> key) < 0
lower = mid lower = mid
else else
upper = mid upper = mid
Expand All @@ -75,7 +104,7 @@ def upper_boundary(ary, key)
upper = ary.size upper = ary.size
while lower + 1 != upper while lower + 1 != upper
mid = (lower + upper).div(2) mid = (lower + upper).div(2)
if key >= ary[mid][0] if (ary[mid][0] <=> key) <= 0
lower = mid lower = mid
else else
upper = mid upper = mid
Expand Down
32 changes: 25 additions & 7 deletions test/basic.rb
Expand Up @@ -201,14 +201,19 @@ def test_bsearch
assert_equal(8, im.upper_boundary(ary, 'g')) assert_equal(8, im.upper_boundary(ary, 'g'))
end end


def add_to_gen(gen, key, value, *tag)
gen.add(key, [value, *tag], *tag)
end

def test_fetch_and_read_wo_tag def test_fetch_and_read_wo_tag
ary = [] gen = Drip::ImmutableDrip::Generator.new
ary << [21, ['a']] add_to_gen(gen, 21, 'a')
ary << [39, ['b']] add_to_gen(gen, 99, 'd', 'tag')
ary << [60, ['c', 'tag']] add_to_gen(gen, 39, 'b')
ary << [99, ['d', 'tag']] add_to_gen(gen, 60, 'c', 'tag')


im = Drip::ImmutableDrip.new(ary, []) im = gen.generate

assert_equal(nil, im.fetch(20)) assert_equal(nil, im.fetch(20))
assert_equal(['a'], im.fetch(21)) assert_equal(['a'], im.fetch(21))
assert_equal(nil, im.fetch(23)) assert_equal(nil, im.fetch(23))
Expand Down Expand Up @@ -242,4 +247,17 @@ def test_fetch_and_read_wo_tag
assert_equal([99, 'd', 'tag'], im.newer(60)) assert_equal([99, 'd', 'tag'], im.newer(60))
assert_equal(nil, im.newer(99)) assert_equal(nil, im.newer(99))
end end

def test_read_w_tag
gen = Drip::ImmutableDrip::Generator.new
add_to_gen(gen, 21, 'a')
add_to_gen(gen, 39, 'b', 'b', 'tag')
add_to_gen(gen, 60, 'c', 'c', 'tag')
add_to_gen(gen, 99, 'd', 'tag', 'd')
add_to_gen(gen, 159, 'e', 'tag2', 'e')
im = gen.generate

assert_equal([[99, 'd', 'tag', 'd']], im.head(1, 'tag'))
assert_equal([[99, 'd', 'tag', 'd']], im.head(1, 'd'))
end
end end

0 comments on commit 9aaaf8b

Please sign in to comment.