trace_visualization 0.0.3 → 0.0.5

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 (37) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/bin/trace_visualization +21 -26
  4. data/lib/trace_visualization.rb +2 -2
  5. data/lib/trace_visualization/algorithm.rb +42 -0
  6. data/lib/trace_visualization/data/irepetition.rb +5 -1
  7. data/lib/trace_visualization/data/repetition.rb +14 -6
  8. data/lib/trace_visualization/data/sorted_array.rb +44 -0
  9. data/lib/trace_visualization/data/{lexeme.rb → token.rb} +7 -8
  10. data/lib/trace_visualization/lexeme_overlap_filter.rb +18 -18
  11. data/lib/trace_visualization/mapping.rb +72 -185
  12. data/lib/trace_visualization/repetitions/concatenation.rb +136 -0
  13. data/lib/trace_visualization/repetitions/context.rb +70 -0
  14. data/lib/trace_visualization/repetitions/filter.rb +153 -0
  15. data/lib/trace_visualization/repetitions/incrementation.rb +89 -0
  16. data/lib/trace_visualization/repetitions_psy.rb +12 -5
  17. data/lib/trace_visualization/utils.rb +5 -42
  18. data/lib/trace_visualization/version.rb +1 -1
  19. data/lib/trace_visualization/visualization/console_color_print.rb +20 -4
  20. data/spec/algorithm_spec.rb +69 -0
  21. data/spec/bwt_spec.rb +2 -5
  22. data/spec/data/sorted_array_spec.rb +27 -0
  23. data/spec/lexeme_overlap_filter_spec.rb +22 -22
  24. data/spec/longest_common_prefix_spec.rb +3 -8
  25. data/spec/mapping_spec.rb +72 -69
  26. data/spec/repetitions/concatenation_spec.rb +65 -0
  27. data/spec/repetitions/filter_spec.rb +180 -0
  28. data/spec/repetitions/incrementation_spec.rb +29 -0
  29. data/spec/repetitions_psy_spec.rb +7 -16
  30. data/spec/suffix_array_spec.rb +11 -31
  31. data/spec/utils_spec.rb +21 -9
  32. data/spec/visualization/console_color_print_spec.rb +26 -0
  33. data/trace_visualization.gemspec +2 -2
  34. metadata +27 -13
  35. data/lib/trace_visualization/repetitions_concatenation.rb +0 -134
  36. data/lib/trace_visualization/repetitions_context.rb +0 -18
  37. data/spec/repetitions_concatenation_spec.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 12c27504ea6bbbabd78f47e5bee3df251a5a7050
4
- data.tar.gz: 75a0bf55e52a108f449def1998de4fbf319d1f94
3
+ metadata.gz: 2fee2d1c5c6920d3966ae5190b05bcb40ce2b359
4
+ data.tar.gz: c8cb276ef0bfef1d293b996bd236c4d1cdc6f1b7
5
5
  SHA512:
6
- metadata.gz: f6fff098106b2ba908595a05345bebafc5686348454061983671c937c21a26ecb0cee59a8d6209203707949e7283daba5d620b7d386cd1ac230e021668f4a7f5
7
- data.tar.gz: 6e39264b5f0141746d7fda75d4c2c2be624a0829c12ed548160e6bd9f74afac162b06a6e9e670155ef042f7b7baf65eb0bff43a42236051f0aec81b15842495c
6
+ metadata.gz: 9dc0447760f9d5b95f27ec88e95bde2beb73037f36cb3af6d6aa4a324d17afa348e7462735e9a14e78aefdf9c779bb446beaaca5a249af32e467d4b14695f32f
7
+ data.tar.gz: d9b3c4ce306cd563ab394104fec2e85654e8bc55e8592a64ff7367a8269b7b33635f16412eba65af404c1eb2b790f9986c820a6fbb0aa483bbfbf155774e590b
data/Gemfile CHANGED
@@ -2,7 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  ruby '2.0.0'
4
4
 
5
- gem 'trace_preprocessor', "~> 0.0.2"
5
+ gem 'trace_preprocessor'
6
6
 
