Class: Pocolog::StreamIndex Private

Inherits:
Object
  • Object
show all
Defined in:
lib/pocolog/stream_index.rb

Overview

This class is part of a private API. You should avoid using this class if possible, as it may be removed or be changed in the future.

Index containing the information for a given stream

The stream can possibly span multiple files if it is backed by a IOSequence object. This is transparent to the index as IOSequence provides an interface where positions span the IOs

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base_time: nil, index_map: []) ⇒ StreamIndex

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns a new instance of StreamIndex.



29
30
31
32
33
34
# File 'lib/pocolog/stream_index.rb', line 29

def initialize(base_time: nil, index_map: [])
    raise if index_map.first.kind_of?(Array)

    @base_time = base_time
    @index_map = index_map
end

Instance Attribute Details

#base_timeInteger

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Time (in microseconds) used to reference all the other times in the index

Returns:

  • (Integer)


15
16
17
# File 'lib/pocolog/stream_index.rb', line 15

def base_time
  @base_time
end

#index_mapObject (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

The index information

This is an flat array of file_pos, time for each sample



20
21
22
# File 'lib/pocolog/stream_index.rb', line 20

def index_map
  @index_map
end

Class Method Details

.from_raw_data(base_time, index_map) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Initialize a stream index object from the raw information



23
24
25
26
27
# File 'lib/pocolog/stream_index.rb', line 23

def self.from_raw_data(base_time, index_map)
    raise if index_map.first.kind_of?(Array)

    StreamIndex.new(base_time: base_time, index_map: index_map)
end

.map_entries_internal(index_map) {|pos, time| ... } ⇒ Array

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Map entries of an index index map data array

Yield Parameters:

  • pos (Integer)

    file position

  • time (Integer)

    internal time

Yield Returns:

  • ((Integer, Integer))

    new position and time

Returns:

  • (Array)

    updated index map



80
81
82
83
84
85
86
# File 'lib/pocolog/stream_index.rb', line 80

def self.map_entries_internal(index_map)
    new_map = Array.new(index_map.size)
    (0...index_map.size).step(2) do |i|
        new_map[i, 2] = yield(index_map[i, 2])
    end
    new_map
end

