trace_visualization 0.0.2 → 0.0.3
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 +4 -4
- data/Gemfile +2 -0
- data/Rakefile +4 -4
- data/bin/trace_visualization +133 -0
- data/lib/trace_visualization.rb +6 -0
- data/lib/trace_visualization/mapping.rb +61 -42
- data/lib/trace_visualization/reorder.rb +2 -0
- data/lib/trace_visualization/repetitions_score.rb +87 -0
- data/lib/trace_visualization/utils.rb +1 -1
- data/lib/trace_visualization/version.rb +1 -1
- data/lib/trace_visualization/visualization/console_color_print.rb +8 -8
- data/spec/bwt_spec.rb +3 -5
- data/spec/longest_common_prefix_spec.rb +11 -4
- data/spec/repetitions_concatenation_spec.rb +8 -2
- data/spec/repetitions_psy_spec.rb +23 -10
- data/spec/suffix_array_spec.rb +64 -37
- data/trace_visualization.gemspec +14 -14
- metadata +6 -15
- data/lib/trace_visualization/preprocessor/Makefile +0 -43
- data/lib/trace_visualization/preprocessor/hashmap.c +0 -93
- data/lib/trace_visualization/preprocessor/hashmap.h +0 -27
- data/lib/trace_visualization/preprocessor/hashmap_test.cpp +0 -90
- data/lib/trace_visualization/preprocessor/lexeme.h +0 -11
- data/lib/trace_visualization/preprocessor/lexeme_table.c +0 -50
- data/lib/trace_visualization/preprocessor/lexeme_table.h +0 -13
- data/lib/trace_visualization/preprocessor/lexeme_table_cpp.h +0 -61
- data/lib/trace_visualization/preprocessor/parser_functions.c +0 -42
- data/lib/trace_visualization/preprocessor/parser_test.cpp +0 -71
- data/lib/trace_visualization/preprocessor/preprocessor.l +0 -18
- data/lib/trace_visualization/preprocessor/test_main.cpp +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 12c27504ea6bbbabd78f47e5bee3df251a5a7050
|
4
|
+
data.tar.gz: 75a0bf55e52a108f449def1998de4fbf319d1f94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6fff098106b2ba908595a05345bebafc5686348454061983671c937c21a26ecb0cee59a8d6209203707949e7283daba5d620b7d386cd1ac230e021668f4a7f5
|
7
|
+
data.tar.gz: 6e39264b5f0141746d7fda75d4c2c2be624a0829c12ed548160e6bd9f74afac162b06a6e9e670155ef042f7b7baf65eb0bff43a42236051f0aec81b15842495c
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require 'bundler/gem_tasks'
|
2
2
|
|
3
|
-
desc 'Compile preprocessor'
|
4
|
-
task :install do
|
5
|
-
system('cd
|
6
|
-
end
|
3
|
+
#desc 'Compile preprocessor'
|
4
|
+
#task :install do
|
5
|
+
# system('cd ext/preprocessor; make install')
|
6
|
+
#end
|
7
7
|
|
8
8
|
desc 'Spec all functionality of gem'
|
9
9
|
task :spec_all do
|
@@ -0,0 +1,133 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'trace_visualization'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'benchmark'
|
6
|
+
require 'optparse'
|
7
|
+
|
8
|
+
include TraceVisualization
|
9
|
+
|
10
|
+
##
|
11
|
+
# Parse command line options
|
12
|
+
def parse_options
|
13
|
+
options = {}
|
14
|
+
|
15
|
+
optionParser = OptionParser.new do|opts|
|
16
|
+
opts.banner = "Usage: trace_visualization [options] file"
|
17
|
+
|
18
|
+
options[:offset] = 0
|
19
|
+
opts.on('-x', '--offset N', 'Number of lines for offset. Default 0') do |n|
|
20
|
+
options[:offset] = n.to_i
|
21
|
+
end
|
22
|
+
|
23
|
+
options[:limit] = 2**32
|
24
|
+
opts.on('-l', '--limit N', "Number of lines. Default #{options[:limit]}") do |n|
|
25
|
+
options[:limit] = n.to_i
|
26
|
+
end
|
27
|
+
|
28
|
+
options[:out] = 3
|
29
|
+
opts.on('-o', '--out N', 'Number of output results') do |n|
|
30
|
+
options[:out] = n.to_i
|
31
|
+
end
|
32
|
+
|
33
|
+
options[:positions_min_size] = 3
|
34
|
+
opts.on('-m', '--positions_min_size N', "The minimum number of repetition positions. Default #{options[:positions_min_size]}") do |s|
|
35
|
+
options[:positions_min_size] = s.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
options[:test_preprocessor_performance] = false
|
39
|
+
opts.on('-t', '--test_preprocessor_performance', 'Test preprocessor performance') do
|
40
|
+
options[:test_preprocessor_performance] = true
|
41
|
+
end
|
42
|
+
|
43
|
+
opts.on('-h', '--help', 'Display this screen') do
|
44
|
+
puts opts
|
45
|
+
exit
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
optionParser.parse!
|
50
|
+
|
51
|
+
options[:source_file_name] = ARGV[0]
|
52
|
+
|
53
|
+
options
|
54
|
+
end
|
55
|
+
|
56
|
+
#------------------------------------------------------------------------------
|
57
|
+
def foo(options)
|
58
|
+
|
59
|
+
preprocessorConfig = TracePreprocessor.init do
|
60
|
+
use_default_lexemes
|
61
|
+
|
62
|
+
output_token "printf(\"{TOKEN;%s;%s;%ld;%d}\", name, source, value, value_kind);"
|
63
|
+
end
|
64
|
+
|
65
|
+
preprocessor = nil
|
66
|
+
bm('Preprocessor Generate') do
|
67
|
+
preprocessor = TracePreprocessor.generate(preprocessorConfig, :c)
|
68
|
+
end
|
69
|
+
|
70
|
+
tmp_file = Tempfile.new('trace_visualization')
|
71
|
+
|
72
|
+
bm('Preprocessor work') do
|
73
|
+
preprocessor.run options[:source_file_name], tmp_file.path
|
74
|
+
end
|
75
|
+
|
76
|
+
mapping = nil
|
77
|
+
bm('Mapping') do
|
78
|
+
mapping = TraceVisualization::Mapping.new
|
79
|
+
mapping.process_without_reorder { from_preprocessed_file(tmp_file.path, options[:offset], options[:limit], !options[:test_preprocessor_performance]) }
|
80
|
+
end
|
81
|
+
|
82
|
+
source_file_length = `wc -c #{options[:source_file_name]}`.to_i
|
83
|
+
tmp_file_length = tmp_file.length
|
84
|
+
|
85
|
+
puts "source_file_length = #{source_file_length}"
|
86
|
+
puts "tmp_file_length = #{tmp_file_length} (+#{((tmp_file_length - source_file_length) * 100.0 / source_file_length).round(2)}%)"
|
87
|
+
puts "mapping_length = #{mapping.length} (-#{((source_file_length - mapping.length) * 100.0 / source_file_length).round(2)}%)"
|
88
|
+
|
89
|
+
tmp_file.close
|
90
|
+
tmp_file.unlink
|
91
|
+
|
92
|
+
if options[:test_preprocessor_performance]
|
93
|
+
puts "Finish preprocessor"
|
94
|
+
exit 0
|
95
|
+
end
|
96
|
+
|
97
|
+
rs = nil
|
98
|
+
bm('PSY1') do
|
99
|
+
rs = Repetitions.psy1(mapping, options[:positions_min_size], true)
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "rs.size = #{rs.size}"
|
103
|
+
|
104
|
+
#context = nil
|
105
|
+
#bm('Context') do
|
106
|
+
# context = TraceVisualization::Repetitions::Context.new(mapping, rs)
|
107
|
+
#end
|
108
|
+
|
109
|
+
RepetitionsScore.fill_score(rs, :sort => true, :order => 'desc', :version => 'relative')
|
110
|
+
|
111
|
+
rs[0 ... options[:out]].each do |r|
|
112
|
+
puts '---------------------'
|
113
|
+
puts r
|
114
|
+
puts Visualization::ConsoleColorPrint.hl(mapping, r)
|
115
|
+
end
|
116
|
+
|
117
|
+
rs
|
118
|
+
end
|
119
|
+
|
120
|
+
|
121
|
+
def bm(name, &block)
|
122
|
+
Benchmark.bm(17) do |x|
|
123
|
+
x.report(name, &block)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
options = parse_options
|
129
|
+
rs = foo(options)
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
data/lib/trace_visualization.rb
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
mapping
|
3
3
|
utils
|
4
4
|
version
|
5
|
+
reorder
|
6
|
+
repetitions
|
7
|
+
repetitions_psy
|
8
|
+
repetitions_context
|
9
|
+
repetitions_score
|
10
|
+
visualization/console_color_print
|
5
11
|
).each { |file| require File.join(File.dirname(__FILE__), 'trace_visualization', file) }
|
6
12
|
|
7
13
|
require 'logger'
|
@@ -58,61 +58,73 @@ module TraceVisualization
|
|
58
58
|
@max_value = TraceVisualization::Reorder.process(@mapped_str)
|
59
59
|
end
|
60
60
|
|
61
|
+
def process_without_reorder(&block)
|
62
|
+
instance_eval(&block)
|
63
|
+
end
|
64
|
+
|
65
|
+
##
|
61
66
|
# Load data from source file. File is read line by line
|
67
|
+
|
62
68
|
def from_file(path)
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
validate_file_name_argument(path)
|
70
|
+
|
71
|
+
open(path) do |fd|
|
72
|
+
while (line = fd.gets)
|
73
|
+
process_line(line)
|
74
|
+
end
|
75
|
+
end
|
70
76
|
end
|
71
77
|
|
78
|
+
##
|
72
79
|
# Load data from preprocessed file. File is read line by line
|
73
|
-
def from_preprocessed_file(path)
|
74
|
-
raise ArgumentError, 'Argument must be a string' unless path.instance_of? String
|
75
|
-
raise ArgumentError, 'File path is not defined' unless path.empty?
|
76
|
-
raise RuntimeError, 'File doesn\'t exists' unless File.exists?(path)
|
77
80
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
+
def from_preprocessed_file(path, offset, limit, use_lexeme_table = true)
|
82
|
+
validate_file_name_argument(path)
|
83
|
+
|
84
|
+
idx = 0
|
85
|
+
open(path) do |fd|
|
86
|
+
while (line = fd.gets)
|
87
|
+
process_preprocessed_line(line, use_lexeme_table) if (idx >= offset && idx < offset + limit)
|
88
|
+
|
89
|
+
idx += 1
|
90
|
+
end
|
91
|
+
end
|
81
92
|
end
|
82
93
|
|
83
94
|
# new
|
84
95
|
def from_string(str)
|
85
|
-
|
86
|
-
raise ArgumentError, 'String is not defined' if str.empty?
|
96
|
+
validate_string_argument(str)
|
87
97
|
|
88
98
|
@str = str
|
89
99
|
|
90
100
|
str.split("\n").each do |line|
|
91
101
|
process_line(line)
|
92
102
|
end
|
103
|
+
|
104
|
+
@mapped_str.pop if @mapped_str[-1].value == "\n" && str[-1] != "\n"
|
93
105
|
end
|
94
|
-
|
95
|
-
def from_preprocessed_string(str)
|
96
|
-
|
97
|
-
raise ArgumentError, 'String is not defined' if str.empty?
|
106
|
+
|
107
|
+
def from_preprocessed_string(str, use_lexeme_table = true)
|
108
|
+
validate_string_argument(str)
|
98
109
|
|
99
110
|
str.split("\n").each do |line|
|
100
111
|
process_preprocessed_line(line)
|
101
112
|
end
|
102
113
|
end
|
103
114
|
|
104
|
-
def process_preprocessed_line(line)
|
115
|
+
def process_preprocessed_line(line, use_lexeme_table = true)
|
105
116
|
lexeme_positions = []
|
106
117
|
pos = 0
|
107
118
|
while (m = LEXEME_REGEXP.match(line, pos))
|
108
119
|
pos = m.begin(0)
|
109
|
-
|
110
|
-
lexeme = install_lexeme_m(m)
|
120
|
+
|
121
|
+
lexeme = install_lexeme_m(m, use_lexeme_table)
|
111
122
|
lexeme_positions << TraceVisualization::Data::LexemePos.new(lexeme, pos)
|
112
123
|
|
113
124
|
pos += lexeme.lexeme_length
|
114
125
|
end
|
115
|
-
|
126
|
+
|
127
|
+
|
116
128
|
pos, idx = 0, 0
|
117
129
|
while pos < line.length
|
118
130
|
lexeme = nil
|
@@ -120,13 +132,13 @@ module TraceVisualization
|
|
120
132
|
lexeme = lexeme_positions[idx].lexeme
|
121
133
|
idx += 1
|
122
134
|
else
|
123
|
-
lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1)
|
135
|
+
lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1, use_lexeme_table)
|
124
136
|
end
|
125
137
|
pos += lexeme.lexeme_length
|
126
138
|
@mapped_str << lexeme
|
127
139
|
end
|
128
|
-
|
129
|
-
@mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1)
|
140
|
+
|
141
|
+
@mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1, use_lexeme_table)
|
130
142
|
end
|
131
143
|
|
132
144
|
# new
|
@@ -164,28 +176,21 @@ module TraceVisualization
|
|
164
176
|
@mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1)
|
165
177
|
end
|
166
178
|
|
167
|
-
def install_lexeme(name, lexeme_string, int_value, lexeme_length)
|
168
|
-
lexeme = @lexeme_table[lexeme_string]
|
179
|
+
def install_lexeme(name, lexeme_string, int_value, lexeme_length, use_lexeme_table = true)
|
180
|
+
lexeme = use_lexeme_table ? @lexeme_table[lexeme_string] : nil
|
169
181
|
|
170
|
-
if lexeme
|
182
|
+
if lexeme.nil?
|
171
183
|
lexeme = TraceVisualization::Data::Lexeme.new(name, lexeme_string, int_value)
|
172
184
|
lexeme.lexeme_length = lexeme_length
|
173
|
-
|
185
|
+
|
186
|
+
@lexeme_table[lexeme_string] = lexeme if use_lexeme_table
|
174
187
|
end
|
175
188
|
|
176
189
|
lexeme
|
177
190
|
end
|
178
191
|
|
179
|
-
def install_lexeme_m(m)
|
180
|
-
|
181
|
-
|
182
|
-
if lexeme == nil
|
183
|
-
lexeme = TraceVisualization::Data::Lexeme.new(m[:name], m[:source], m[:value].to_i)
|
184
|
-
lexeme.lexeme_length = m.to_s.length
|
185
|
-
@lexeme_table[m[:source]] = lexeme
|
186
|
-
end
|
187
|
-
|
188
|
-
lexeme
|
192
|
+
def install_lexeme_m(m, use_lexeme_table = true)
|
193
|
+
install_lexeme(m[:name], m[:source], m[:value].to_i, m.to_s.length, use_lexeme_table)
|
189
194
|
end
|
190
195
|
|
191
196
|
def [](index)
|
@@ -201,7 +206,9 @@ module TraceVisualization
|
|
201
206
|
end
|
202
207
|
|
203
208
|
def <<(object)
|
204
|
-
|
209
|
+
lexeme = install_lexeme('UNKNOWN', object, object.to_i, object.to_s.length)
|
210
|
+
lexeme.ord = 0 # fake ord because Reorder already processed
|
211
|
+
@mapped_str << lexeme
|
205
212
|
end
|
206
213
|
|
207
214
|
def pop
|
@@ -279,5 +286,17 @@ module TraceVisualization
|
|
279
286
|
end
|
280
287
|
|
281
288
|
end
|
289
|
+
|
290
|
+
def validate_file_name_argument(path)
|
291
|
+
raise ArgumentError, 'Argument must be a string' if not path.instance_of? String
|
292
|
+
raise ArgumentError, 'File path is not defined' if path.empty?
|
293
|
+
raise RuntimeError, 'File doesn\'t exists' if not File.exists?(path)
|
294
|
+
end
|
295
|
+
|
296
|
+
def validate_string_argument(str)
|
297
|
+
raise ArgumentError, 'Argument must be a string' unless str.instance_of? String
|
298
|
+
raise ArgumentError, 'String is not defined' if str.empty?
|
299
|
+
end
|
300
|
+
|
282
301
|
end
|
283
302
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module TraceVisualization
|
2
|
+
module RepetitionsScore
|
3
|
+
|
4
|
+
# Priority length when repetition score is calculated
|
5
|
+
ALPHA_SCORE = 0.5
|
6
|
+
|
7
|
+
# Priority positions.size when repetition score is calculated
|
8
|
+
BETA_SCORE = 1 - ALPHA_SCORE
|
9
|
+
|
10
|
+
# Options:
|
11
|
+
# *sort* true / false
|
12
|
+
# *order* order for sort (default 'asc')
|
13
|
+
# *version* version of importance function
|
14
|
+
def self.fill_score(rs, options = {})
|
15
|
+
|
16
|
+
opts = {
|
17
|
+
:sort => false,
|
18
|
+
:order => 'asc'
|
19
|
+
}.merge options
|
20
|
+
|
21
|
+
case opts[:version]
|
22
|
+
when 'relative'
|
23
|
+
function_relative(rs)
|
24
|
+
when 'linear'
|
25
|
+
function_linear(rs)
|
26
|
+
else
|
27
|
+
throw Exception.new("Unknown version")
|
28
|
+
end
|
29
|
+
|
30
|
+
if opts[:sort]
|
31
|
+
rs.sort! do |a, b|
|
32
|
+
opts[:order] == 'desc' ? b.score <=> a.score : a.score <=> b.score
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# f(len, size) = alpha * len' + beta * size'
|
38
|
+
# len', size' - relative to max values
|
39
|
+
def self.function_relative(rs)
|
40
|
+
len_max, size_max = 0, 0
|
41
|
+
|
42
|
+
rs.each do |r|
|
43
|
+
len = r.length
|
44
|
+
len_max = len if len > len_max
|
45
|
+
|
46
|
+
size = r.positions_size
|
47
|
+
size_max = size if size > size_max
|
48
|
+
end
|
49
|
+
|
50
|
+
rs.each do |r|
|
51
|
+
r.score = ALPHA_SCORE * r.strict_length / len_max +
|
52
|
+
BETA_SCORE * r.positions_size / size_max
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# f(len, size, k) = alpha * len + beta * size + gamma * k
|
57
|
+
def self.function_linear(rs)
|
58
|
+
len_max, len_min, size_max, size_min, k_max = 0, 2**32, 0, 2**32, 0
|
59
|
+
|
60
|
+
rs.each do |r|
|
61
|
+
len = r.length
|
62
|
+
len_max = len if len > len_max
|
63
|
+
len_min = len if len < len_min
|
64
|
+
|
65
|
+
size = r.positions_size
|
66
|
+
size_max = size if size > size_max
|
67
|
+
size_min = size if size < size_min
|
68
|
+
|
69
|
+
k_max = r.k if r.k > k_max
|
70
|
+
end
|
71
|
+
|
72
|
+
d = (len_max * size_min + size_max * k_max - size_max * len_min - len_max * k_max).to_f
|
73
|
+
|
74
|
+
alpha = (size_min + k_max * (size_max - 1)) / d
|
75
|
+
beta = - (len_min + k_max * (len_max - 1)) / d
|
76
|
+
gamma = (len_max * size_min - size_max * len_min - size_min + len_min) / d
|
77
|
+
|
78
|
+
puts "len_max = #{len_max}, len_min = #{len_min}, size_max = #{size_max}, size_min = #{size_min}, k_max = #{k_max}"
|
79
|
+
puts "alpha = #{alpha}, beta = #{beta}, gamma = #{gamma}"
|
80
|
+
|
81
|
+
rs.each do |r|
|
82
|
+
r.score = alpha * r.length + beta * r.positions_size + gamma * r.k
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|