redis-diff_match_patch 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/diff_match_patch-merge.lua +111 -41
- data/lib/redis-diff_match_patch.rb +1 -1
- data/redis-diff_match_patch.gemspec +1 -0
- data/test/redis-diff_match_patch_test.rb +29 -0
- metadata +19 -8
@@ -2316,49 +2316,119 @@ end
|
|
2316
2316
|
local src = redis.call("get", KEYS[1])
|
2317
2317
|
local dst1 = redis.call("get", KEYS[2])
|
2318
2318
|
local dst2 = redis.call("get", KEYS[3])
|
2319
|
-
local
|
2320
|
-
local
|
2319
|
+
local diff1 = diff_main(src, dst1)
|
2320
|
+
local diff2 = diff_main(src, dst2)
|
2321
|
+
local diff = diff1
|
2322
|
+
local diff1_offset = 1
|
2323
|
+
|
2324
|
+
function diffToString(diffs)
|
2325
|
+
local s = ""
|
2326
|
+
|
2327
|
+
for x, e in ipairs(diffs) do
|
2328
|
+
if e[1] == DIFF_EQUAL then
|
2329
|
+
s = s .. " EQU " .. e[2]
|
2330
|
+
elseif e[1] == DIFF_DELETE then
|
2331
|
+
s = s .. " DEL " .. e[2]
|
2332
|
+
elseif e[1] == DIFF_INSERT then
|
2333
|
+
s = s .. " INS " .. e[2]
|
2334
|
+
end
|
2335
|
+
end
|
2336
|
+
|
2337
|
+
return s
|
2338
|
+
end
|
2339
|
+
|
2340
|
+
redis.call("set", "diff1-demo", diffToString(diff1))
|
2341
|
+
redis.call("set", "diff2-demo", diffToString(diff2))
|
2342
|
+
redis.call("del", "diff-demo-log")
|
2343
|
+
redis.call("del", "diff2-demo-log")
|
2344
|
+
redis.call("rpush", "diff-demo-log", diffToString(diff))
|
2345
|
+
redis.call("rpush", "diff2-demo-log", diffToString(diff2))
|
2346
|
+
|
2347
|
+
-- Merge diff2 into diff1.
|
2348
|
+
while table.getn(diff2) > 0 do
|
2349
|
+
local element2 = table.remove(diff2, 1)
|
2350
|
+
local type2 = element2[1]
|
2351
|
+
local string2 = element2[2]
|
2352
|
+
local length2 = string.len(string2)
|
2353
|
+
|
2354
|
+
if table.getn(diff) < diff1_offset then
|
2355
|
+
table.insert(diff, element2)
|
2356
|
+
else
|
2357
|
+
local element1 = diff[diff1_offset]
|
2358
|
+
local type1 = element1[1]
|
2359
|
+
local string1 = element1[2]
|
2360
|
+
local length1 = string.len(string1)
|
2361
|
+
|
2362
|
+
if type2 == DIFF_EQUAL then
|
2363
|
+
|
2364
|
+
if type1 == DIFF_EQUAL or type1 == DIFF_DELETE then
|
2365
|
+
if length1 == length2 then
|
2366
|
+
elseif length1 < length2 then
|
2367
|
+
local substring = string.sub(string2, length1 + 1)
|
2368
|
+
table.insert(diff2, 1, { type2, substring })
|
2369
|
+
elseif length1 > length2 then
|
2370
|
+
local substring1 = string.sub(string1, 1, length2)
|
2371
|
+
local substring2 = string.sub(string1, length2 + 1)
|
2372
|
+
diff[diff1_offset] = { type1, substring1 }
|
2373
|
+
table.insert(diff, diff1_offset + 1, { type1, substring2 })
|
2374
|
+
end
|
2375
|
+
|
2376
|
+
elseif type1 == DIFF_INSERT then
|
2377
|
+
-- The other guy is adding text, wait for him to finish.
|
2378
|
+
table.insert(diff2, 1, element2)
|
2379
|
+
|
2380
|
+
end
|
2381
|
+
|
2382
|
+
elseif type2 == DIFF_DELETE then
|
2383
|
+
|
2384
|
+
-- If I'm deleting and he's deleting too
|
2385
|
+
if type1 == DIFF_EQUAL or type1 == DIFF_DELETE then
|
2386
|
+
if length1 <= length2 then
|
2387
|
+
local substring = string.sub(string2, length1 + 1)
|
2388
|
+
diff[diff1_offset] = { DIFF_DELETE, string1 }
|
2389
|
+
table.insert(diff2, 1, { type1, substring })
|
2390
|
+
elseif length1 > length2 then
|
2391
|
+
local substring1 = string.sub(string1, 1, length2)
|
2392
|
+
local substring2 = string.sub(string1, length2 + 1)
|
2393
|
+
diff[diff1_offset] = { DIFF_DELETE, substring1 }
|
2394
|
+
table.insert(diff, diff1_offset + 1, { type1, substring2 })
|
2395
|
+
end
|
2396
|
+
|
2397
|
+
-- He's adding text, let him proceed!
|
2398
|
+
elseif type1 == DIFF_INSERT then
|
2399
|
+
table.insert(diff2, element2)
|
2400
|
+
|
2401
|
+
end
|
2402
|
+
|
2403
|
+
elseif type2 == DIFF_INSERT then
|
2404
|
+
|
2405
|
+
-- He doesn't have a change for this location, go ahead and insert.
|
2406
|
+
if type1 == DIFF_EQUAL then
|
2407
|
+
table.insert(diff, diff1_offset, element2)
|
2408
|
+
|
2409
|
+
-- Insert first and wait to delete.
|
2410
|
+
elseif type1 == DIFF_DELETE then
|
2411
|
+
table.insert(diff, diff1_offset, element2)
|
2412
|
+
|
2413
|
+
-- If we're both trying to insert, throw string2 away.
|
2414
|
+
elseif type1 == DIFF_INSERT then
|
2415
|
+
|
2416
|
+
end
|
2417
|
+
|
2418
|
+
end
|
2419
|
+
|
2420
|
+
diff1_offset = diff1_offset + 1
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
redis.call("rpush", "diff-demo-log", diffToString(diff))
|
2424
|
+
redis.call("rpush", "diff2-demo-log", diffToString(diff2))
|
2425
|
+
end
|
2426
|
+
|
2427
|
+
local patches = patch_make(src, diff)
|
2428
|
+
local result = patch_apply(patches, src)
|
2321
2429
|
|
2322
2430
|
if KEYS[4] then
|
2323
|
-
|
2431
|
+
redis.call("set", KEYS[4], result)
|
2324
2432
|
end
|
2325
2433
|
|
2326
2434
|
return result
|
2327
|
-
|
2328
|
-
-- -- Expose the API
|
2329
|
-
-- _M.DIFF_DELETE = DIFF_DELETE
|
2330
|
-
-- _M.DIFF_INSERT = DIFF_INSERT
|
2331
|
-
-- _M.DIFF_EQUAL = DIFF_EQUAL
|
2332
|
-
--
|
2333
|
-
-- _M.diff_main = diff_main
|
2334
|
-
-- _M.diff_cleanupSemantic = diff_cleanupSemantic
|
2335
|
-
-- _M.diff_cleanupEfficiency = diff_cleanupEfficiency
|
2336
|
-
-- _M.diff_levenshtein = diff_levenshtein
|
2337
|
-
-- _M.diff_prettyHtml = diff_prettyHtml
|
2338
|
-
--
|
2339
|
-
-- _M.match_main = match_main
|
2340
|
-
--
|
2341
|
-
-- _M.patch_make = patch_make
|
2342
|
-
-- _M.patch_toText = patch_toText
|
2343
|
-
-- _M.patch_fromText = patch_fromText
|
2344
|
-
-- _M.patch_apply = patch_apply
|
2345
|
-
--
|
2346
|
-
-- -- Expose some non-API functions as well, for testing purposes etc.
|
2347
|
-
-- _M.diff_commonPrefix = _diff_commonPrefix
|
2348
|
-
-- _M.diff_commonSuffix = _diff_commonSuffix
|
2349
|
-
-- _M.diff_commonOverlap = _diff_commonOverlap
|
2350
|
-
-- _M.diff_halfMatch = _diff_halfMatch
|
2351
|
-
-- _M.diff_bisect = _diff_bisect
|
2352
|
-
-- _M.diff_cleanupMerge = _diff_cleanupMerge
|
2353
|
-
-- _M.diff_cleanupSemanticLossless = _diff_cleanupSemanticLossless
|
2354
|
-
-- _M.diff_text1 = _diff_text1
|
2355
|
-
-- _M.diff_text2 = _diff_text2
|
2356
|
-
-- _M.diff_toDelta = _diff_toDelta
|
2357
|
-
-- _M.diff_fromDelta = _diff_fromDelta
|
2358
|
-
-- _M.diff_xIndex = _diff_xIndex
|
2359
|
-
-- _M.match_alphabet = _match_alphabet
|
2360
|
-
-- _M.match_bitap = _match_bitap
|
2361
|
-
-- _M.new_patch_obj = _new_patch_obj
|
2362
|
-
-- _M.patch_addContext = _patch_addContext
|
2363
|
-
-- _M.patch_splitMax = _patch_splitMax
|
2364
|
-
-- _M.patch_addPadding = _patch_addPadding
|
@@ -115,6 +115,27 @@ class Redis
|
|
115
115
|
assert_equal expected, actual
|
116
116
|
end
|
117
117
|
|
118
|
+
def test_simple_merges
|
119
|
+
[
|
120
|
+
[ "" , [ "" , "" , "" ] ],
|
121
|
+
[ "a" , [ "" , "a" , "" ] ],
|
122
|
+
[ "a" , [ "" , "" , "a" ] ],
|
123
|
+
[ "cat" , [ "horse" , "cat" , "horse" ] ],
|
124
|
+
[ "cat" , [ "horse" , "horse" , "cat" ] ],
|
125
|
+
[ "cat" , [ "dog" , "cat" , "dog" ] ],
|
126
|
+
[ "cat" , [ "dog" , "dog" , "cat" ] ],
|
127
|
+
[ "" , [ "cat" , "" , "cat" ] ],
|
128
|
+
[ "" , [ "cat" , "cat" , "" ] ],
|
129
|
+
[ "cat" , [ "a" , "ca" , "at" ] ],
|
130
|
+
[ "take a break" , [ "give heart" , "take heart" , "give a break" ] ],
|
131
|
+
[ "defghi" , [ "abc" , "def" , "ghi" ] ],
|
132
|
+
[ "alex\ntest\nc\nd" , [ "a\nb\nc" , "alex\nb\nc\nd" , "a\ntest\nc" ] ],
|
133
|
+
[ "a b c d e" , [ "1 2 3 4 5" , "a 2 c 4 e" , "1 b 3 d 5" ] ]
|
134
|
+
].each do |expect, args|
|
135
|
+
assert_equal expect, simple_merge(*args)
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
118
139
|
protected
|
119
140
|
|
120
141
|
def k key
|
@@ -137,6 +158,14 @@ class Redis
|
|
137
158
|
@redis.get k(key)
|
138
159
|
end
|
139
160
|
|
161
|
+
def simple_merge doc, rev1, rev2
|
162
|
+
set :doc, doc
|
163
|
+
set :rev1, rev1
|
164
|
+
set :rev2, rev2
|
165
|
+
|
166
|
+
@dmp.merge k(:doc), k(:rev1), k(:rev2)
|
167
|
+
end
|
168
|
+
|
140
169
|
end
|
141
170
|
|
142
171
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-diff_match_patch
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-03-
|
12
|
+
date: 2012-03-06 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement: &
|
16
|
+
requirement: &70096136592700 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70096136592700
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: turn
|
27
|
-
requirement: &
|
27
|
+
requirement: &70096136592280 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,18 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70096136592280
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: rake
|
38
|
+
requirement: &70096136591860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70096136591860
|
36
47
|
description: This library will allow you to perform atomic diffs, patches and merges
|
37
48
|
on Redis strings.
|
38
49
|
email:
|
@@ -68,7 +79,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
68
79
|
version: '0'
|
69
80
|
segments:
|
70
81
|
- 0
|
71
|
-
hash:
|
82
|
+
hash: 2305032445798493678
|
72
83
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
84
|
none: false
|
74
85
|
requirements:
|
@@ -77,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
77
88
|
version: '0'
|
78
89
|
segments:
|
79
90
|
- 0
|
80
|
-
hash:
|
91
|
+
hash: 2305032445798493678
|
81
92
|
requirements: []
|
82
93
|
rubyforge_project: redis-diff_match_patch
|
83
94
|
rubygems_version: 1.8.11
|