7
7
  # Specify your gem's dependencies in trace_visualization.gemspec
8
8
  gemspec
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'trace_visualization'
4
+ require 'trace_preprocessor'
4
5
  require 'tempfile'
5
6
  require 'benchmark'
6
7
  require 'optparse'
@@ -39,6 +40,11 @@ def parse_options
39
40
  opts.on('-t', '--test_preprocessor_performance', 'Test preprocessor performance') do
40
41
  options[:test_preprocessor_performance] = true
41
42
  end
43
+
44
+ opts.on('-v', '--version', 'Display version') do
45
+ puts "Version #{VERSION}"
46
+ exit
47
+ end
42
48
 
43
49
  opts.on('-h', '--help', 'Display this screen') do
44
50
  puts opts
@@ -75,8 +81,10 @@ def foo(options)
75
81
 
76
82
  mapping = nil
77
83
  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]) }
84
+ mapping = Mapping.new
85
+ mapping.process do
86
+ from_preprocessed_file(tmp_file.path, options[:offset], options[:limit], !options[:test_preprocessor_performance])
87
+ end
80
88
  end
81
89
 
82
90
  source_file_length = `wc -c #{options[:source_file_name]}`.to_i
@@ -94,40 +102,27 @@ def foo(options)
94
102
  exit 0
95
103
  end
96
104
 
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}"
105
+ repetitions = Algorithm.process(mapping, {})
103
106
 
104
- #context = nil
105
- #bm('Context') do
106
- # context = TraceVisualization::Repetitions::Context.new(mapping, rs)
107
- #end
107
+ RepetitionsScore.fill_score(repetitions, :sort => true, :order => 'desc', :version => 'relative')
108
108
 
109
- RepetitionsScore.fill_score(rs, :sort => true, :order => 'desc', :version => 'relative')
109
+ #
110
+ # rs[0 ... options[:out]].each do |r|
111
+ # puts '---------------------'
112
+ # puts r
113
+ # puts Visualization::ConsoleColorPrint.hl(mapping, r)
114
+ # end
110
115
 
111
- rs[0 ... options[:out]].each do |r|
112
- puts '---------------------'
113
- puts r
114
- puts Visualization::ConsoleColorPrint.hl(mapping, r)
115
- end
116
+ Visualization::ConsoleColorPrint.hl_stdout(mapping, repetitions[0])
116
117
 
117
- rs
118
+ repetitions
118
119
  end
119
120
 
120
-
121
121
  def bm(name, &block)
122
122
  Benchmark.bm(17) do |x|
123
123
  x.report(name, &block)
124
124
  end
125
125
  end
126
126
 
127
-
128
127
  options = parse_options
129
- rs = foo(options)
130
-
131
-
132
-
133
-
128
+ rs = foo(options)
@@ -5,7 +5,7 @@
5
5
  reorder
6
6
  repetitions
7
7
  repetitions_psy
8
- repetitions_context
8
+ repetitions/context
9
9
  repetitions_score
10
10
  visualization/console_color_print
11
11
  ).each { |file| require File.join(File.dirname(__FILE__), 'trace_visualization', file) }
@@ -34,7 +34,7 @@ module TraceVisualization
34
34
  # Read & mapping file
35
35
  mapping = TraceVisualization::Mapping.new
36
36
  mapping.process do
37
- from_preprocessed_file options[:file_name]
37
+ from_file options[:file_name]
38
38
  end
39
39
 
40
40
  =begin
