trace_visualization 0.0.1
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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +6 -0
- data/LICENSE +339 -0
- data/LICENSE.txt +22 -0
- data/README.md +4 -0
- data/Rakefile +1 -0
- data/lib/trace_visualization/bwt.rb +32 -0
- data/lib/trace_visualization/bwt.rbold +32 -0
- data/lib/trace_visualization/data/irepetition.rb +49 -0
- data/lib/trace_visualization/data/repetition.rb +101 -0
- data/lib/trace_visualization/generators.rb +53 -0
- data/lib/trace_visualization/longest_common_prefix.rb +34 -0
- data/lib/trace_visualization/mapping.rb +120 -0
- data/lib/trace_visualization/reorder.rb +25 -0
- data/lib/trace_visualization/repetitions.rb +66 -0
- data/lib/trace_visualization/repetitions_concatenation.rb +134 -0
- data/lib/trace_visualization/repetitions_context.rb +18 -0
- data/lib/trace_visualization/repetitions_incrementation.rb +81 -0
- data/lib/trace_visualization/repetitions_psy.rb +83 -0
- data/lib/trace_visualization/suffix_array.rb +203 -0
- data/lib/trace_visualization/utils.rb +47 -0
- data/lib/trace_visualization/version.rb +3 -0
- data/lib/trace_visualization/visualization/console_color_print.rb +32 -0
- data/lib/trace_visualization.rb +10 -0
- data/spec/bwt_spec.rb +47 -0
- data/spec/generators_spec.rb +30 -0
- data/spec/longest_common_prefix_spec.rb +29 -0
- data/spec/mapping_spec.rb +67 -0
- data/spec/reorder_spec.rb +42 -0
- data/spec/repetitions_concatenation_spec.rb +58 -0
- data/spec/repetitions_incrementation_spec.rb +88 -0
- data/spec/repetitions_psy_spec.rb +39 -0
- data/spec/repetitions_spec.rb +18 -0
- data/spec/spec_helper.rb +19 -0
- data/spec/suffix_array_spec.rb +68 -0
- data/trace_visualization.gemspec +35 -0
- metadata +204 -0
@@ -0,0 +1,203 @@
|
|
1
|
+
module TraceVisualization
|
2
|
+
module SuffixArray
|
3
|
+
def self.naive(str)
|
4
|
+
n = str.length
|
5
|
+
|
6
|
+
tmp = Array.new(n)
|
7
|
+
result = Array.new(n)
|
8
|
+
|
9
|
+
for i in 0 ... n
|
10
|
+
tmp[i] = [str[i .. -1], i]
|
11
|
+
end
|
12
|
+
|
13
|
+
tmp.sort! { |x, y| x[0] <=> y[0] }
|
14
|
+
|
15
|
+
for i in 0 ... n
|
16
|
+
result[i] = tmp[i][1]
|
17
|
+
end
|
18
|
+
|
19
|
+
result
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.effective(str)
|
23
|
+
n = str.length
|
24
|
+
s = []
|
25
|
+
|
26
|
+
if str.instance_of? String
|
27
|
+
str.each_char { |c| s << c.ord }
|
28
|
+
elsif str.instance_of? Array
|
29
|
+
str.each { |c| s << c.ord }
|
30
|
+
end
|
31
|
+
|
32
|
+
3.times { s << 0 }
|
33
|
+
|
34
|
+
suffix_array = Array.new(n + 3, 0)
|
35
|
+
|
36
|
+
effective_linear(s, suffix_array, n, s.max + 1)
|
37
|
+
|
38
|
+
suffix_array[0 ... -3]
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find the suffix array SA.
|
42
|
+
# Used approach from article "Linear Work Suffix Array Construction"
|
43
|
+
# by Juha Karkkainen, Peter Sanders and Stefan Burkhardt
|
44
|
+
def self.effective_linear(s, suffix_array, n, alphabet_size)
|
45
|
+
n0 = (n + 2) / 3
|
46
|
+
n1 = (n + 1) / 3
|
47
|
+
n2 = n / 3
|
48
|
+
n02 = n0 + n2
|
49
|
+
|
50
|
+
s12 = Array.new(n02 + 3, 0)
|
51
|
+
sa12 = Array.new(n02 + 3, 0)
|
52
|
+
s0 = Array.new(n0, 0)
|
53
|
+
sa0 = Array.new(n0, 0)
|
54
|
+
|
55
|
+
# Generate positions of mod 1 and mod 2 suffixes
|
56
|
+
# the "+(n0-n1)" adds a dummy mod 1 suffix if n%3 == 1
|
57
|
+
i = j = 0
|
58
|
+
while (i < n + (n0 - n1))
|
59
|
+
if i % 3 != 0
|
60
|
+
s12[j] = i
|
61
|
+
j += 1
|
62
|
+
end
|
63
|
+
i += 1
|
64
|
+
end
|
65
|
+
|
66
|
+
# LSB radix sort the mod 1 and mod 2 triples
|
67
|
+
radix_pass(s12, sa12, s[2 ... s.length], n02, alphabet_size)
|
68
|
+
radix_pass(sa12, s12, s[1 ... s.length], n02, alphabet_size)
|
69
|
+
radix_pass(s12, sa12, s, n02, alphabet_size)
|
70
|
+
|
71
|
+
# Find lexicographic names of triples
|
72
|
+
name, c0, c1, c2 = 0, -1, -1, -1
|
73
|
+
for i in 0 ... n02
|
74
|
+
if (s[sa12[i]] != c0 || s[sa12[i] + 1] != c1 || s[sa12[i] + 2] != c2)
|
75
|
+
name += 1
|
76
|
+
c0 = s[sa12[i]]
|
77
|
+
c1 = s[sa12[i] + 1]
|
78
|
+
c2 = s[sa12[i] + 2]
|
79
|
+
end
|
80
|
+
|
81
|
+
if (sa12[i] % 3 == 1)
|
82
|
+
s12[sa12[i]/3] = name # Left half
|
83
|
+
else
|
84
|
+
s12[sa12[i]/3 + n0] = name # Right half
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Recurse if names are not yet unique
|
89
|
+
if name < n02
|
90
|
+
effective_linear(s12, sa12, n02, name)
|
91
|
+
|
92
|
+
# Store unique names in s12 using the suffix array
|
93
|
+
for i in 0 ... n02
|
94
|
+
s12[sa12[i]] = i + 1
|
95
|
+
end
|
96
|
+
else
|
97
|
+
# Generate the suffix array of s12 directly
|
98
|
+
for i in 0 ... n02
|
99
|
+
sa12[s12[i] - 1] = i
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Stably sort the mod 0 suffixes from sa12 by their first character
|
104
|
+
i, j = 0, 0
|
105
|
+
while i < n02
|
106
|
+
if sa12[i] < n0
|
107
|
+
s0[j] = 3 * sa12[i]
|
108
|
+
j += 1
|
109
|
+
end
|
110
|
+
i += 1
|
111
|
+
end
|
112
|
+
radix_pass(s0, sa0, s, n0, alphabet_size)
|
113
|
+
|
114
|
+
# Merge sorted sa0 suffixes and sorted sa12 suffixes
|
115
|
+
p, t, k = 0, n0 - n1, 0
|
116
|
+
|
117
|
+
while k < n
|
118
|
+
# Pos of current offset 12 suffix
|
119
|
+
i = get_i(n0, sa12, t)
|
120
|
+
|
121
|
+
# Pos of current offset 0 suffix
|
122
|
+
j = sa0[p]
|
123
|
+
|
124
|
+
# Different compares for mod 1 and mod 2 suffixes
|
125
|
+
if (sa12[t] < n0 ? leq_pairs(s[i], s12[sa12[t] + n0], s[j], s12[j/3]) : leq_triples(s[i], s[i + 1], s12[sa12[t] - n0 + 1], s[j], s[j + 1], s12[j/3 + n0]))
|
126
|
+
suffix_array[k] = i
|
127
|
+
t += 1
|
128
|
+
if t == n02
|
129
|
+
# Done: only sa0 suffixes left
|
130
|
+
k += 1
|
131
|
+
while p < n0
|
132
|
+
suffix_array[k] = sa0[p]
|
133
|
+
p += 1
|
134
|
+
k += 1
|
135
|
+
end
|
136
|
+
end
|
137
|
+
else
|
138
|
+
suffix_array[k] = j
|
139
|
+
p += 1;
|
140
|
+
if p == n0
|
141
|
+
# Done: only sa12 suffixes left
|
142
|
+
k += 1
|
143
|
+
while t < n02
|
144
|
+
suffix_array[k] = get_i(n0, sa12, t)
|
145
|
+
t += 1
|
146
|
+
k += 1
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
k += 1
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
private
|
157
|
+
|
158
|
+
# Stably sort a[0 .. n - 1] to b[0 .. n - 1] with keys in 0 .. K from r
|
159
|
+
# Params:
|
160
|
+
# +a+:: positions in r for sort
|
161
|
+
# +b+:: sorted positions in r
|
162
|
+
# +r+:: source
|
163
|
+
# +n+:: number of positions in a and b
|
164
|
+
# +k+:: size of alphabet
|
165
|
+
def self.radix_pass(a, b, r, n, k)
|
166
|
+
c = Array.new(k + 1, 0)
|
167
|
+
|
168
|
+
# Count occurrences
|
169
|
+
for i in 0 ... n
|
170
|
+
c[r[a[i]]] += 1
|
171
|
+
end
|
172
|
+
|
173
|
+
# Exclusive prefix sums
|
174
|
+
sum = 0
|
175
|
+
for i in 0 .. k
|
176
|
+
t = c[i]
|
177
|
+
c[i] = sum
|
178
|
+
sum += t
|
179
|
+
end
|
180
|
+
|
181
|
+
# Sort
|
182
|
+
for i in 0 ... n
|
183
|
+
b[c[r[a[i]]]] = a[i]
|
184
|
+
c[r[a[i]]] += 1
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def self.get_i(n0, sa12, t)
|
189
|
+
sa12[t] < n0 ? sa12[t] * 3 + 1 : (sa12[t] - n0) * 3 + 2
|
190
|
+
end
|
191
|
+
|
192
|
+
# Lexicographic order for pairs
|
193
|
+
def self.leq_pairs(a1, a2, b1, b2)
|
194
|
+
a1 < b1 || a1 == b1 && a2 <= b2
|
195
|
+
end
|
196
|
+
|
197
|
+
# Lexicographic order for triples
|
198
|
+
def self.leq_triples(a1, a2, a3, b1, b2, b3)
|
199
|
+
a1 < b1 || a1 == b1 && leq_pairs(a2, a3, b2, b3)
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module TraceVisualization
|
2
|
+
module Utils
|
3
|
+
|
4
|
+
def self.rhash(lp, rp)
|
5
|
+
lp.hash + rp.hash
|
6
|
+
end
|
7
|
+
|
8
|
+
# Get the start position of lines
|
9
|
+
def self.lines_pos(str)
|
10
|
+
lines_pos = [0]
|
11
|
+
pos = -1
|
12
|
+
|
13
|
+
while (pos = str.index(/\n/, pos + 1))
|
14
|
+
lines_pos << pos + 1 if pos + 1 < str.length
|
15
|
+
end
|
16
|
+
|
17
|
+
lines_pos
|
18
|
+
end
|
19
|
+
|
20
|
+
# Repetitions by line
|
21
|
+
def self.rs_by_line(rs, lines_pos, rs_by_line)
|
22
|
+
for r in rs
|
23
|
+
r_pos = r.left_positions
|
24
|
+
r.lines = []
|
25
|
+
i, j = 0, 0
|
26
|
+
|
27
|
+
while (i < lines_pos.size && j < r_pos.size)
|
28
|
+
a, b = lines_pos[i], (i + 1 < lines_pos.size ? lines_pos[i + 1] : 2**32)
|
29
|
+
|
30
|
+
if a <= r_pos[j] && r_pos[j] < b
|
31
|
+
rs_by_line[i] << [r, r_pos[j]]
|
32
|
+
r.lines << i
|
33
|
+
|
34
|
+
j += 1
|
35
|
+
else
|
36
|
+
i += 1
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
rs_by_line.each { |item| item.sort! { |a, b| a[1] <=> b[1] } }
|
42
|
+
|
43
|
+
rs_by_line
|
44
|
+
end
|
45
|
+
|
46
|
+
end # module Utils
|
47
|
+
end # module TraceVisualization
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'travis/data/repetition'
|
2
|
+
|
3
|
+
module Travis
|
4
|
+
module Visualization
|
5
|
+
module ConsoleColorPrint
|
6
|
+
|
7
|
+
GRN = "\033[1;32m"
|
8
|
+
YLW = "\033[1;33m"
|
9
|
+
FNSH = "\033[0m"
|
10
|
+
|
11
|
+
def self.hl(str, repetition)
|
12
|
+
result = ""
|
13
|
+
prev_position = 0
|
14
|
+
positions = repetition.build_positions
|
15
|
+
|
16
|
+
positions.each do |position|
|
17
|
+
result += str[prev_position ... position[0][0]]
|
18
|
+
|
19
|
+
for i in 0 ... position.size
|
20
|
+
pos, len = position[i]
|
21
|
+
result += GRN + "#{str[pos ... pos + len]}" + FNSH
|
22
|
+
result += YLW + "#{str[pos + len ... position[i + 1][0]]}" + FNSH if i < position.size - 1
|
23
|
+
end
|
24
|
+
|
25
|
+
prev_position = position[-1][0] + position[-1][1]
|
26
|
+
end
|
27
|
+
|
28
|
+
result += str[prev_position .. -1]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/spec/bwt_spec.rb
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'trace_visualization'
|
2
|
+
require 'trace_visualization/bwt'
|
3
|
+
require 'trace_visualization/mapping'
|
4
|
+
require 'trace_visualization/suffix_array'
|
5
|
+
|
6
|
+
describe TraceVisualization::BurrowsWheelerTransform do
|
7
|
+
it "naive approach" do
|
8
|
+
str = "^BANANA|"
|
9
|
+
|
10
|
+
bwt = TraceVisualization::BurrowsWheelerTransform.naive(str)
|
11
|
+
|
12
|
+
bwt.should eq ["B", "N", "N", "^", "A", "A", "|", "A"]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "effective implementation" do
|
16
|
+
str = "abaababa"
|
17
|
+
|
18
|
+
bwt = TraceVisualization::BurrowsWheelerTransform.bwt(str, TraceVisualization::SuffixArray.effective(str), str.length)
|
19
|
+
bwt.should eq ["b", "b", "b", "a", "a", "a", "a", "a"]
|
20
|
+
|
21
|
+
|
22
|
+
10.times do
|
23
|
+
rnd_str = (0 ... 60).map { (65 + rand(26)).chr }.join + TraceVisualization::TERMINATION_CHAR
|
24
|
+
|
25
|
+
sa_naive = TraceVisualization::SuffixArray.naive(rnd_str)
|
26
|
+
sa_effective = TraceVisualization::SuffixArray.effective(rnd_str)
|
27
|
+
sa_effective.should eq sa_naive
|
28
|
+
|
29
|
+
bwt_naive = TraceVisualization::BurrowsWheelerTransform.naive(rnd_str)
|
30
|
+
bwt_effective = TraceVisualization::BurrowsWheelerTransform.bwt(rnd_str, TraceVisualization::SuffixArray.effective(rnd_str), rnd_str.length)
|
31
|
+
|
32
|
+
bwt_effective.should eq bwt_naive
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "test with mapping" do
|
37
|
+
str = "127.0.0.1 a 127.0.0.1 b"
|
38
|
+
arr = TraceVisualization::Mapping.parse(str)
|
39
|
+
ip, ws, a, b = arr[0], arr[1], arr[2], arr[6]
|
40
|
+
|
41
|
+
bwt = TraceVisualization::BurrowsWheelerTransform.bwt(arr, TraceVisualization::SuffixArray.effective(arr), arr.length)
|
42
|
+
bwt_str = TraceVisualization::Mapping.restore(bwt)
|
43
|
+
|
44
|
+
bwt.should eq [ip, ip, a, ws, ws, b, ws]
|
45
|
+
bwt_str.should eq "127.0.0.1127.0.0.1a b "
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'trace_visualization/generators'
|
2
|
+
|
3
|
+
describe TraceVisualization::Generators do
|
4
|
+
describe TraceVisualization::Generators::Thue do
|
5
|
+
it "thue_2_3" do
|
6
|
+
TraceVisualization::Generators::Thue.str_2_3(0).should eq "a"
|
7
|
+
TraceVisualization::Generators::Thue.str_2_3(1).should eq "ab"
|
8
|
+
TraceVisualization::Generators::Thue.str_2_3(2).should eq "abba"
|
9
|
+
TraceVisualization::Generators::Thue.str_2_3(3).should eq "abbabaab"
|
10
|
+
TraceVisualization::Generators::Thue.str_2_3(4).should eq "abbabaabbaababba"
|
11
|
+
TraceVisualization::Generators::Thue.str_2_3(5).should eq "abbabaabbaababbabaababbaabbabaab"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "thue_3_2" do
|
15
|
+
TraceVisualization::Generators::Thue.str_3_2(0).should eq "a"
|
16
|
+
TraceVisualization::Generators::Thue.str_3_2(1).should eq "abcab"
|
17
|
+
TraceVisualization::Generators::Thue.str_3_2(2).should eq "abcabacabcbacbcacbabcabacabcb"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "fibonacci" do
|
21
|
+
TraceVisualization::Generators::Fibonacci.str(0).should eq "b"
|
22
|
+
TraceVisualization::Generators::Fibonacci.str(1).should eq "a"
|
23
|
+
TraceVisualization::Generators::Fibonacci.str(2).should eq "ab"
|
24
|
+
TraceVisualization::Generators::Fibonacci.str(3).should eq "aba"
|
25
|
+
TraceVisualization::Generators::Fibonacci.str(4).should eq "abaab"
|
26
|
+
TraceVisualization::Generators::Fibonacci.str(5).should eq "abaababa"
|
27
|
+
TraceVisualization::Generators::Fibonacci.str(6).should eq "abaababaabaab"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'trace_visualization/longest_common_prefix'
|
2
|
+
require 'trace_visualization/suffix_array'
|
3
|
+
require 'trace_visualization/mapping'
|
4
|
+
|
5
|
+
describe TraceVisualization::LongestCommonPrefix do
|
6
|
+
|
7
|
+
context '.effective' do
|
8
|
+
it 'should return array with longest common prefix in linear time' do
|
9
|
+
str = "mississippi"
|
10
|
+
|
11
|
+
sa = TraceVisualization::SuffixArray.effective(str)
|
12
|
+
lcp = TraceVisualization::LongestCommonPrefix.effective(str, sa, str.size)
|
13
|
+
|
14
|
+
lcp.should eq([0, 1, 1, 4, 0, 0, 1, 0, 2, 1, 3])
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should return correct result for mapped string', :current => true do
|
18
|
+
str = "127.0.0.1 foo\r\n127.0.0.1 bar"
|
19
|
+
arr = TraceVisualization::Mapping.parse(str)
|
20
|
+
|
21
|
+
sa = TraceVisualization::SuffixArray.effective(arr)
|
22
|
+
lcp = TraceVisualization::LongestCommonPrefix.effective(arr, sa, arr.size)
|
23
|
+
|
24
|
+
sa.should eq([6, 5, 8, 1, 10, 9, 2, 4, 3, 11, 7, 0])
|
25
|
+
lcp.should eq([0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'trace_visualization/mapping'
|
2
|
+
|
3
|
+
describe TraceVisualization::Mapping do
|
4
|
+
it "simple id values" do
|
5
|
+
str = "foo[1234]bar[1235]far[1234]"
|
6
|
+
|
7
|
+
arr = TraceVisualization::Mapping.parse(str)
|
8
|
+
|
9
|
+
arr.size.should eq(12)
|
10
|
+
|
11
|
+
|
12
|
+
ids = arr.find_all { |item| item.type == "id" }
|
13
|
+
ids.size.should eq(3)
|
14
|
+
ids[0].src.should eq("[1234]")
|
15
|
+
ids[1].src.should eq("[1235]")
|
16
|
+
ids[2].src.should eq("[1234]")
|
17
|
+
ids[0].should eq(ids[2])
|
18
|
+
|
19
|
+
str2 = TraceVisualization::Mapping.restore(arr)
|
20
|
+
str2.should eq(str)
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
it "ip values" do
|
25
|
+
str = "user1 ip : 127.0.0.1 \r\nuser2 ip : 127.0.0.2"
|
26
|
+
|
27
|
+
arr = TraceVisualization::Mapping.parse(str)
|
28
|
+
arr.size.should eq(27)
|
29
|
+
|
30
|
+
ips = arr.find_all { |item| item.type == "ip" }
|
31
|
+
ips.size.should eq(2)
|
32
|
+
ips[0].src.should eq("127.0.0.1")
|
33
|
+
ips[1].src.should eq("127.0.0.2")
|
34
|
+
|
35
|
+
str2 = TraceVisualization::Mapping.restore(arr)
|
36
|
+
str2.should eq(str)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "compare different types" do
|
40
|
+
# Ids
|
41
|
+
id_1 = TraceVisualization::Mapping::Item.new("[12345678]", "id")
|
42
|
+
id_2 = TraceVisualization::Mapping::Item.new("[12345679]", "id")
|
43
|
+
TraceVisualization::Reorder.process([id_1, id_2])
|
44
|
+
|
45
|
+
id_1.should be < id_2
|
46
|
+
|
47
|
+
# IPs
|
48
|
+
ip_1 = TraceVisualization::Mapping::Item.new("127.0.0.1", "ip")
|
49
|
+
ip_2 = TraceVisualization::Mapping::Item.new("127.0.0.2", "ip")
|
50
|
+
TraceVisualization::Reorder.process([ip_1, ip_2])
|
51
|
+
|
52
|
+
ip_1.should be < ip_2
|
53
|
+
|
54
|
+
# Time
|
55
|
+
time_1 = TraceVisualization::Mapping::Item.new("[16 Jan 2013 00:10:00]", "time")
|
56
|
+
time_2 = TraceVisualization::Mapping::Item.new("[16 Jan 2013 00:10:01]", "time")
|
57
|
+
TraceVisualization::Reorder.process([time_1, time_2])
|
58
|
+
|
59
|
+
# Different
|
60
|
+
TraceVisualization::Reorder.process([time_1, time_2, id_1, ip_1])
|
61
|
+
|
62
|
+
time_1.should be < time_2
|
63
|
+
id_1.should be < ip_1
|
64
|
+
id_1.should be < time_1
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'trace_visualization/reorder'
|
2
|
+
|
3
|
+
describe TraceVisualization::Reorder do
|
4
|
+
|
5
|
+
class A
|
6
|
+
include Comparable
|
7
|
+
|
8
|
+
attr_accessor :ord
|
9
|
+
attr_accessor :value
|
10
|
+
|
11
|
+
def initialize(theValue)
|
12
|
+
@value = theValue
|
13
|
+
end
|
14
|
+
|
15
|
+
def <=>(anOther)
|
16
|
+
@value <=> anOther.value
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it "reorder values and set correct order" do
|
21
|
+
data = Array.new(100) { |index| A.new(index * 100) }
|
22
|
+
data.shuffle!
|
23
|
+
|
24
|
+
TraceVisualization::Reorder.process(data)
|
25
|
+
|
26
|
+
data.each { |item| item.ord.should eq(item.value / 100 + 1) }
|
27
|
+
end
|
28
|
+
|
29
|
+
it "duplicate values with the same order", :current => true do
|
30
|
+
x1, x2 = A.new(1), A.new(2)
|
31
|
+
x3, x4 = A.new(123456789), A.new(123456789)
|
32
|
+
|
33
|
+
data = [x1, x2, x3, x4].shuffle
|
34
|
+
|
35
|
+
TraceVisualization::Reorder.process(data)
|
36
|
+
|
37
|
+
x1.ord.should eq(1)
|
38
|
+
x2.ord.should eq(2)
|
39
|
+
x3.ord.should eq(3)
|
40
|
+
x4.ord.should eq(3)
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'trace_visualization/repetitions_concatenation'
|
2
|
+
require 'trace_visualization/repetitions_context'
|
3
|
+
require 'trace_visualization/data/repetition'
|
4
|
+
|
5
|
+
describe TraceVisualization::RepetitionsConcatenation do
|
6
|
+
it "process common positions" do
|
7
|
+
str = "aaaxbbbyaaazbbbvaaawbbb"
|
8
|
+
|
9
|
+
context = TraceVisualization::Repetitions::Context.new(str, [])
|
10
|
+
|
11
|
+
lpos = [0, 8, 16]
|
12
|
+
rpos = [4, 12, 20]
|
13
|
+
ppos = [[0, 4], [8, 12], [16, 20]]
|
14
|
+
|
15
|
+
left = TraceVisualization::Data::Repetition.new(3, lpos)
|
16
|
+
right = TraceVisualization::Data::Repetition.new(3, rpos)
|
17
|
+
|
18
|
+
cpl, cpr = TraceVisualization::RepetitionsConcatenation.process_common_positions(left, right, 1, context)
|
19
|
+
|
20
|
+
left.left_positions.should eq cpl
|
21
|
+
right.left_positions.should eq cpr
|
22
|
+
|
23
|
+
lpos.should eq left.left_positions
|
24
|
+
rpos.should eq right.left_positions
|
25
|
+
end
|
26
|
+
|
27
|
+
it "don't concatenate repetitions through forbidden chars" do
|
28
|
+
str = <<EOF
|
29
|
+
aaa
|
30
|
+
bbb
|
31
|
+
aaa
|
32
|
+
bbb
|
33
|
+
EOF
|
34
|
+
context = TraceVisualization::Repetitions::Context.new(str, [])
|
35
|
+
|
36
|
+
lpos, rpos = [0, 8], [4, 12]
|
37
|
+
left = TraceVisualization::Data::Repetition.new(3, lpos)
|
38
|
+
right = TraceVisualization::Data::Repetition.new(3, rpos)
|
39
|
+
|
40
|
+
cpl, cpr = TraceVisualization::RepetitionsConcatenation.process_common_positions(left, right, 1, context)
|
41
|
+
|
42
|
+
cpl.should eq []
|
43
|
+
cpr.should eq []
|
44
|
+
|
45
|
+
#
|
46
|
+
str.gsub!(TraceVisualization::FORBIDDEN_CHARS, "x")
|
47
|
+
context = TraceVisualization::Repetitions::Context.new(str, [])
|
48
|
+
|
49
|
+
lpos, rpos = [0, 8], [4, 12]
|
50
|
+
left = TraceVisualization::Data::Repetition.new(3, lpos)
|
51
|
+
right = TraceVisualization::Data::Repetition.new(3, rpos)
|
52
|
+
|
53
|
+
cpl, cpr = TraceVisualization::RepetitionsConcatenation.process_common_positions(left, right, 1, context)
|
54
|
+
|
55
|
+
cpl.should eq [0, 8]
|
56
|
+
cpr.should eq [4, 12]
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require 'trace_visualization/repetitions_incrementation'
|
2
|
+
require 'trace_visualization/data/repetition'
|
3
|
+
|
4
|
+
describe TraceVisualization::RepetitionsIncrementation do
|
5
|
+
it "simple incrementation" do
|
6
|
+
str = <<EOF
|
7
|
+
foo 12
|
8
|
+
foo 13
|
9
|
+
foo 12
|
10
|
+
foo 13
|
11
|
+
foo 12
|
12
|
+
foo 13
|
13
|
+
EOF
|
14
|
+
|
15
|
+
hashes = []
|
16
|
+
|
17
|
+
r1 = TraceVisualization::Data::Repetition.new(5, [0, 7, 14, 21, 28, 35])
|
18
|
+
r12 = TraceVisualization::Data::Repetition.new(6, [0, 14, 28])
|
19
|
+
r13 = TraceVisualization::Data::Repetition.new(6, [7, 21, 35])
|
20
|
+
|
21
|
+
repetitions = [r1, r12, r13]
|
22
|
+
|
23
|
+
TraceVisualization::RepetitionsIncrementation.incrementation(str, repetitions, hashes, 1)
|
24
|
+
|
25
|
+
repetition = repetitions[-1]
|
26
|
+
|
27
|
+
repetitions.size.should eq 4
|
28
|
+
repetition.length.should eq 6
|
29
|
+
repetition.k.should eq 1
|
30
|
+
|
31
|
+
repetition.left_positions.should eq [0, 7, 14, 21, 28, 35]
|
32
|
+
repetition.right_positions.should eq [6, 13, 20, 27, 34, 41]
|
33
|
+
end
|
34
|
+
|
35
|
+
it "left incrementation" do
|
36
|
+
str = <<EOF
|
37
|
+
12_foo
|
38
|
+
14_foo
|
39
|
+
22_foo
|
40
|
+
24_foo
|
41
|
+
30_bar
|
42
|
+
32_foo
|
43
|
+
34_foo
|
44
|
+
EOF
|
45
|
+
|
46
|
+
hashes = []
|
47
|
+
|
48
|
+
r1 = TraceVisualization::Data::Repetition.new(4, [2, 9, 16, 23, 37, 44])
|
49
|
+
r2 = TraceVisualization::Data::Repetition.new(5, [1, 15, 36])
|
50
|
+
r3 = TraceVisualization::Data::Repetition.new(5, [8, 22, 43])
|
51
|
+
|
52
|
+
repetitions = [r1, r2, r3]
|
53
|
+
|
54
|
+
TraceVisualization::RepetitionsIncrementation.incrementation(str, repetitions, hashes, 1)
|
55
|
+
|
56
|
+
repetition = repetitions[-1]
|
57
|
+
|
58
|
+
repetitions.size.should eq 4
|
59
|
+
repetition.k.should eq 1
|
60
|
+
repetition.length.should eq 5
|
61
|
+
|
62
|
+
repetition.left_positions.should eq [1, 8, 15, 22, 36, 43]
|
63
|
+
repetition.right_positions.should eq [2, 9, 16, 23, 37, 44]
|
64
|
+
end
|
65
|
+
|
66
|
+
it "test fake repetition" do
|
67
|
+
str = <<EOF
|
68
|
+
abcde11edcb
|
69
|
+
abcde22bcde
|
70
|
+
EOF
|
71
|
+
|
72
|
+
left = TraceVisualization::Data::Repetition.new(5, [0, 12])
|
73
|
+
right = TraceVisualization::Data::Repetition.new(0, [7, 19])
|
74
|
+
|
75
|
+
repetition = TraceVisualization::Data::Repetition.new(7, [0, 12], [7, 19])
|
76
|
+
repetition.left = left
|
77
|
+
repetition.right = right
|
78
|
+
repetition.k = 2
|
79
|
+
|
80
|
+
fake = TraceVisualization::RepetitionsIncrementation.fake_repetition(
|
81
|
+
repetition.class, repetition.left_positions, repetition.right_positions,
|
82
|
+
"right"
|
83
|
+
)
|
84
|
+
|
85
|
+
right.left_positions.should eq fake.left_positions
|
86
|
+
right.right_positions.should eq fake.right_positions
|
87
|
+
end
|
88
|
+
end
|