Skip to content

Commit

Permalink
Merge branch 'master' into index-slots
Browse files Browse the repository at this point in the history
  • Loading branch information
Oleg Andreev committed May 24, 2008
2 parents 2c3a8d3 + 70bd2f5 commit 605728f
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 1 deletion.
51 changes: 50 additions & 1 deletion lib/strokedb/data_structures/simple_skiplist.rb
Expand Up @@ -144,7 +144,7 @@ def first_key
return first ? first[1] : nil
end

# Insert a key-value pair. If key already exists,
# Insert a key-value pair. If the key already exists,
# value will be overwritten.
#
# <i> is a new node
Expand Down Expand Up @@ -179,6 +179,36 @@ def insert(key, value, __level = nil)
self
end

# Remove a key-value pair. If the key does not exist,
# no action is performed.
#
# <d> is a node to be removed
# <M> is a marked node in a update_list
# <N> is next node to <M> which reference must be updated.
#
# M-----------------> d <---------------- N ...
# o ------> M ------> d <------ N ...
# o -> o -> o -> M -> d <- N ....
#
def delete(key)
@mutex.synchronize do
x = anchor
level = node_level(x)
update = Array.new(level)
x = find_with_update(x, level, key, update)

# remove existing key
if node_compare(x, key) == 0
level = node_level(x)
while level > 0
level -= 1
node_delete_after!(x, update[level], level)
end
end
end
self
end

def find_with_update(x, level, key, update) #:nodoc:
while level > 0
level -= 1
Expand Down Expand Up @@ -421,6 +451,25 @@ def node_insert_after!(x, prev, level)
netx[3][level] = x
end

# before:
# prev -> x -> next
# prev <- x -> next
#
# after:
#
# prev -> next
# prev <- next
#
def node_delete_after!(x, prev, level)
netx = node_next(x, level) # 'next' is a reserved word in ruby

# forward links
prev[0][level] = netx

# backward links
netx[3][level] = prev
end

def new_node(level, key, value)
[
[nil]*level,
Expand Down
19 changes: 19 additions & 0 deletions spec/lib/strokedb/data_structures/simple_skiplist_spec.rb
Expand Up @@ -98,6 +98,25 @@
end


describe "Deleting from skiplist" do
before(:each) do
@list = SimpleSkiplist.new
@list.insert "1a", "a"
@list.insert "1b", "b"
@list.insert "1c", "c"
@list.insert "1d", "d"
end
it "should store nil" do
@list.insert("1b", nil)
@list.search("1", "1", 3, 0, false, false).should == ["a", nil, "c"]
end
it "should delete item" do
@list.delete("1b")
@list.search("1", "1", 3, 0, false, false).should == ["a", "c", "d"]
end
end


describe "Big skiplist [#{lang}]" do
before(:each) do
@maxlevel = 8
Expand Down

0 comments on commit 605728f

Please sign in to comment.