eternity 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +4 -1
- data/Rakefile +1 -0
- data/eternity.gemspec +5 -6
- data/lib/eternity.rb +0 -1
- data/lib/eternity/blob.rb +27 -0
- data/lib/eternity/delta.rb +6 -13
- data/lib/eternity/patch.rb +5 -5
- data/lib/eternity/version.rb +1 -1
- data/spec/delta_spec.rb +66 -0
- metadata +10 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2d899599867306841878c64702cb5786909538d3
|
4
|
+
data.tar.gz: 70a14178c9956a8e3a44bb5cc90ac977f063486c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b03d8b518b7b32ae744ced5e17ddbd010c4f3495cdfd2b90f702bff7d67e26387a01d532d77e9c84381d08eb0ebe575cc1206f884fb0093875de321979cfd57d
|
7
|
+
data.tar.gz: 7ae3ebdff6141df8985529030e6bb5a1aec3b1de2e17fd25f1b4fe4364d06166cfbc416dce4ffa119e624aaa7bb2131db250b51ee78c38dd2a51545496c679b7
|
data/.travis.yml
CHANGED
data/Rakefile
CHANGED
data/eternity.gemspec
CHANGED
@@ -18,15 +18,14 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency '
|
22
|
-
spec.add_dependency '
|
23
|
-
spec.add_dependency '
|
24
|
-
spec.add_dependency 'transparent_proxy', '~> 0.0.4'
|
21
|
+
spec.add_dependency 'restruct', '~> 0.1'
|
22
|
+
spec.add_dependency 'class_config', '~> 0.0'
|
23
|
+
spec.add_dependency 'transparent_proxy', '~> 0.0'
|
25
24
|
|
26
25
|
if RUBY_PLATFORM == 'java'
|
27
|
-
spec.add_dependency 'msgpack-jruby'
|
26
|
+
spec.add_dependency 'msgpack-jruby', '~> 1.4'
|
28
27
|
else
|
29
|
-
spec.add_dependency 'msgpack', '~> 0.
|
28
|
+
spec.add_dependency 'msgpack', '~> 0.7'
|
30
29
|
end
|
31
30
|
|
32
31
|
spec.add_development_dependency 'bundler', '~> 1.5'
|
data/lib/eternity.rb
CHANGED
data/lib/eternity/blob.rb
CHANGED
@@ -62,6 +62,29 @@ module Eternity
|
|
62
62
|
Eternity.connection.call('KEYS', Eternity.keyspace[:blob]['*']).count
|
63
63
|
end
|
64
64
|
|
65
|
+
def orphan_files
|
66
|
+
repositories = Repository.all
|
67
|
+
|
68
|
+
repo_commits = repositories.map { |r| r.current_commit } +
|
69
|
+
repositories.flat_map { |r| r.branches.values.map { |c| Commit.new c } }
|
70
|
+
|
71
|
+
branch_commits = Branch.names.map { |b| Branch[b] }
|
72
|
+
|
73
|
+
used_by_type = {
|
74
|
+
commit: (repo_commits.flat_map { |c| [c.id] + c.history_ids } + branch_commits.flat_map { |c| [c.id] + c.history_ids }).uniq
|
75
|
+
}
|
76
|
+
|
77
|
+
commit_blobs = used_by_type[:commit].map { |id| Blob.read :commit, id }
|
78
|
+
|
79
|
+
[:index, :delta, :history].each do |type|
|
80
|
+
used_by_type[type] = commit_blobs.map { |b| b[type.to_s] }.compact
|
81
|
+
end
|
82
|
+
|
83
|
+
used_by_type.each_with_object({}) do |(type, used), hash|
|
84
|
+
hash[type] = files_of(type) - used.map { |id| file_for type, id }
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
65
88
|
private
|
66
89
|
|
67
90
|
def write_redis(type, sha1, serialization)
|
@@ -95,6 +118,10 @@ module Eternity
|
|
95
118
|
File.join Eternity.blob_path, type.to_s, sha1[0..1], sha1[2..-1]
|
96
119
|
end
|
97
120
|
|
121
|
+
def files_of(type)
|
122
|
+
Dir.glob File.join(Eternity.blob_path, type.to_s, '*', '*')
|
123
|
+
end
|
124
|
+
|
98
125
|
end
|
99
126
|
|
100
127
|
end
|
data/lib/eternity/delta.rb
CHANGED
@@ -18,22 +18,15 @@ module Eternity
|
|
18
18
|
union(deltas).each_with_object({}) do |(collection, elements), hash|
|
19
19
|
hash[collection] = {}
|
20
20
|
elements.each do |id, changes|
|
21
|
-
|
22
|
-
|
23
|
-
if
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
current_change['data'] = ConflictResolver.resolve hash[collection][id]['data'] || base_data,
|
28
|
-
change['data'],
|
29
|
-
base_data
|
30
|
-
end
|
31
|
-
elsif hash[collection].key?(id) && change['action'] == DELETE
|
32
|
-
current_change = nil
|
21
|
+
current_change = TrackFlatter.flatten changes
|
22
|
+
if current_change
|
23
|
+
if current_change['action'] == UPDATE
|
24
|
+
base_data = base_index[collection].include?(id) ? base_index[collection][id].data : {}
|
25
|
+
current_change['data'] = changes.select { |c| c['data'] }
|
26
|
+
.inject(base_data) { |d,c| ConflictResolver.resolve d, c['data'], base_data }
|
33
27
|
end
|
34
28
|
hash[collection][id] = current_change
|
35
29
|
end
|
36
|
-
hash[collection].delete id unless hash[collection][id]
|
37
30
|
end
|
38
31
|
hash.delete collection if hash[collection].empty?
|
39
32
|
end
|
data/lib/eternity/patch.rb
CHANGED
@@ -22,7 +22,7 @@ module Eternity
|
|
22
22
|
@base_commit ||= Commit.base_of current_commit, target_commit
|
23
23
|
end
|
24
24
|
|
25
|
-
def delta
|
25
|
+
def delta
|
26
26
|
@delta ||= TransparentProxy.new { calculate_delta }
|
27
27
|
end
|
28
28
|
|
@@ -47,12 +47,12 @@ module Eternity
|
|
47
47
|
def calculate_delta
|
48
48
|
base_commit.with_index do |base_index|
|
49
49
|
current_commit.with_index do |current_index|
|
50
|
-
|
50
|
+
|
51
51
|
current_delta = Delta.merge current_history.reverse.map(&:delta), base_index
|
52
52
|
target_delta = Delta.merge target_history.reverse.map(&:delta), base_index
|
53
53
|
revert_delta = Delta.revert current_delta, base_index
|
54
54
|
|
55
|
-
merged_delta = merge_deltas
|
55
|
+
merged_delta = merge_deltas target_delta, revert_delta, base_index
|
56
56
|
|
57
57
|
merged_delta.each_with_object({}) do |(collection, elements), hash|
|
58
58
|
hash[collection] = {}
|
@@ -92,7 +92,7 @@ module Eternity
|
|
92
92
|
super
|
93
93
|
end
|
94
94
|
|
95
|
-
def merge_deltas(
|
95
|
+
def merge_deltas(target_delta, revert_delta, base_index)
|
96
96
|
remaining_delta = Delta.merge remaining_history.reverse.map(&:delta), base_index
|
97
97
|
Delta.merge [revert_delta, target_delta, remaining_delta], base_index
|
98
98
|
end
|
@@ -106,7 +106,7 @@ module Eternity
|
|
106
106
|
|
107
107
|
private
|
108
108
|
|
109
|
-
def merge_deltas(
|
109
|
+
def merge_deltas(target_delta, revert_delta, base_index)
|
110
110
|
Delta.merge [revert_delta, target_delta], base_index
|
111
111
|
end
|
112
112
|
|
data/lib/eternity/version.rb
CHANGED
data/spec/delta_spec.rb
CHANGED
@@ -313,4 +313,70 @@ describe 'Delta' do
|
|
313
313
|
|
314
314
|
end
|
315
315
|
|
316
|
+
it 'Insert -> Delete -> Update' do
|
317
|
+
# P P M
|
318
|
+
# REPO 1: (*)----(1)-------(4)---(7)
|
319
|
+
# \ \ \ /
|
320
|
+
# REPO 2: \-(2)--(3)---(5)--(6)
|
321
|
+
# M MP
|
322
|
+
|
323
|
+
repo_1[:countries].insert 'AR', name: 'Argentina'
|
324
|
+
repo_1.commit author: 'User 1', message: 'Commit 1'
|
325
|
+
repo_1.current_commit.must_equal_index 'countries' => {
|
326
|
+
'AR' => digest(name: 'Argentina'),
|
327
|
+
}
|
328
|
+
|
329
|
+
repo_1.push
|
330
|
+
|
331
|
+
repo_2[:countries].insert 'UY', name: 'Uruguay'
|
332
|
+
repo_2.commit author: 'User 2', message: 'Commit 2'
|
333
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
334
|
+
'UY' => digest(name: 'Uruguay'),
|
335
|
+
}
|
336
|
+
|
337
|
+
delta = repo_2.pull
|
338
|
+
delta.must_equal 'countries' => {
|
339
|
+
'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina'}}
|
340
|
+
}
|
341
|
+
|
342
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
343
|
+
'AR' => digest(name: 'Argentina'),
|
344
|
+
'UY' => digest(name: 'Uruguay')
|
345
|
+
}
|
346
|
+
|
347
|
+
repo_1[:countries].delete 'AR'
|
348
|
+
repo_1.commit author: 'User 1', message: 'Commit 4'
|
349
|
+
repo_1.current_commit.must_equal_index Hash.new
|
350
|
+
|
351
|
+
repo_1.push
|
352
|
+
|
353
|
+
repo_2[:countries].update 'AR', name: 'Argentina', number: 54
|
354
|
+
repo_2.commit author: 'User 2', message: 'Commit 5'
|
355
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
356
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
357
|
+
'UY' => digest(name: 'Uruguay')
|
358
|
+
}
|
359
|
+
|
360
|
+
delta = repo_2.pull
|
361
|
+
delta.must_be_empty
|
362
|
+
|
363
|
+
repo_2.current_commit.must_equal_index 'countries' => {
|
364
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
365
|
+
'UY' => digest(name: 'Uruguay')
|
366
|
+
}
|
367
|
+
|
368
|
+
repo_2.push
|
369
|
+
|
370
|
+
delta = repo_1.pull
|
371
|
+
delta.must_equal 'countries' => {
|
372
|
+
'AR' => {'action' => 'insert', 'data' => {'name' => 'Argentina', 'number' => 54}},
|
373
|
+
'UY' => {'action' => 'insert', 'data' => {'name' => 'Uruguay'}},
|
374
|
+
}
|
375
|
+
|
376
|
+
repo_1.current_commit.must_equal_index 'countries' => {
|
377
|
+
'AR' => digest(name: 'Argentina', number: 54),
|
378
|
+
'UY' => digest(name: 'Uruguay')
|
379
|
+
}
|
380
|
+
end
|
381
|
+
|
316
382
|
end
|
metadata
CHANGED
@@ -1,85 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: eternity
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gabriel Naiman
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-04-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
-
- !ruby/object:Gem::Dependency
|
14
|
-
name: redic
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
16
|
-
requirements:
|
17
|
-
- - ~>
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.5.0
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ~>
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.5.0
|
27
13
|
- !ruby/object:Gem::Dependency
|
28
14
|
name: restruct
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
30
16
|
requirements:
|
31
17
|
- - ~>
|
32
18
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.1
|
19
|
+
version: '0.1'
|
34
20
|
type: :runtime
|
35
21
|
prerelease: false
|
36
22
|
version_requirements: !ruby/object:Gem::Requirement
|
37
23
|
requirements:
|
38
24
|
- - ~>
|
39
25
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.1
|
26
|
+
version: '0.1'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: class_config
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ~>
|
46
32
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.0
|
33
|
+
version: '0.0'
|
48
34
|
type: :runtime
|
49
35
|
prerelease: false
|
50
36
|
version_requirements: !ruby/object:Gem::Requirement
|
51
37
|
requirements:
|
52
38
|
- - ~>
|
53
39
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.0
|
40
|
+
version: '0.0'
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: transparent_proxy
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - ~>
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: 0.0
|
47
|
+
version: '0.0'
|
62
48
|
type: :runtime
|
63
49
|
prerelease: false
|
64
50
|
version_requirements: !ruby/object:Gem::Requirement
|
65
51
|
requirements:
|
66
52
|
- - ~>
|
67
53
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.0
|
54
|
+
version: '0.0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: msgpack
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ~>
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.
|
61
|
+
version: '0.7'
|
76
62
|
type: :runtime
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - ~>
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.
|
68
|
+
version: '0.7'
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
70
|
name: bundler
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|