Permalink
Browse files

Really simple append-only lists.

  • Loading branch information...
1 parent efc1295 commit bfd5b47fa82f7a18d8ea50390e7640d73a4a163b @therealadam committed Aug 29, 2011
Showing with 86 additions and 7 deletions.
  1. +0 −1 Gemfile
  2. +1 −5 README.md
  3. +1 −0 lib/sexyback.rb
  4. +45 −0 lib/sexyback/list.rb
  5. +1 −1 sexyback.gemspec
  6. +34 −0 spec/sexyback/list_spec.rb
  7. +4 −0 spec/spec_helper.rb
View
@@ -1,6 +1,5 @@
source "http://rubygems.org"
-# Specify your gem's dependencies in sexyback.gemspec
gemspec
group :dependency do
View
@@ -51,15 +51,11 @@ Atomic types:
- Hash
- Set
+- Sorted Set (TODO)
- Append-only list (TODO)
- Lock (TODO)
- Scoreboard (TODO)
-Non-atomic, but still awesome:
-
-- Sorted set (TODO)
-- Single-entry list (TODO)
-
TODO: copy everything from redback
TODO: Redis duck-type compatible driver-esque object
View
@@ -6,6 +6,7 @@ module Sexyback
autoload :Connection, 'sexyback/connection'
autoload :Hash, 'sexyback/hash'
+ autoload :List, 'sexyback/list'
autoload :Set, 'sexyback/set'
end
View
@@ -0,0 +1,45 @@
+class Sexyback::List
+ include Sexyback::Connection
+
+ attr_accessor :cf, :key
+
+ def initialize(cf, key)
+ @cf = cf
+ @key = key
+ end
+
+ def add(obj)
+ connection.insert(cf, key, addition_for(obj))
+ end
+
+ def delete(obj)
+ connection.insert(cf, key, removal_for(obj))
+ end
+
+ def to_a
+ connection.get(cf, key).inject([]) do |ary, (timestamp, entry)|
+ case entry
+ when /^\+/
+ ary << entry.slice(1..-1)
+ when /^-/
+ ary.delete(entry.slice(1..-1))
+ end
+ ary
+ end
+ end
+
+ def addition_for(obj)
+ {timestamp => "+" + obj}
+ end
+
+ def removal_for(obj)
+ {timestamp => "-" + obj}
+ end
+
+ def timestamp
+ t = Time.now.utc
+ t.tv_sec * 10_000_000 + t.tv_usec
+ end
+
+end
+
View
@@ -20,5 +20,5 @@ Gem::Specification.new do |s|
s.require_paths = ["lib"]
s.add_dependency 'activesupport', '~> 3.0.0'
- s.add_dependency 'cassandra', '~> 0.10.0'
+ s.add_dependency 'cassandra', '~> 0.12.1'
end
View
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe Sexyback::List do
+
+ before { Sexyback::List.connection = Cassandra::Mock.new('Sexyback', schema) }
+ subject { Sexyback::List.new(:List, 'the_roots') }
+ let(:the_roots) { %w{ahmir tariq kamal james kirk frank damon owen} }
+
+ describe "#add" do
+
+ it "records an entry for the added object" do
+ the_roots.each { |m| subject.add(m) }
+ subject.to_a.should eq(the_roots)
+ end
+
+ end
+
+ describe "#delete" do
+
+ it "records an entry for the removed object" do
+ the_roots.each { |m| subject.add(m) }
+ subject.delete("owen") # Sorry, Owen
+
+ subject.to_a.should_not include("owen")
+ end
+
+ end
+
+ describe "#include?"
+
+ describe "#compact"
+
+end
+
View
@@ -13,6 +13,10 @@ def schema
'Set' => {
'comparator_type' => 'org.apache.cassandra.db.marshal.UTF8Type',
'column_type' => 'Standard'
+ },
+ 'List' => {
+ 'comparator_type' => 'org.apache.cassandra.db.marshal.UTF8Type',
+ 'column_type' => 'Standard'
}
}
}

0 comments on commit bfd5b47

Please sign in to comment.