Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add SortedArray

  • Loading branch information...
commit 95ec3fb66e9730833d32ca9ed353cf6cb2c7281a 1 parent d072e86
@seki authored
Showing with 92 additions and 52 deletions.
  1. +92 −52 lib/drip.rb
View
144 lib/drip.rb
@@ -403,54 +403,72 @@ def upper_boundary(ary, key)
end
class Drip
- class ImmutableDrip
+ class SortedArray
include Drip::ArrayBsearch
- class Generator
- def initialize(pool=[], tag=[])
- @pool = pool
- @tag = tag
- @shared = Hash.new {|h, k| h[k] = k; k}
- @tag.each {|pair| @shared[pair[0]]}
- end
- attr_reader :pool, :tag
+ def initialize(ary)
+ @ary = ary
+ end
- def add(key, value, *tag)
- @pool << [key, value]
- idx = @pool.size - 1
- tag.uniq.each do |t|
- @tag << [[@shared[t], key]]
- end
- end
-
- def generate
- tag = @tag.sort
- tag.inject(nil) do |last, kv|
- k = kv[0]
- k[0] = last if k[0] == last
- k[0]
- end
- ImmutableDrip.new(@pool.sort, tag)
- end
+ def fetch(key)
+ idx = lower_boundary(@ary, key)
+ k, v = @ary[idx]
+ k == key ? v.to_a : nil
+ end
+
+ def read(key, n=1)
+ idx = lower_boundary(@ary, key + 1)
+ return [] unless idx
+ @ary[idx, n].collect {|kv|
+ [kv[0], *kv[1].to_a]
+ }
+ end
+
+ def empty?
+ @ary.empty?
+ end
+
+ def latest?(key)
+ return false if @ary.empty?
+ return @ary[-1][0] == key
+ end
+
+ def head(n)
+ n = @ary.size < n ? @ary.size : n
+ @ary[-n, n].collect {|kv|
+ [kv[0], *kv[1].to_a]
+ }
+ end
+
+ def older(key)
+ return nil if @ary.empty?
+ key = @ary[-1][0] + 1 unless key
+ idx = upper_boundary(@ary, key - 1)
+ k, v = @ary[idx - 1]
+ k && k < key ? [k, *v.to_a] : nil
+ end
+
+ def last
+ @ary[-1]
end
+ end
+end
+
+class Drip
+ class ImmutableDrip
+ include Drip::ArrayBsearch
def initialize(pool=[], tag=[])
- @pool = pool
+ @pool = Drip::SortedArray.new(pool)
@tag = tag
end
def fetch(key)
- idx = lower_boundary(@pool, key)
- k, v = @pool[idx]
- k == key ? v.to_a : nil
+ @pool.fetch(key)
end
def read(key, n=1)
- idx = lower_boundary(@pool, key + 1)
- return [] unless idx
- @pool[idx, n].collect {|kv|
- [kv[0], *kv[1].to_a]
- }
+ @pool.read(key, n)
end
def read_tag(key, tag, n=1)
@@ -463,13 +481,11 @@ def read_tag(key, tag, n=1)
def latest?(key, tag)
return false if @pool.empty?
- if tag
- lower = lower_boundary(@tag, [tag, key])
- upper = upper_boundary(@tag, [tag, INF])
- return lower == upper - 1
- else
- return @pool[-1][0] == key
- end
+ return @pool.latest?(key) unless tag
+
+ lower = lower_boundary(@tag, [tag, key])
+ upper = upper_boundary(@tag, [tag, INF])
+ return lower == upper - 1
end
def head_tag(n, tag)
@@ -482,11 +498,7 @@ def head_tag(n, tag)
end
def head(n=1, tag=nil)
- return head_tag(n, tag) if tag
- n = @pool.size < n ? @pool.size : n
- @pool[-n, n].collect {|kv|
- [kv[0], *kv[1].to_a]
- }
+ tag ? head_tag(n, tag) : @pool.head(n)
end
def older_tag(key, tag)
@@ -497,21 +509,49 @@ def older_tag(key, tag)
def older(key, tag=nil)
return nil if @pool.empty?
- key = @pool[-1][0] + 1 unless key
+ key = @pool.last[0] + 1 unless key
return older_tag(key, tag) if tag
- idx = upper_boundary(@pool, key - 1)
- k, v = @pool[idx - 1]
- k && k < key ? [k, *v.to_a] : nil
+ @pool.older(key)
end
def newer(key, tag=nil)
return read(key, 1)[0] unless tag
read_tag(key, tag, 1)[0]
end
-
end
end
+class Drip
+ class ImmutableDrip
+ class Generator
+ def initialize(pool=[], tag=[])
+ @pool = pool
+ @tag = tag
+ @shared = Hash.new {|h, k| h[k] = k; k}
+ @tag.each {|pair| @shared[pair[0]]}
+ end
+ attr_reader :pool, :tag
+
+ def add(key, value, *tag)
+ @pool << [key, value]
+ idx = @pool.size - 1
+ tag.uniq.each do |t|
+ @tag << [[@shared[t], key]]
+ end
+ end
+
+ def generate
+ tag = @tag.sort
+ tag.inject(nil) do |last, kv|
+ k = kv[0]
+ k[0] = last if k[0] == last
+ k[0]
+ end
+ ImmutableDrip.new(@pool.sort, tag)
+ end
+ end
+ end
+end
if __FILE__ == $0
require 'my_drip'
Please sign in to comment.
Something went wrong with that request. Please try again.