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.
Files changed (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/key_value_chain.rb +150 -0
  3. 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: []