@@ -0,0 +1,42 @@
1
+ require 'trace_visualization/utils'
2
+ require 'trace_visualization/assert'
3
+ require 'trace_visualization/repetitions/filter'
4
+ require 'trace_visualization/repetitions/concatenation'
5
+
6
+ module TraceVisualization
7
+
8
+ # Main algorithm
9
+ module Algorithm
10
+ include TraceVisualization
11
+ include TraceVisualization::Repetitions
12
+
13
+ # Run main algorithm of approximate repeats processing
14
+ # @param mapping [TraceVisualization::Mapping]
15
+ # @param options [Hash]
16
+ def self.process(mapping, options = {})
17
+ TraceVisualization.assert_instance_of(mapping, Mapping)
18
+
19
+ Utils.set_default_options(options, { :positions_min_size => 3, :k => 3 })
20
+
21
+ context = Context.new(mapping)
22
+
23
+ # First step - calculate strict repetitions
24
+ context.repetitions = Repetitions.psy1(mapping, options[:positions_min_size])
25
+
26
+ # Second step - iterative process concatenation & incrementation algorithms for approximate repeats processing
27
+ Filter.strict_repetitions_filter(mapping, context, options)
28
+
29
+ for kk in 1 .. options[:k]
30
+ Concatenation.process(context, {
31
+ :k => kk,
32
+ :positions_min_size => options[:positions_min_size]
33
+ })
34
+
35
+ Filter.repetitions_filter(mapping, context, options)
36
+ end
37
+
38
+ context.repetitions
39
+ end
40
+
41
+ end # Algorithm
42
+ end # TraceVisualization
@@ -1,3 +1,7 @@
1
+ require 'trace_visualization/data/sorted_array'
2
+
3
+ include TraceVisualization::Data
4
+
1
5
  # Interface for Repetition
2
6
  module IRepetition
3
7
  def positions_size; end
@@ -31,7 +35,7 @@ class RepetitionBase
31
35
  attr_accessor :lines
32
36
 
33
37
  def initialize
34
- @lines = []
38
+ @lines = SortedArray.new
35
39
  end
36
40
 
37
41
  def left_length
@@ -5,11 +5,13 @@ module TraceVisualization
5
5
  module Data
6
6
  class Repetition < RepetitionBase
7
7
  @@sequence = 0
8
-
8
+
9
+ attr_reader :id
10
+ attr_reader :left_positions, :right_positions
11
+
9
12
  attr_accessor :score
10
13
  attr_accessor :pcount
11
- attr_reader :left_positions, :right_positions
12
- attr_reader :id
14
+
13
15
  attr_accessor :strict_ids
14
16
 
15
17
  def to_s
@@ -23,7 +25,7 @@ module TraceVisualization
23
25
  "left = #{@left != nil ? @left.id : 'nil'}, " +
24
26
  "right = #{@right != nil ? @right.id : 'nil'}"
25
27
  end
26
-
28
+
27
29
  def initialize(length, left_positions, right_positions = nil)
28
30
  super()
29
31
 
@@ -35,10 +37,16 @@ module TraceVisualization
35
37
  @right_positions = right_positions
36
38
 
37
39
  @id = (@@sequence += 1)
38
- @strict_ids = [@id]
39
- @lines = []
40
+ @strict_ids = [ @id ]
40
41
  end
41
42
 
43
+ def ==(other_repetition)
44
+ other_repetition != nil &&
45
+ @length == other_repetition.length &&
46
+ @left_positions == other_repetition.left_positions &&
47
+ @right_positions == other_repetition.right_positions
48
+ end
49
+
42
50
  def positions_size
43
51
  @left_positions.size
44
52
  end
@@ -0,0 +1,44 @@
1
+ module TraceVisualization
2
+ module Data
3
+ class SortedArray < Array
4
+ def self.[] *array
5
+ SortedArray.new(array)
6
+ end
7
+
8
+ def initialize(array = nil)
9
+ super( array.sort ) if array
10
+ end
11
+
12
+ def << value
13
+ insert index_of_last_LE(value), value
14
+ end
15
+
16
+ alias push <<
17
+ alias shift <<
18
+
19
+ def index_of_last_LE value
20
+ l, r = 0, length - 1
21
+ while l <= r
22
+ m = (r + l) / 2
23
+
24
+ if value < self[m]
25
+ r = m - 1
26
+ else
27
+ l = m + 1
28
+ end
29
+ end
30
+
31
+ l
32
+ end
33
+
34
+ def index value
35
+ idx = index_of_last_LE(value)
36
+
37
+ if idx != 0 && self[idx - 1] == value
38
+ idx -= 1 while idx != 0 && self[idx - 1] == value
39
+ idx
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -1,12 +1,12 @@
1
1
  module TraceVisualization
