rubcask 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile.lock +2 -2
- data/lib/rubcask/data_file.rb +56 -22
- data/lib/rubcask/directory.rb +13 -16
- data/lib/rubcask/hinted_file.rb +1 -1
- data/lib/rubcask/server/abstract_server.rb +2 -0
- data/lib/rubcask/server/runner.rb +2 -1
- data/lib/rubcask/server/threaded.rb +0 -1
- data/lib/rubcask/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0568bcb47da50a78d9679c88b735cb5b2c259efb00297bb87f749463520cb371'
|
4
|
+
data.tar.gz: 210aaa3e1dd5eb5b0dd26a105f3151717661ff92f24ff54ded3077306b07b838
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f52adc24589f583eb1e777c5fe42c1c672e9b2c39e6cd2da5ca75f9be61d7c208a90d146a43adee28978c6217e3557e3b2c89a4290051f10fc2bf92290ab3d6c
|
7
|
+
data.tar.gz: 626f339669b988a5f844b90285e92985122a08d6144d22bd1a311411ca298876656ef375b13e4230da1c49edb00120191d53d046358fef107e13b34ab1634812
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rubcask (0.
|
4
|
+
rubcask (0.2.0)
|
5
5
|
concurrent-ruby (~> 1.1)
|
6
6
|
|
7
7
|
GEM
|
@@ -9,7 +9,7 @@ GEM
|
|
9
9
|
specs:
|
10
10
|
ast (2.4.2)
|
11
11
|
benchmark-ips (2.10.0)
|
12
|
-
concurrent-ruby (1.
|
12
|
+
concurrent-ruby (1.2.0)
|
13
13
|
docile (1.4.0)
|
14
14
|
json (2.6.3)
|
15
15
|
json (2.6.3-java)
|
data/lib/rubcask/data_file.rb
CHANGED
@@ -22,18 +22,35 @@ module Rubcask
|
|
22
22
|
@write_pos = file_size
|
23
23
|
end
|
24
24
|
|
25
|
+
# @!macro [new] might_change_pos
|
26
|
+
# @note Calling this method might change `pos` of the `file`
|
27
|
+
|
28
|
+
# @!macro [new] no_change_pos
|
29
|
+
# @note Calling this method will not change `pos` of the `file`
|
30
|
+
|
31
|
+
# @!macro [new] read_result_return
|
32
|
+
# @return [DataEntry]
|
33
|
+
# @return [nil] if at the end of file
|
34
|
+
# @raise [ChecksumError] if the entry has an incorrect checksum
|
35
|
+
|
25
36
|
# Fetch entry at given offset.
|
26
|
-
#
|
37
|
+
# With optional size parameter we can do less I/O operations.
|
38
|
+
# @macro might_change_pos
|
27
39
|
# @param [Integer] offset File offset in bytes
|
28
|
-
# @param [Integer, nil] size
|
40
|
+
# @param [Integer, nil] size Entry size in bytes
|
41
|
+
# @macro read_result_return
|
29
42
|
def [](offset, size = nil)
|
30
|
-
|
31
|
-
|
43
|
+
if size.nil?
|
44
|
+
seek(offset)
|
45
|
+
return read
|
46
|
+
end
|
47
|
+
pread(offset, size)
|
32
48
|
end
|
33
49
|
|
34
|
-
# yields each
|
50
|
+
# yields each entry in the file
|
51
|
+
# @macro might_change_pos
|
35
52
|
# @return [Enumerator] if no block given
|
36
|
-
# @yieldparam [DataEntry]
|
53
|
+
# @yieldparam [DataEntry] data_entry Entry from the file
|
37
54
|
def each
|
38
55
|
return to_enum(__method__) unless block_given?
|
39
56
|
|
@@ -46,28 +63,30 @@ module Rubcask
|
|
46
63
|
end
|
47
64
|
end
|
48
65
|
|
49
|
-
# Read entry at the current file position
|
50
|
-
# @
|
51
|
-
# @
|
52
|
-
# @
|
66
|
+
# Read an entry at the current file position
|
67
|
+
# @macro might_change_pos
|
68
|
+
# @param [Integer, nil] size Entry size in bytes
|
69
|
+
# @macro read_result_return
|
53
70
|
def read(size = nil)
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
crc, expire_timestamp, key_size, value_size = header.unpack(HEADER_FORMAT)
|
60
|
-
key = io.read(key_size)
|
61
|
-
value = io.read(value_size)
|
71
|
+
read_from_io(
|
72
|
+
size ? StringIO.new(@file.read(size)) : @file
|
73
|
+
)
|
74
|
+
end
|
62
75
|
|
63
|
-
|
64
|
-
|
76
|
+
# Fetch an entry at given offset and with provided size
|
77
|
+
# @macro no_change_pos
|
78
|
+
# @param [Integer] offset File offset in bytes
|
79
|
+
# @param [Integer] size Entry size in bytes
|
80
|
+
# @macro read_result_return
|
81
|
+
def pread(offset, size)
|
82
|
+
read_from_io(StringIO.new(@file.pread(size, offset)))
|
65
83
|
end
|
66
84
|
|
67
85
|
AppendResult = Struct.new(:value_pos, :value_size)
|
68
|
-
# Append
|
86
|
+
# Append an entry at the end of the file
|
87
|
+
# @macro no_change_pos
|
69
88
|
# @param [DataEntry] entry Entry to write to the file
|
70
|
-
# @return [AppendResult] struct containing position and size of the
|
89
|
+
# @return [AppendResult] struct containing position and size of the entry
|
71
90
|
def append(entry)
|
72
91
|
current_pos = @write_pos
|
73
92
|
|
@@ -87,5 +106,20 @@ module Rubcask
|
|
87
106
|
@file.flush
|
88
107
|
AppendResult.new(current_pos, @write_pos - current_pos)
|
89
108
|
end
|
109
|
+
|
110
|
+
private
|
111
|
+
|
112
|
+
def read_from_io(io)
|
113
|
+
header = io.read(18)
|
114
|
+
|
115
|
+
return nil unless header
|
116
|
+
|
117
|
+
crc, expire_timestamp, key_size, value_size = header.unpack(HEADER_FORMAT)
|
118
|
+
key = io.read(key_size)
|
119
|
+
value = io.read(value_size)
|
120
|
+
|
121
|
+
raise ChecksumError, "Checksums do not match" if crc != Zlib.crc32(header[4..] + key + value)
|
122
|
+
DataEntry.new(expire_timestamp, key, value)
|
123
|
+
end
|
90
124
|
end
|
91
125
|
end
|
data/lib/rubcask/directory.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "concurrent"
|
3
|
+
require "concurrent/atomic/atomic_fixnum"
|
4
|
+
require "concurrent/atomic/reentrant_read_write_lock"
|
4
5
|
|
6
|
+
require "fiber" # rubocop:disable Lint/RedundantRequireStatement It is needed for `Fiber.current`(used by concurrent) in some rubies
|
5
7
|
require "forwardable"
|
6
8
|
require "logger"
|
7
9
|
require "monitor"
|
@@ -131,11 +133,11 @@ module Rubcask
|
|
131
133
|
end
|
132
134
|
|
133
135
|
data_file = @files[entry.file_id]
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
136
|
+
|
137
|
+
# We are using pread so there's no need to synchronize the read
|
138
|
+
value = data_file.pread(entry.value_pos, entry.value_size).value
|
139
|
+
return nil if Tombstone.is_tombstone?(value)
|
140
|
+
return value
|
139
141
|
end
|
140
142
|
end
|
141
143
|
|
@@ -190,21 +192,16 @@ module Rubcask
|
|
190
192
|
# @yieldparam [String] value
|
191
193
|
# @macro lock_block_for_iteration
|
192
194
|
# @macro key_any_order
|
193
|
-
# @return Enumerator if block
|
195
|
+
# @return [Enumerator<Array(String, String)>] if no block given
|
194
196
|
def each
|
195
197
|
return to_enum(__method__) unless block_given?
|
196
198
|
|
197
199
|
@lock.with_read_lock do
|
198
200
|
@keydir.each do |key, entry|
|
199
201
|
file = @files[entry.file_id]
|
200
|
-
file.
|
201
|
-
|
202
|
-
|
203
|
-
next if Tombstone.is_tombstone?(value)
|
204
|
-
yield [key, value]
|
205
|
-
ensure
|
206
|
-
file.mon_exit
|
207
|
-
end
|
202
|
+
value = file[entry.value_pos, entry.value_size].value
|
203
|
+
next if Tombstone.is_tombstone?(value)
|
204
|
+
yield [key, value]
|
208
205
|
end
|
209
206
|
end
|
210
207
|
end
|
@@ -213,7 +210,7 @@ module Rubcask
|
|
213
210
|
# @macro deleted_keys
|
214
211
|
# @macro key_any_order
|
215
212
|
# @macro lock_block_for_iteration
|
216
|
-
# @return Enumerator if block
|
213
|
+
# @return [Enumerator<String>] if no block given
|
217
214
|
def each_key(&block)
|
218
215
|
return to_enum(__method__) unless block
|
219
216
|
|
data/lib/rubcask/hinted_file.rb
CHANGED
@@ -13,7 +13,7 @@ module Rubcask
|
|
13
13
|
ID_REGEX = /(\d+)\.data$/
|
14
14
|
HINT_EXTENSION_REGEX = /\.data$/
|
15
15
|
|
16
|
-
def_delegators :@data_file, :seek, :[], :close, :flush, :each, :pos, :write_pos
|
16
|
+
def_delegators :@data_file, :seek, :[], :pread, :close, :flush, :each, :pos, :write_pos
|
17
17
|
|
18
18
|
# @return [String] path of the file
|
19
19
|
attr_reader :path
|
data/lib/rubcask/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rubcask
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Marcin Henryk Bartkowiak
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: concurrent-ruby
|