Module: Lich::Common::Buffer

Defined in:
lib/common/buffer.rb

Constant Summary collapse

DOWNSTREAM_STRIPPED =
1
DOWNSTREAM_RAW =
2
DOWNSTREAM_MOD =
4
UPSTREAM =
8
UPSTREAM_MOD =
16
SCRIPT_OUTPUT =
32
@@index =
Hash.new
@@streams =
Hash.new
@@mutex =
Mutex.new
@@offset =
0
@@buffer =
Array.new
@@max_size =
3000

Class Method Summary collapse

Class Method Details

.cleanupself

Note:

This method will remove entries for threads that are no longer running.

Cleans up the index and streams for threads that are no longer active.

Examples:

Buffer.cleanup

Returns:

  • (self)

    the Buffer instance



181
182
183
184
185
# File 'lib/common/buffer.rb', line 181

def Buffer.cleanup
  @@index.delete_if { |k, _v| not Thread.list.any? { |t| t.object_id == k } }
  @@streams.delete_if { |k, _v| not Thread.list.any? { |t| t.object_id == k } }
  return self
end

.clearArray<Object>

Clears the buffer for the current thread and returns all lines that match the current stream.

Examples:

lines = Buffer.clear

Returns:

  • (Array<Object>)

    an array of lines that match the current stream



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/common/buffer.rb', line 100

def Buffer.clear
  thread_id = Thread.current.object_id
  if @@index[thread_id].nil?
    @@mutex.synchronize {
      @@index[thread_id] = (@@offset + @@buffer.length)
      @@streams[thread_id] ||= DOWNSTREAM_STRIPPED
    }
  end
  lines = Array.new
  loop {
    if (@@index[thread_id] - @@offset) >= @@buffer.length
      return lines
    end

    line = nil
    @@mutex.synchronize {
      if @@index[thread_id] < @@offset
        @@index[thread_id] = @@offset
      end
      line = @@buffer[@@index[thread_id] - @@offset]
    }
    @@index[thread_id] += 1
    lines.push(line) if ((line.stream & @@streams[thread_id]) != 0)
  }
  return lines
end

.getsObject

Note:

This method will block if no line is available until one becomes available.

Retrieves the next line from the buffer, blocking until a line is available.

Examples:

line = Buffer.gets

Returns:

  • (Object)

    the next line from the buffer



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/common/buffer.rb', line 27

def Buffer.gets
  thread_id = Thread.current.object_id
  if @@index[thread_id].nil?
    @@mutex.synchronize {
      @@index[thread_id] = (@@offset + @@buffer.length)
      @@streams[thread_id] ||= DOWNSTREAM_STRIPPED
    }
  end
  line = nil
  loop {
    if (@@index[thread_id] - @@offset) >= @@buffer.length
      sleep 0.05 while ((@@index[thread_id] - @@offset) >= @@buffer.length)
    end
    @@mutex.synchronize {
      if @@index[thread_id] < @@offset
        @@index[thread_id] = @@offset
      end
      line = @@buffer[@@index[thread_id] - @@offset]
    }
    @@index[thread_id] += 1
    break if ((line.stream & @@streams[thread_id]) != 0)
  }
  return line
end

.gets?Object?

Retrieves the next line from the buffer if available, otherwise returns nil.

Examples:

line = Buffer.gets?

Returns:

  • (Object, nil)

    the next line from the buffer or nil if no line is available



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/common/buffer.rb', line 57

def Buffer.gets?
  thread_id = Thread.current.object_id
  if @@index[thread_id].nil?
    @@mutex.synchronize {
      @@index[thread_id] = (@@offset + @@buffer.length)
      @@streams[thread_id] ||= DOWNSTREAM_STRIPPED
    }
  end
  line = nil
  loop {
    if (@@index[thread_id] - @@offset) >= @@buffer.length
      return nil
    end

    @@mutex.synchronize {
      if @@index[thread_id] < @@offset
        @@index[thread_id] = @@offset
      end
      line = @@buffer[@@index[thread_id] - @@offset]
    }
    @@index[thread_id] += 1
    break if ((line.stream & @@streams[thread_id]) != 0)
  }
  return line
end

.rewindself

Resets the index for the current thread to the beginning of the buffer.

Examples:

Buffer.rewind

Returns:

  • (self)

    the Buffer instance



88
89
90
91
92
93
# File 'lib/common/buffer.rb', line 88

def Buffer.rewind
  thread_id = Thread.current.object_id
  @@index[thread_id] = @@offset
  @@streams[thread_id] ||= DOWNSTREAM_STRIPPED
  return self
end

.streamsInteger

Note:

This method is subject to rubocop error Lint/HashCompareByIdentity.

Retrieves the current stream identifier for the calling thread.

Examples:

current_stream = Buffer.streams

Returns:

  • (Integer)

    the current stream identifier



156
157
158
# File 'lib/common/buffer.rb', line 156

def Buffer.streams
  @@streams[Thread.current.object_id]
end

.streams=(val) ⇒ nil

Sets the stream identifier for the calling thread.

Examples:

Buffer.streams = new_stream_id

Parameters:

  • val (Integer)

    the new stream identifier

Returns:

  • (nil)

    if the value is invalid

Raises:

  • (StandardError)

    if the value is not an Integer or if it does not represent a valid stream



167
168
169
170
171
172
173
# File 'lib/common/buffer.rb', line 167

def Buffer.streams=(val)
  if (val.class != Integer) or ((val & 63) == 0)
    respond "--- Lich: error: invalid streams value\n\t#{$!.caller[0..2].join("\n\t")}"
    return nil
  end
  @@streams[Thread.current.object_id] = val
end

.update(line, stream = nil) ⇒ self

Updates the buffer with a new line and an optional stream identifier.

Examples:

Buffer.update(new_line, stream_id)

Parameters:

  • line (Object)

    the line to be added to the buffer

  • stream (Integer, nil) (defaults to: nil)

    the stream identifier for the line (default: nil)

Returns:

  • (self)

    the Buffer instance



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/common/buffer.rb', line 134

def Buffer.update(line, stream = nil)
  @@mutex.synchronize {
    frozen_line = line.dup
    unless stream.nil?
      frozen_line.stream = stream
    end
    frozen_line.freeze
    @@buffer.push(frozen_line)
    while (@@buffer.length > @@max_size)
      @@buffer.shift
      @@offset += 1
    end
  }
  return self
end