2
2
  module Data
3
- class Lexeme
3
+ class Token
4
4
  attr_accessor :name
5
5
  attr_accessor :value
6
6
  attr_accessor :int_value
7
7
 
8
- # Length of preprocessed string (see LEXEME_REGEXP)
9
- attr_accessor :lexeme_length
8
+ # Length of preprocessed string (see TOKEN_REGEXP)
9
+ attr_accessor :token_length
10
10
 
11
11
  attr_accessor :ord
12
12
 
@@ -47,12 +47,11 @@ module TraceVisualization
47
47
  end
48
48
  end
49
49
 
50
- class LexemePos
51
- attr_accessor :lexeme
52
- attr_accessor :pos
50
+ class TokenPosition
51
+ attr_accessor :token, :pos
53
52
 
54
- def initialize(lexeme, pos)
55
- @lexeme, @pos = lexeme, pos
53
+ def initialize(token, pos)
54
+ @token, @pos = token, pos
56
55
  end
57
56
  end
58
57
  end
@@ -1,10 +1,10 @@
1
1
  module TraceVisualization
2
2
  module LexemeOverlapFilter
3
3
 
4
- def self.process(lexeme_poss)
5
- lexeme_poss.sort! { |a, b| a.pos <=> b.pos }
6
- left_bound = lexeme_poss.inject(0) do |left_bound, lexeme_pos|
7
- [lexeme_pos.pos + lexeme_pos.lexeme.length, left_bound].max
4
+ def self.process(token_positions)
5
+ token_positions.sort! { |a, b| a.pos <=> b.pos }
6
+ left_bound = token_positions.inject(0) do |left_bound, token_pos|
7
+ [token_pos.pos + token_pos.token.length, left_bound].max
8
8
  end
9
9
 
10
10
  idx, current, result = 0, [], []
@@ -13,24 +13,24 @@ module TraceVisualization
13
13
 
14
14
  i = 0
15
15
  while i < current.size
16
- lexeme_pos = current[i]
16
+ token_pos = current[i]
17
17
 
18
- if lexeme_pos.pos + lexeme_pos.lexeme.length == pos
19
- fl_delete_lexeme = false
18
+ if token_pos.pos + token_pos.token.length == pos
19
+ fl_delete_token = false
20
20
 
21
21
  if current.size == 1
22
- result << lexeme_pos
23
- fl_delete_lexeme = true
22
+ result << token_pos
23
+ fl_delete_token = true
24
24
  else
25
- if is_longest_lexeme(current, lexeme_pos)
26
- result << lexeme_pos
25
+ if is_longest_token(current, token_pos)
26
+ result << token_pos
27
27
  current = []
28
28
  else
29
- fl_delete_lexeme = true
29
+ fl_delete_token = true
30
30
  end
31
31
  end
32
32
 
33
- if fl_delete_lexeme
33
+ if fl_delete_token
34
34
  current.delete_at(i)
35
35
  i -= 1
36
36
  end
@@ -39,8 +39,8 @@ module TraceVisualization
39
39
  i += 1
40
40
  end
41
41
 
42
- while idx < lexeme_poss.size && lexeme_poss[idx].pos == pos
43
- current << lexeme_poss[idx]
42
+ while idx < token_positions.size && token_positions[idx].pos == pos
43
+ current << token_positions[idx]
44
44
  idx += 1
45
45
  end
46
46
  end
@@ -48,11 +48,11 @@ module TraceVisualization
48
48
  result
49
49
  end
50
50
 
51
- def self.is_longest_lexeme(lexeme_poss, lexeme_pos)
51
+ def self.is_longest_token(token_positions, token_pos)
52
52
  result = true
53
53
 
54
- lexeme_poss.each do |other_lexeme_pos|
55
- if lexeme_pos != other_lexeme_pos && lexeme_pos.lexeme.length < other_lexeme_pos.lexeme.length
54
+ token_positions.each do |other_token_pos|
55
+ if token_pos != other_token_pos && token_pos.token.length < other_token_pos.token.length
56
56
  result = false
57
57
  break
58
58
  end