.time_from_internal(time, base_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a Time object from the index’ own internal Time representation



219
220
221
222
# File 'lib/pocolog/stream_index.rb', line 219

def self.time_from_internal(time, base_time)
    time += base_time
    Time.at(time / 1_000_000, time % 1_000_000)
end

.time_to_internal(time, base_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Converts a Time object into the index’ internal representation



225
226
227
228
# File 'lib/pocolog/stream_index.rb', line 225

def self.time_to_internal(time, base_time)
    internal = time.tv_sec * 1_000_000 + time.tv_usec
    internal - base_time
end

Instance Method Details

#add_raw_sample(pos, internal_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Append a new sample to the index

Parameters:

  • internal_time (Integer)

    time as an offset in microseconds from the base time



145
146
147
148
# File 'lib/pocolog/stream_index.rb', line 145

def add_raw_sample(pos, internal_time)
    @base_time ||= internal_time
    @index_map << pos << (internal_time - @base_time)
end

#add_sample(pos, internal_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Append a new sample to the index

Parameters:

  • internal_time (Integer)

    time as an offset in microseconds from the base time



137
138
139
# File 'lib/pocolog/stream_index.rb', line 137

def add_sample(pos, internal_time)
    add_raw_sample(pos, internal_time)
end

#concat(stream_index, file_pos_offset = 0) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Concatenates followup information for the same stream

Parameters:

  • stream_index (StreamIndex)

    the index to concatenate

  • file_pos_offset (Integer) (defaults to: 0)

    offset to apply to the added stream’s file position. This is used when building the index of a stream backed by a IOSequence.



123
124
125
126
127
128
129
130
131
# File 'lib/pocolog/stream_index.rb', line 123

def concat(stream_index, file_pos_offset = 0)
    @base_time ||= stream_index.base_time
    time_offset = stream_index.base_time - base_time

    new_index_map = stream_index.map_entries_internal do |pos, time|
        [pos + file_pos_offset, time + time_offset]
    end
    @index_map.concat(new_index_map)
end

#empty?Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

True if there are no samples indexed in self

Returns:

  • (Boolean)


94
95
96
# File 'lib/pocolog/stream_index.rb', line 94

def empty?
    @index_map.empty?
end

#end_timeTime?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the time of the last sample

Returns:

  • (Time, nil)


214
215
216
# File 'lib/pocolog/stream_index.rb', line 214

def end_time
    time_by_sample_number(-1) unless empty?
end

#file_position_by_sample_number(sample_number) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the IO position of a sample

Parameters:

  • sample_number (Integer)

    the sample index in the stream

Returns:

  • (Integer)

    the sample’s position in the backing IO

Raises:

  • IndexError if the sample number is out of bounds



255
256
257
# File 'lib/pocolog/stream_index.rb', line 255

def file_position_by_sample_number(sample_number)
    @index_map.fetch(sample_number * 2)
end

#initialize_copy(_copy) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Raises:

  • (NotImplementedError)


36
37
38
# File 'lib/pocolog/stream_index.rb', line 36

def initialize_copy(_copy)
    raise NotImplementedError, "StreamInfo is non-copyable"
end

#internal_time_by_sample_number(sample_number) ⇒ Integer

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the time of a sample

Parameters:

  • sample_number (Integer)

    the sample index in the stream

Returns:

  • (Integer)

    the sample’s time in the index’ internal encoding

Raises:

  • IndexError if the sample number is out of bounds



264
265
266
# File 'lib/pocolog/stream_index.rb', line 264

def internal_time_by_sample_number(sample_number)
    @index_map.fetch(sample_number * 2 + 1)
end

#map_entries {|pos, time| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Create a new index object with its entries changed

Yield Parameters:

  • pos (Integer)

    the file position for this sample

  • time (Integer)

    the internal sample time, as an offset in microseconds from #base_time



60
61
62
63
# File 'lib/pocolog/stream_index.rb', line 60

def map_entries(&block)
    new_map = map_entries_internal(&block)
    self.class.from_raw_data(@base_time, new_map)
end

#map_entries_internal(&block) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Non-destructively change the internal @index_map object



68
69
70
# File 'lib/pocolog/stream_index.rb', line 68

def map_entries_internal(&block)
    self.class.map_entries_internal(@index_map, &block)
end

#raw_each {|file_pos, time| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Iterate over the index

Yield Parameters:

  • file_pos (Integer)

    the position in the file

  • time (Integer)

    the time since #base_time



102
103
104
# File 'lib/pocolog/stream_index.rb', line 102

def raw_each(&block)
    @index_map.each_slice(2, &block)
end

#raw_each_time {|time| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Iterate over the sample times

Yield Parameters:

  • time (Integer)

    the time since #base_time in microseconds



109
110
111
112
113
114
115
# File 'lib/pocolog/stream_index.rb', line 109

def raw_each_time
    return enum_for(__method__) unless block_given?

    (1...@index_map.size).step(2) do |i|
        yield(@index_map[i])
    end
end

#remove_after(time) ⇒ StreamIndex

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new index without any sample at or after the given time

Parameters:

  • time (Time)

Returns:



164
165
166
167
168
# File 'lib/pocolog/stream_index.rb', line 164

def remove_after(time)
    index = sample_number_by_time(time)
    new_map = @index_map[0...(index * 2)]
    self.class.from_raw_data(@base_time, new_map)
end

#remove_before(time) ⇒ StreamIndex

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return a new index without any sample before the given time

Parameters:

  • time (Time)

Returns:



154
155
156
157
158
# File 'lib/pocolog/stream_index.rb', line 154

def remove_before(time)
    index = sample_number_by_time(time)
    new_map = @index_map[(index * 2)...@index_map.size]
    self.class.from_raw_data(@base_time, new_map)
end

#resample_by_index(period) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the index with only every N-th samples



171
172
173
174
175
176
177
178
179
180
181
# File 'lib/pocolog/stream_index.rb', line 171

def resample_by_index(period)
    return self.class.from_raw_data(@base_time, @index_map) if period == 1

    new_map = Array.new((sample_count + period - 1) / period * 2)
    (0...new_map.size).step(2) do |i|
        j = i * period
        new_map[i] = @index_map[j]
        new_map[i + 1] = @index_map[j + 1]
    end
    self.class.from_raw_data(@base_time, new_map)
end

#resample_by_time(period, start_time: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the index with only every N-th samples



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/pocolog/stream_index.rb', line 184

def resample_by_time(period, start_time: nil)
    period_us = Integer(period * 1_000_000)
    next_time =
        if start_time
            self.class.time_to_internal(start_time, @base_time)
        else
            internal_time_by_sample_number(0)
        end

    new_map = []
    raw_each do |pos, time|
        if time >= next_time
            new_map << pos << time
            next_time += ((time - next_time) / period_us + 1) * period_us
        end
    end

    self.class.from_raw_data(@base_time, new_map)
end

#sample_countObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Number of samples in this index



89
90
91
# File 'lib/pocolog/stream_index.rb', line 89

def sample_count
    @index_map.size / 2
end

#sample_number_by_internal_time(sample_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the sample number of the first sample whose time is not before the given time

Parameters:

  • (Integer)


243
244
245
246
247
248
# File 'lib/pocolog/stream_index.rb', line 243

def sample_number_by_internal_time(sample_time)
    idx = (0...sample_count).bsearch do |i|
        @index_map[i * 2 + 1] >= sample_time
    end
    idx || sample_count
end

#sample_number_by_time(sample_time) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the sample number of the first sample whose time is not before the given time

Parameters:

  • (Time)


234
235
236
237
# File 'lib/pocolog/stream_index.rb', line 234

def sample_number_by_time(sample_time)
    sample_time = StreamIndex.time_to_internal(sample_time, base_time)
    sample_number_by_internal_time(sample_time)
end

#start_timeTime?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the time of the first sample

Returns:

  • (Time, nil)


207
208
209
# File 'lib/pocolog/stream_index.rb', line 207

def start_time
    time_by_sample_number(0) unless empty?
end

#time_by_sample_number(sample_number) ⇒ Time

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the time of a sample

Parameters:

  • sample_number (Integer)

    the sample index in the stream

Returns:

  • (Time)

    the sample’s time in the index’ internal encoding

Raises:

  • IndexError if the sample number is out of bounds



273
274
275
276
277
278
# File 'lib/pocolog/stream_index.rb', line 273

def time_by_sample_number(sample_number)
    StreamIndex.time_from_internal(
        internal_time_by_sample_number(sample_number),
        base_time
    )
end