key_value_chain 0.0.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 +7 -0
- data/lib/key_value_chain.rb +150 -0
- metadata +45 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 6e6f9bda4e6d93193dbb407f219688b339fbf83964c934df9a3e19e19fc549cf
|
|
4
|
+
data.tar.gz: fdb16d7af710bf239370f38a769a81afdc157c6cc70c2b46002698f2785ec240
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: edadbe7b571b1328f9314f67cfed9e4d3f6ea605c2f687cb1ad2db875a0019eab55ba0911c821684b143e7eb5e4d52918f664c2cc720838ecc3a429557acf2c3
|
|
7
|
+
data.tar.gz: 7caec92a77e745dae5e542c10d19a1b9f1bdaca021a931caf683803c5ac48a25d369c75c0553bcb2d50901237bf543fd692bd513b9cb15d47b736b2f5e583aaa
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
require 'digest'
|
|
2
|
+
require 'json'
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class KeyValueChain
|
|
6
|
+
def initialize(path)
|
|
7
|
+
@path = path
|
|
8
|
+
@chain = DriveKVChain.new(path)
|
|
9
|
+
end
|
|
10
|
+
def [](key)
|
|
11
|
+
@chain[key]
|
|
12
|
+
end
|
|
13
|
+
def []=(key,value)
|
|
14
|
+
@chain[key] = value
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
class KVPair
|
|
18
|
+
attr_reader :key, :value
|
|
19
|
+
def initialize(prevBlockHash, key, value, nonce = -1)
|
|
20
|
+
@prevBlockHash = prevBlockHash
|
|
21
|
+
@key = key
|
|
22
|
+
@value = value
|
|
23
|
+
@nonce = nonce
|
|
24
|
+
if @nonce < 0
|
|
25
|
+
@none = 0
|
|
26
|
+
until self.is_valid?
|
|
27
|
+
@nonce += 1
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
def to_hash
|
|
32
|
+
Digest::SHA1.hexdigest self.to_json
|
|
33
|
+
end
|
|
34
|
+
def from_json(json)
|
|
35
|
+
h = JSON.parse(json)
|
|
36
|
+
@prevBlockHash = h["prevBlock"]
|
|
37
|
+
@nonce = h["nonce"]
|
|
38
|
+
@key = h["key"]
|
|
39
|
+
@value = h["value"]
|
|
40
|
+
end
|
|
41
|
+
def to_json
|
|
42
|
+
pairhash = {:prevBlock => @prevBlockHash, :nonce => @nonce, :key => @key, :value => @value}
|
|
43
|
+
JSON.generate(pairhash)
|
|
44
|
+
end
|
|
45
|
+
def is_valid?
|
|
46
|
+
self.to_hash[0,4] == "0000"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
class DriveKVChain
|
|
51
|
+
def initialize(path)
|
|
52
|
+
@path = path
|
|
53
|
+
@last_block_hash = "0000000000000000000000000000000000000000"
|
|
54
|
+
self[""]
|
|
55
|
+
end
|
|
56
|
+
def [](key)
|
|
57
|
+
prev = "0000000000000000000000000000000000000000"
|
|
58
|
+
value = ""
|
|
59
|
+
File.open(@path, "a+") do |f|
|
|
60
|
+
f.each_line do |line|
|
|
61
|
+
h = JSON.parse(line)
|
|
62
|
+
raise "Broken Blockchain, invalid hashes" unless h["prevBlock"] == prev
|
|
63
|
+
prev = Digest::SHA1.hexdigest line.chomp
|
|
64
|
+
raise "Broken Blockchain, invalid nonce" unless prev[0,4] == "0000"
|
|
65
|
+
value = h["value"] if h["key"] == key
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
@last_block_hash = prev
|
|
69
|
+
value
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def []=(key,value)
|
|
73
|
+
pair = KVPair.new(@last_block_hash, key, value)
|
|
74
|
+
open(@path, 'a') { |f|
|
|
75
|
+
f.puts pair.to_json
|
|
76
|
+
}
|
|
77
|
+
@last_block_hash = pair.to_hash
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
class MemKVChain
|
|
82
|
+
def initialize(path)
|
|
83
|
+
@blocks = []
|
|
84
|
+
@hashtable = Hash.new("")
|
|
85
|
+
@path = path
|
|
86
|
+
self.loadfile
|
|
87
|
+
end
|
|
88
|
+
def add_block_to_hash(pair)
|
|
89
|
+
if pair.is_valid?
|
|
90
|
+
@blocks << pair
|
|
91
|
+
@hashtable[pair.key] = pair.value
|
|
92
|
+
return true
|
|
93
|
+
end
|
|
94
|
+
false
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def add_block(pair)
|
|
98
|
+
if add_block_to_hash(pair)
|
|
99
|
+
open(@path, 'a') { |f|
|
|
100
|
+
f.puts pair.to_json
|
|
101
|
+
}
|
|
102
|
+
return true
|
|
103
|
+
else
|
|
104
|
+
return false
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
def last_block_json
|
|
108
|
+
@blocks[-1].to_json
|
|
109
|
+
end
|
|
110
|
+
def last_block_hash
|
|
111
|
+
if @blocks.any?
|
|
112
|
+
@blocks[-1].to_hash
|
|
113
|
+
else
|
|
114
|
+
"0000000000000000000000000000000000000000"
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
def [](key)
|
|
118
|
+
@hashtable[key]
|
|
119
|
+
end
|
|
120
|
+
def []=(key, value)
|
|
121
|
+
self.add_block(KVPair.new(self.last_block_hash, key, value))
|
|
122
|
+
end
|
|
123
|
+
def loadfile(path = @path)
|
|
124
|
+
#f = File.open(path, "a+")
|
|
125
|
+
#f.foreach(path).with_index do |line, line_num|
|
|
126
|
+
# self.add_block(pair_from_json(line))
|
|
127
|
+
#end
|
|
128
|
+
File.open(path, "a+") do |f|
|
|
129
|
+
f.each_line do |line|
|
|
130
|
+
self.add_block_to_hash(pair_from_json(line))
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def pair_from_json(json)
|
|
138
|
+
pair = KVPair.new("", "", "", 0)
|
|
139
|
+
pair.from_json(json)
|
|
140
|
+
pair
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
#chain = DriveKVChain.new("./logfile")
|
|
150
|
+
#(1..1000).each { |n| puts chain["key#{n}"]}
|
metadata
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: key_value_chain
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.0.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Till Schröder
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-07-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: This is not a serious project! It's just for fun! This is a simple key-value
|
|
14
|
+
store that you can use just like a hash table, but it's also safed to you hard drive.
|
|
15
|
+
email: tillodoc@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/key_value_chain.rb
|
|
21
|
+
homepage: https://gitlab.com/roetlich/keyvaluechainrb
|
|
22
|
+
licenses:
|
|
23
|
+
- MIT
|
|
24
|
+
metadata: {}
|
|
25
|
+
post_install_message:
|
|
26
|
+
rdoc_options: []
|
|
27
|
+
require_paths:
|
|
28
|
+
- lib
|
|
29
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '0'
|
|
34
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0'
|
|
39
|
+
requirements: []
|
|
40
|
+
rubyforge_project:
|
|
41
|
+
rubygems_version: 2.7.6
|
|
42
|
+
signing_key:
|
|
43
|
+
specification_version: 4
|
|
44
|
+
summary: A key-value store. With a blockchain. For fun.
|
|
45
|
+
test_files: []
|