@@ -3,38 +3,18 @@ require 'ipaddr'
3
3
 
4
4
  require 'trace_visualization/reorder'
5
5
  require 'trace_visualization/lexeme_overlap_filter'
6
- require 'trace_visualization/data/lexeme'
6
+ require 'trace_visualization/data/token'
7
+
8
+ include TraceVisualization
7
9
 
8
10
  module TraceVisualization
9
11
  class Mapping
10
-
11
- attr_accessor :tokens
12
-
13
- LEXEME_REGEXP = /\{LEXEME;(?<name>[a-zA-Z0-9]+);(?<source>[^;]+);(?<value>[0-9]+)\}/
14
-
15
- DEFAULT_TOKENS = {
16
- :ID => [
17
- /(?<lexeme>\[\d{3,}\])/,
18
- lambda { |source| source[1 ... -1].to_i }
19
- ],
20
-
21
- :IP => [
22
- /(?<lexeme>(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))/,
23
- lambda { |source| IPAddr.new(source).to_i }
24
- ],
25
-
26
- :TIME => [
27
- /(?<lexeme>\[\d{2} [a-zA-Z]{3} \d{4} \d{2}\:\d{2}\:\d{2}\])/,
28
- lambda { |source| Time.parse(source[1 ... -1]).to_i }
29
- ]
30
- }
12
+ TOKEN_REGEXP = /\{TOKEN;(?<name>[a-zA-Z0-9]+);(?<source>[^;]+);(?<value>[0-9]+);(?<kind>[0-9]+)\}/
31
13
 
32
14
  def initialize
33
- # hash map: lexeme-object by lexeme-string
34
- @lexeme_table = {}
35
-
36
- @tokens = {}
37
- @mapped_str = []
15
+ @tokens_map = {}
16
+ @data = []
17
+ @lines = []
38
18
  end
39
19
 
40
20
  def self.init(&block)
@@ -42,163 +22,112 @@ module TraceVisualization
42
22
  mapping.instance_eval(&block)
43
23
  mapping
44
24
  end
45
-
46
- # new
47
- def token(name, pattern, converter_func)
48
- @tokens[name] = [pattern, converter_func]
49
- end
50
-
51
- def default_tokens
52
- @tokens.merge!(DEFAULT_TOKENS)
53
- end
54
25
 
55
- # new
26
+ # Process input data with reorder
56
27
  def process(&block)
57
28
  instance_eval(&block)
58
- @max_value = TraceVisualization::Reorder.process(@mapped_str)
29
+ @max_value = Reorder.process(@data)
59
30
  end
60
31
 
32
+ # Process input data without reorder
61
33
  def process_without_reorder(&block)
62
34
  instance_eval(&block)
63
35
  end
64
36
 
65
- ##
66
- # Load data from source file. File is read line by line
67
-
68
- def from_file(path)
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
76
- end
77
-
78
- ##
79
37
  # Load data from preprocessed file. File is read line by line
80
-
81
- def from_preprocessed_file(path, offset, limit, use_lexeme_table = true)
38
+ def from_file(path, offset = 0, limit = 2**32, use_lexeme_table = true)
82
39
  validate_file_name_argument(path)
83
40
 
84
41
  idx = 0
85
42
  open(path) do |fd|
86
43
  while (line = fd.gets)
87
- process_preprocessed_line(line, use_lexeme_table) if (idx >= offset && idx < offset + limit)
44
+ line.chomp!
45
+ if idx >= offset && idx < offset + limit
46
+ process_line(line, use_lexeme_table)
47
+ elsif idx >= offset + limit
48
+ break
49
+ end
88
50
 
89
51
  idx += 1
90
52
  end
91
53
  end
92
- end
93
-
94
- # new
95
- def from_string(str)
96
- validate_string_argument(str)
97
54
 
98
- @str = str
99
-
100
- str.split("\n").each do |line|
101
- process_line(line)
102
- end
103
-
104
- @mapped_str.pop if @mapped_str[-1].value == "\n" && str[-1] != "\n"
55
+ @data.pop
105
56
  end
106
57
 
