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.
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