Skip to content

Commit

Permalink
Attempting to simplify Memory store
Browse files Browse the repository at this point in the history
  • Loading branch information
mattruggio committed Sep 5, 2022
1 parent 53d46db commit 32d4cc6
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 63 deletions.
3 changes: 3 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,6 @@ RSpec/ExampleLength:

Metrics/ClassLength:
Max: 150

Layout/LineLength:
Max: 125
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

#### 0.0.1 - TBD
#### 0.0.2 - Monday, Sept. 5th, 2022

* Initial proof-of-concept release.
12 changes: 10 additions & 2 deletions lib/teton/key.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative 'key_pointer'

module Teton
# Understands a fully-qualified path to a resource or resources.
class Key
Expand All @@ -22,8 +24,10 @@ def to_s(suffix_keys = [])
(parts + suffix_keys).join(separator)
end

def traverse(&block)
parts.each_with_index(&block)
def traverse
parts.each_with_index do |_part, index|
yield KeyPointer.new(self, index)
end
end

def entry?
Expand All @@ -33,5 +37,9 @@ def entry?
def resource?
parts.length.odd?
end

def last_part
parts.last
end
end
end
35 changes: 35 additions & 0 deletions lib/teton/key_pointer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

module Teton
# Points to a section within a key's parts. A section can either be a resource or an entry.
class KeyPointer
attr_reader :key, :index

def initialize(key, index)
@key = key
@index = index.to_i

freeze
end

def value
key.parts[index]
end

def not_last?
!last?
end

def last?
index == key.parts.length - 1
end

def entry?
index.odd?
end

def resource?
index.even? || index.zero?
end
end
end
105 changes: 46 additions & 59 deletions lib/teton/stores/memory.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,80 +20,45 @@ def initialize(store = {})
# Main Object API

def set(key, data)
pointer = store

key.traverse do |part, index|
if index < key.parts.length - 1
pointer = insert_traverse(index, pointer, part)
else
# last id
upsert(pointer, part, data)
end
end
store_pointer = insert_traverse_to_last(key)

upsert(store_pointer, key.last_part, data)

self
end

def get(key)
pointer = store

key.traverse do |part, index|
break unless pointer

pointer =
if index < key.parts.length - 1
# not last part
traverse(index, pointer, part)
elsif key.resource?
# last part
entries(key, pointer, part)
else
# id
entry(key, pointer, part)
end
end
store_pointer = traverse_to_last(key)

pointer
return unless store_pointer

if key.resource?
entries(key, store_pointer, key.last_part)
else
entry(key, store_pointer, key.last_part)
end
end

def del(key)
pointer = store

key.traverse do |part, index|
break unless pointer

if index < key.parts.length - 1
# not last part
pointer = traverse(index, pointer, part)
else
# last part
pointer.delete(part)
end
end
store_pointer = traverse_to_last(key)

return self unless store_pointer

store_pointer.delete(key.last_part)

self
end

def count(key)
count = 0
pointer = store

key.traverse do |part, index|
break unless pointer

if index < key.parts.length - 1
# not last part
pointer = traverse(index, pointer, part)
elsif key.resource?
# last part
count = (pointer.dig(part, IDS_KEY) || {}).keys.length
else
# id
count = pointer.dig(part, DATA_KEY) ? 1 : 0
end
end
store_pointer = traverse_to_last(key)

return 0 unless store_pointer

count
if key.resource?
(store_pointer.dig(key.last_part, IDS_KEY) || {}).keys.length
else
store_pointer.dig(key.last_part, DATA_KEY) ? 1 : 0
end
end

# Persistence API
Expand Down Expand Up @@ -157,6 +122,28 @@ def traverse(index, pointer, part)
end
end

def insert_traverse_to_last(key)
store_pointer = store

key.traverse do |key_pointer|
store_pointer = insert_traverse(key_pointer.index, store_pointer, key_pointer.value) if key_pointer.not_last?
end

store_pointer
end

def traverse_to_last(key)
store_pointer = store

key.traverse do |key_pointer|
break unless store_pointer

store_pointer = traverse(key_pointer.index, store_pointer, key_pointer.value) if key_pointer.not_last?
end

store_pointer
end

def entry(key, pointer, part)
data = pointer.dig(part, DATA_KEY)
meta = pointer.dig(part, META_KEY)
Expand Down
2 changes: 1 addition & 1 deletion lib/teton/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module Teton
VERSION = '0.0.1'
VERSION = '0.0.2'
end

0 comments on commit 32d4cc6

Please sign in to comment.