107
- def from_preprocessed_string(str, use_lexeme_table = true)
58
+ # Load data from string
59
+ def from_string(str, use_lexeme_table = true)
108
60
  validate_string_argument(str)
109
61
 
110
62
  str.split("\n").each do |line|
111
- process_preprocessed_line(line)
63
+ process_line(line)
112
64
  end
65
+
66
+ @data.pop
113
67
  end
114
68
 
115
- def process_preprocessed_line(line, use_lexeme_table = true)
116
- lexeme_positions = []
69
+ # Process line
70
+ def process_line(line, use_lexeme_table = true)
71
+ @lines << @data.length
72
+
73
+ token_positions = []
117
74
  pos = 0
118
- while (m = LEXEME_REGEXP.match(line, pos))
75
+ while (m = TOKEN_REGEXP.match(line, pos))
119
76
  pos = m.begin(0)
120
77
 
121
- lexeme = install_lexeme_m(m, use_lexeme_table)
122
- lexeme_positions << TraceVisualization::Data::LexemePos.new(lexeme, pos)
123
-
124
- pos += lexeme.lexeme_length
125
- end
126
-
78
+ token = install_token_m(m, use_lexeme_table)
79
+ token_positions << Data::TokenPosition.new(token, pos)
127
80
 
128
- pos, idx = 0, 0
129
- while pos < line.length
130
- lexeme = nil
131
- if idx < lexeme_positions.size && lexeme_positions[idx].pos == pos
132
- lexeme = lexeme_positions[idx].lexeme
133
- idx += 1
134
- else
135
- lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1, use_lexeme_table)
136
- end
137
- pos += lexeme.lexeme_length
138
- @mapped_str << lexeme
81
+ pos += token.token_length
139
82
  end
140
83
 
141
- @mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1, use_lexeme_table)
142
- end
143
-
144
- # new
145
- def process_line(line)
146
- lexeme_poss = []
147
84
 
148
- @tokens.each do |name, value|
149
- pattern, converter_func = value
150
- pos = 0
151
- while (m = pattern.match(line, pos))
152
- lexeme_string, pos = m[:lexeme], m.begin(0)
153
-
154
- lexeme = install_lexeme(name, lexeme_string, converter_func.call(lexeme_string), lexeme_string.length)
155
- lexeme_poss << TraceVisualization::Data::LexemePos.new(lexeme, pos)
156
-
157
- pos += lexeme_string.length
158
- end
159
- end
160
-
161
- lexeme_poss = TraceVisualization::LexemeOverlapFilter.process(lexeme_poss)
162
-
163
85
  pos, idx = 0, 0
164
86
  while pos < line.length
165
- lexeme = nil
166
- if idx < lexeme_poss.size && lexeme_poss[idx].pos == pos
167
- lexeme = lexeme_poss[idx].lexeme
87
+ token = nil
88
+ if idx < token_positions.size && token_positions[idx].pos == pos
89
+ token = token_positions[idx].token
168
90
  idx += 1
169
91
  else
170
- lexeme = install_lexeme('CHAR', line[pos], line[pos].ord, 1)
92
+ token = install_token('CHAR', line[pos], line[pos].ord, 1, use_lexeme_table)
171
93
  end
172
- pos += lexeme.length
173
- @mapped_str << lexeme
94
+ pos += token.token_length
95
+ @data << token
174
96
  end
175
97
 
176
- @mapped_str << install_lexeme('CHAR', "\n", "\n".ord, 1)
98
+ @data << install_lf_token
177
99
  end
178
100
 
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
101
+ def install_token(name, token_string, int_value, token_length, use_token_table = true)
102
+ name = name.intern
181
103
 
182
- if lexeme.nil?
183
- lexeme = TraceVisualization::Data::Lexeme.new(name, lexeme_string, int_value)
184
- lexeme.lexeme_length = lexeme_length
104
+ token = use_token_table ? @tokens_map[token_string] : nil
105
+
106
+ if token.nil?
107
+ token = Data::Token.new(name, token_string, int_value)
108
+ token.token_length = token_length
185
109
 
186
- @lexeme_table[lexeme_string] = lexeme if use_lexeme_table
110
+ @tokens_map[token_string] = token if use_token_table
187
111
  end
