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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f76c2109a42456676af151b6a5cef12a74af248d
4
- data.tar.gz: 3868000b435fe7980807d5ea3301d87378ec4602
3
+ metadata.gz: 2d899599867306841878c64702cb5786909538d3
4
+ data.tar.gz: 70a14178c9956a8e3a44bb5cc90ac977f063486c
5
5
  SHA512:
6
- metadata.gz: c56a780bfd908e067fa7477c381f0ccb5b0db796e6f8d57e52109db39ed5baa6dc16832229e7b7223add0d04fdd34da1121555c8e71490eccdfd5be0024ff6f4
7
- data.tar.gz: 14a8b29628bce41a2886a5439ab10b28d8c07b523ee8886219b276d4b0f94add1340622d08d3b1183f00c8dddb037132ad35dccfcc11f4428c5c3de17900646f
6
+ metadata.gz: b03d8b518b7b32ae744ced5e17ddbd010c4f3495cdfd2b90f702bff7d67e26387a01d532d77e9c84381d08eb0ebe575cc1206f884fb0093875de321979cfd57d
7
+ data.tar.gz: 7ae3ebdff6141df8985529030e6bb5a1aec3b1de2e17fd25f1b4fe4364d06166cfbc416dce4ffa119e624aaa7bb2131db250b51ee78c38dd2a51545496c679b7
data/.travis.yml CHANGED
@@ -4,6 +4,9 @@ rvm:
4
4
  - 2.0
5
5
  - 2.1
6
6
  - 2.2
7
+ - 2.3.0
7
8
  - jruby
8
9
  services:
9
- - redis-server
10
+ - redis-server
11
+ before_install:
12
+ - gem install bundler
data/Rakefile CHANGED
@@ -5,6 +5,7 @@ Rake::TestTask.new(:spec) do |t|
5
5
  t.libs << 'spec'
6
6
  t.pattern = 'spec/**/*_spec.rb'
7
7
  t.verbose = false
8
+ t.warning = false
8
9
  end
9
10
 
10
11
  task :console do
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 'redic', '~> 1.5.0'
22
- spec.add_dependency 'restruct', '~> 0.1.0'
23
- spec.add_dependency 'class_config', '~> 0.0.2'
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.5.9'
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
@@ -1,4 +1,3 @@
1
- require 'redic'
2
1
  require 'digest/sha1'
3
2
  require 'msgpack'
4
3
  require 'class_config'
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
@@ -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
- changes.each do |change|
22
- current_change = change
23
- if hash[collection][id]
24
- current_change = TrackFlatter.flatten [hash[collection][id], change]
25
- if current_change && [INSERT, UPDATE].include?(current_change['action'])
26
- base_data = base_index[collection].include?(id) ? base_index[collection][id].data : {}
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
@@ -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 current_delta, target_delta, revert_delta, base_index
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(current_delta, target_delta, revert_delta, base_index)
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(current_delta, target_delta, revert_delta, base_index)
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
 
@@ -1,3 +1,3 @@
1
1
  module Eternity
2
- VERSION = '0.1.2'
2
+ VERSION = '0.1.3'
3
3
  end
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.2
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-01-08 00:00:00.000000000 Z
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.0
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.0
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.2
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.2
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.4
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.4
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.5.9
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.5.9
68
+ version: '0.7'
83
69
  - !ruby/object:Gem::Dependency
84
70
  name: bundler
85
71
  requirement: !ruby/object:Gem::Requirement