redis-diff_match_patch 1.0.0 → 1.1.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.
- 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
|