trace_visualization 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +6 -0
  4. data/LICENSE +339 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +4 -0
  7. data/Rakefile +1 -0
  8. data/lib/trace_visualization/bwt.rb +32 -0
  9. data/lib/trace_visualization/bwt.rbold +32 -0
  10. data/lib/trace_visualization/data/irepetition.rb +49 -0
  11. data/lib/trace_visualization/data/repetition.rb +101 -0
  12. data/lib/trace_visualization/generators.rb +53 -0
  13. data/lib/trace_visualization/longest_common_prefix.rb +34 -0
  14. data/lib/trace_visualization/mapping.rb +120 -0
  15. data/lib/trace_visualization/reorder.rb +25 -0
  16. data/lib/trace_visualization/repetitions.rb +66 -0
  17. data/lib/trace_visualization/repetitions_concatenation.rb +134 -0
  18. data/lib/trace_visualization/repetitions_context.rb +18 -0
  19. data/lib/trace_visualization/repetitions_incrementation.rb +81 -0
  20. data/lib/trace_visualization/repetitions_psy.rb +83 -0
  21. data/lib/trace_visualization/suffix_array.rb +203 -0
  22. data/lib/trace_visualization/utils.rb +47 -0
  23. data/lib/trace_visualization/version.rb +3 -0
  24. data/lib/trace_visualization/visualization/console_color_print.rb +32 -0
  25. data/lib/trace_visualization.rb +10 -0
  26. data/spec/bwt_spec.rb +47 -0
  27. data/spec/generators_spec.rb +30 -0
  28. data/spec/longest_common_prefix_spec.rb +29 -0
  29. data/spec/mapping_spec.rb +67 -0
  30. data/spec/reorder_spec.rb +42 -0
  31. data/spec/repetitions_concatenation_spec.rb +58 -0
  32. data/spec/repetitions_incrementation_spec.rb +88 -0
  33. data/spec/repetitions_psy_spec.rb +39 -0
  34. data/spec/repetitions_spec.rb +18 -0
  35. data/spec/spec_helper.rb +19 -0
  36. data/spec/suffix_array_spec.rb +68 -0
  37. data/trace_visualization.gemspec +35 -0
  38. 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,3 @@
1
+ module TraceVisualization
2
+ VERSION = "0.0.1"
3
+ end
@@ -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
@@ -0,0 +1,10 @@
1
+ require "trace_visualization/version"
2
+
3
+ module TraceVisualization
4
+
5
+ # Should be 'greater' of all possible chars in the lexicographical order
6
+ TERMINATION_CHAR = '$'
7
+
8
+ FORBIDDEN_CHARS = /\n/
9
+
10
+ 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