188
112
 
189
- lexeme
113
+ token
190
114
  end
191
115
 
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)
116
+ def install_token_m(m, use_lexeme_table = true)
117
+ install_token(m[:name], m[:source], m[:value].to_i, m.to_s.length, use_lexeme_table)
118
+ end
119
+
120
+ # Install token with LF (line feed or end of line)
121
+ def install_lf_token
122
+ install_token('CHAR', "\n", 0x0A, 1)
194
123
  end
195
124
 
196
125
  def [](index)
197
- @mapped_str[index]
126
+ @data[index]
198
127
  end
199
128
 
200
129
  def length
201
- @mapped_str.length
130
+ @data.length
202
131
  end
203
132
 
204
133
  def size
@@ -206,13 +135,13 @@ module TraceVisualization
206
135
  end
207
136
 
208
137
  def <<(object)
209
- lexeme = install_lexeme('UNKNOWN', object, object.to_i, object.to_s.length)
138
+ lexeme = install_token('UNKNOWN', object, object.to_i, object.to_s.length)
210
139
  lexeme.ord = 0 # fake ord because Reorder already processed
211
- @mapped_str << lexeme
140
+ @data << lexeme
212
141
  end
213
142
 
214
143
  def pop
215
- @mapped_str.pop
144
+ @data.pop
216
145
  end
217
146
 
218
147
  def max
@@ -220,15 +149,23 @@ module TraceVisualization
220
149
  end
221
150
 
222
151
  def find_all
223
- @mapped_str.find_all { |item| yield(item) }
152
+ @data.find_all { |item| yield(item) }
224
153
  end
225
154
 
226
- def restore(pos = 0, length = @mapped_str.length)
227
- @mapped_str[pos ... pos + length].inject("") { |res, c| res += c.value }
155
+ # Restore source data
156
+ # @param pos [Integer] begin position
157
+ # @param length [Integer] the length of restore part
158
+ def restore(pos = 0, length = @data.length)
159
+ @data[pos ... pos + length].inject("") { |res, c| res += c.value }
228
160
  end
229
161
 
230
162
  def to_ary
231
- @mapped_str.collect { |lexeme| lexeme.value }
163
+ @data.collect { |lexeme| lexeme.value }
164
+ end
165
+
166
+ # @return array of lines positions
167
+ def lines
168
+ @lines
232
169
  end
233
170
 
234
171
  def method_missing(name, *args, &blk)
@@ -236,57 +173,7 @@ module TraceVisualization
236
173
  end
237
174
 
238
175
  private
239
-
240
- def parse(str)
241
- map = {}
242
- ppos = []
243
- itemByPos = {}
244
-
245
- DEFAULT_TOKENS.each do |type, patterns|
246
- patterns.each do |pattern|
247
- match(str, type, pattern, map, ppos, itemByPos)
248
- end
249
- end
250
-
251
- i, j = 0, 0
252
- result = []
253
-
254
- ppos.sort!
255
-
256
- while i < str.size
257
- if i == ppos[j]
258
- item = itemByPos[ppos[j]]
259
- result << item
260
- i, j = i + item.length, j + 1
261
- else
262
- result << Item.new(str[i], "char")
263
- i += 1
264
- end
265
- end
266
-
267
- @max_value = TraceVisualization::Reorder.process(result)
268
-
269
- result
270
- end
271
176
 
272
- def match(str, type, pattern, map, ppos, itemByPos)
273
- pos = 0
274
-
275
- limit = 1000
276
-
277
- while (m = pattern.match(str, pos))
278
- value = m[:value]
279
- pos = m.begin(0)
280
- ppos << pos
281
-
282
- map[value] = Item.new(value, type) unless map[value]
283
- itemByPos[pos] = map[value]
284
-
285
- pos += value.size
286
- end
287
-
288
- end
289
-
290
177
  def validate_file_name_argument(path)
291
178
  raise ArgumentError, 'Argument must be a string' if not path.instance_of? String
292
179
  raise ArgumentError, 'File path is not defined' if path.empty?