Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit f7a34ed

Browse files
Compactor workshop viable impl (#13)
* add base compactor * fix deletion for multiple segments * ahead * finish compactor
1 parent 9fa9be6 commit f7a34ed

File tree

7 files changed

+116
-12
lines changed

7 files changed

+116
-12
lines changed

‎lib/amnesia.rb‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
require_relative 'amnesia/cli'
2+
require_relative 'amnesia/compactor'
23

34
dir = './_data'
45

56
segment_files = Dir.each_child(dir).map { |f| "#{dir}/#{f}" }.sort_by { |f| File::Stat.new(f).mtime }
67

8+
# Amnesia::Compactor.call(*segment_files.take(2))
9+
710
Amnesia::CLI.new(segment_files, populate_index: true).start

‎lib/amnesia/cli.rb‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ def initialize(segment_files, populate_index: nil)
1919
end
2020

2121
def start
22+
segment_handler.compact
23+
2224
puts "Welcome to AmnesiaDB - Version 0.1.0\n\n"
2325

2426
loop do

‎lib/amnesia/compactor.rb‎

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
module Amnesia
2+
class Compactor
3+
def self.call(sstable1, sstable2)
4+
# todos itens de sstable1 e sstable2
5+
sstable_items1 = sstable1.all
6+
sstable_items2 = sstable2.all
7+
8+
pp sstable_items1
9+
pp sstable_items2
10+
11+
puts ''
12+
13+
# ponteiro 1, ponteiro 2 -> 0
14+
p1 = p2 = 0
15+
16+
result = []
17+
18+
# loop ate que eu termine os registros de ambos os arquivos
19+
loop do
20+
item1 = sstable_items1[p1] # item é uma tupla ['name', 'mateus']
21+
item2 = sstable_items2[p2]
22+
23+
break if item1.nil? && item2.nil?
24+
25+
# TODO: o que acontece se uma das keys for nil ?
26+
key1 = item1[0] unless item1.nil?
27+
key2 = item2[0] unless item2.nil?
28+
29+
min_key = [key1, key2].compact.min
30+
31+
if key1 == key2
32+
p1 += 1
33+
p2 += 1
34+
35+
result << item1
36+
37+
next
38+
end
39+
40+
if min_key == key1
41+
p1 += 1
42+
43+
result << item1
44+
else
45+
p2 += 1
46+
47+
result << item2
48+
end
49+
end
50+
51+
pp result
52+
53+
result.reject { |(_key, value)| value.nil? || value.empty? }
54+
end
55+
end
56+
end

‎lib/amnesia/memtable_handler.rb‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module Amnesia
22
class MemtableHandler
3-
def initialize(segment_handler, max_items_threshold = 5)
3+
def initialize(segment_handler, max_items_threshold = 2)
44
@segment_handler = segment_handler
55
@max_items_threshold = max_items_threshold
66

‎lib/amnesia/segment.rb‎

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ module Amnesia
22
class Segment
33
attr_reader :index_structure
44

5-
def initialize(filename, index_structure: Amnesia::Indexes::HashIndex.new)
5+
def initialize(filename, items: nil,index_structure: Amnesia::Indexes::HashIndex.new)
66
@filename = filename
7-
@storage = Amnesia::Storage.new(filename)
7+
@storage = Amnesia::Storage.new(filename,items: items)
88
@storage.create_db_file unless @storage.file_exists?
99
@index_structure = index_structure
1010
end
@@ -13,6 +13,14 @@ def name
1313
@filename
1414
end
1515

16+
def destroy
17+
File.delete(@filename)
18+
end
19+
20+
def all
21+
@storage.all
22+
end
23+
1624
def retrieve(key)
1725
index_entry = @index_structure.get(key)
1826

‎lib/amnesia/segment_handler.rb‎

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,28 @@ def current_segment
99
@segments.first
1010
end
1111

12+
def segments
13+
@segments ||= []
14+
end
15+
16+
def compact
17+
segments_to_compact = segments[-2..]
18+
19+
return if segments_to_compact.nil?
20+
21+
pp segments_to_compact
22+
23+
filename = "./_data/#{Time.now.to_i}.c.segment"
24+
25+
compaction_result = Amnesia::Compactor.call(*segments_to_compact)
26+
27+
new_segment = Amnesia::Segment.new(filename, items: compaction_result)
28+
29+
@segments.unshift(new_segment)
30+
31+
segments.pop(2).each(&:destroy)
32+
end
33+
1234
def flush(items)
1335
# TODO: Use the storage class for that
1436
filename = "./_data/#{Time.now.to_i}.segment"
@@ -17,7 +39,9 @@ def flush(items)
1739
items.each { |(key, value)| f.write("#{key},#{value}\n") }
1840
end
1941

20-
@segments << Amnesia::Segment.new(filename)
42+
@segments.unshift(Amnesia::Segment.new(filename))
43+
44+
compact if @segments.length == 2
2145

2246
:finished_flushing
2347
end

‎lib/amnesia/storage.rb‎

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ module Amnesia
22
class Storage
33
attr_reader :filename
44

5-
def initialize(filename)
5+
def initialize(filename,items: nil)
66
@filename = filename
7+
populate_data(items) unless items.nil? || items.empty?
78
end
89

910
def size
@@ -16,6 +17,14 @@ def set(key, value)
1617
File.write(filename, entry, mode: 'a+')
1718
end
1819

20+
def all
21+
File.readlines(filename).map do |record|
22+
key, value = record.chomp.split(',')
23+
24+
[key, value]
25+
end
26+
end
27+
1928
def delete(key)
2029
set(key, '')
2130
end
@@ -27,19 +36,15 @@ def get(key, index_entry: nil)
2736
end
2837

2938
def parse_record(raw_record)
30-
value = raw_record_value(raw_record)
31-
32-
return nil if value.nil? || value.empty?
33-
34-
value
39+
raw_record_value(raw_record)
3540
end
3641

3742
def raw_record_value(raw_record)
3843
(raw_record || '').chomp.split(',', 2)[1]
3944
end
4045

41-
def create_db_file
42-
File.write(filename, '') unless file_exists?
46+
def create_db_file(content='')
47+
File.write(filename, content) unless file_exists?
4348
end
4449

4550
def file_exists?
@@ -48,6 +53,12 @@ def file_exists?
4853

4954
private
5055

56+
def populate_data(items)
57+
data_block = items.map { |(key, value)| "#{key},#{value}\n" }.join('')
58+
59+
create_db_file(data_block)
60+
end
61+
5162
def record_from_scan(key)
5263
lines = File.readlines(filename)
5364

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /