philiprehberger-ring_buffer 0.2.0 → 0.4.0
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/CHANGELOG.md +31 -0
- data/README.md +38 -0
- data/lib/philiprehberger/ring_buffer/version.rb +1 -1
- data/lib/philiprehberger/ring_buffer.rb +77 -6
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 8d3a987697f096aa8b9d085eeb0a4bcd6f83a5af1a0c2afcae477a6e789bbcdf
|
|
4
|
+
data.tar.gz: 66b3843e018fbb2f2e02d72d6b727e7cae71a64c299ac7e4e29747aebc8cf351
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 10d2a15e1fc6afeb68d4c8a760170eddbec9c833c3c552fb72d9c3ea72d9efe5c741c1f0beca5375592344ffbac699b27d49fd3c18f75988bbc0e289078eb7f4
|
|
7
|
+
data.tar.gz: be638339a29c4492487f1aefca54a2235256b09a7a8f3c07eda3b72a7e5df29e9aea9f77d9e2a7225ef9c54735b6ab17a173e0b1153edb23549ca9e0a3b1f133
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,26 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.4.0] - 2026-04-14
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- `#resize(new_capacity)` to dynamically change buffer capacity while preserving elements
|
|
14
|
+
- `#inspect` for human-readable string representation
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- Bug report template: Ruby version now required, gem version field added
|
|
18
|
+
- Feature request template: added "Alternatives considered" field and API placeholder
|
|
19
|
+
|
|
20
|
+
## [0.3.0] - 2026-04-09
|
|
21
|
+
|
|
22
|
+
### Added
|
|
23
|
+
- `#shift` removes and returns the oldest element
|
|
24
|
+
- `#pop` removes and returns the newest element
|
|
25
|
+
- `#oldest` and `#newest` peek without mutating
|
|
26
|
+
|
|
27
|
+
### Changed
|
|
28
|
+
- Internal `to_a` now derives the start index from `@head` and `@count`, supporting consumption via `shift`/`pop` while preserving all existing semantics
|
|
29
|
+
|
|
10
30
|
## [0.2.0] - 2026-04-03
|
|
11
31
|
|
|
12
32
|
### Added
|
|
@@ -57,3 +77,14 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
|
|
|
57
77
|
- Statistics: average, sum, min, max
|
|
58
78
|
- Last-n element retrieval
|
|
59
79
|
- Enumerable support
|
|
80
|
+
|
|
81
|
+
[0.4.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.4.0
|
|
82
|
+
[0.3.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.3.0
|
|
83
|
+
[0.2.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.2.0
|
|
84
|
+
[0.1.6]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.6
|
|
85
|
+
[0.1.5]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.5
|
|
86
|
+
[0.1.4]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.4
|
|
87
|
+
[0.1.3]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.3
|
|
88
|
+
[0.1.2]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.2
|
|
89
|
+
[0.1.1]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.1
|
|
90
|
+
[0.1.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.1.0
|
data/README.md
CHANGED
|
@@ -70,6 +70,24 @@ buf.size # => 0
|
|
|
70
70
|
buf.empty? # => true
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
+
### Consuming Elements
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
buf = Philiprehberger::RingBuffer.new(3)
|
|
77
|
+
[1, 2, 3].each { |v| buf.push(v) }
|
|
78
|
+
|
|
79
|
+
buf.shift # => 1 (removes oldest)
|
|
80
|
+
buf.pop # => 3 (removes newest)
|
|
81
|
+
buf.to_a # => [2]
|
|
82
|
+
|
|
83
|
+
buf.push(4)
|
|
84
|
+
buf.push(5)
|
|
85
|
+
buf.oldest # => 2 (peek, no mutation)
|
|
86
|
+
buf.newest # => 5
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
`shift`, `pop`, `oldest`, and `newest` all return `nil` when the buffer is empty.
|
|
90
|
+
|
|
73
91
|
### Statistics
|
|
74
92
|
|
|
75
93
|
```ruby
|
|
@@ -85,6 +103,20 @@ buf.stddev # => 8.16496580927726
|
|
|
85
103
|
buf.median # => 20.0
|
|
86
104
|
```
|
|
87
105
|
|
|
106
|
+
### Resize
|
|
107
|
+
|
|
108
|
+
```ruby
|
|
109
|
+
buf = Philiprehberger::RingBuffer.new(3)
|
|
110
|
+
[1, 2, 3].each { |v| buf.push(v) }
|
|
111
|
+
|
|
112
|
+
buf.resize(5)
|
|
113
|
+
buf.capacity # => 5
|
|
114
|
+
buf.to_a # => [1, 2, 3]
|
|
115
|
+
|
|
116
|
+
buf.resize(2)
|
|
117
|
+
buf.to_a # => [2, 3] (keeps most recent)
|
|
118
|
+
```
|
|
119
|
+
|
|
88
120
|
### Enumerable
|
|
89
121
|
|
|
90
122
|
```ruby
|
|
@@ -100,6 +132,10 @@ buf.select(&:odd?) # => [1, 3]
|
|
|
100
132
|
|--------|-------------|
|
|
101
133
|
| `RingBuffer.new(capacity)` | Create a buffer with fixed capacity |
|
|
102
134
|
| `#push(value)` | Add a value, overwriting oldest if full |
|
|
135
|
+
| `#shift` | Remove and return the oldest element (or `nil`) |
|
|
136
|
+
| `#pop` | Remove and return the newest element (or `nil`) |
|
|
137
|
+
| `#oldest` | Peek the oldest element without removing (or `nil`) |
|
|
138
|
+
| `#newest` | Peek the newest element without removing (or `nil`) |
|
|
103
139
|
| `#[](index)` | Access by index (0 = oldest, -1 = newest) |
|
|
104
140
|
| `#to_a` | Convert to array (oldest first) |
|
|
105
141
|
| `#size` | Number of elements in the buffer |
|
|
@@ -108,6 +144,8 @@ buf.select(&:odd?) # => [1, 3]
|
|
|
108
144
|
| `#first(n)` | First n elements (oldest) |
|
|
109
145
|
| `#last(n)` | Last n elements (most recent) |
|
|
110
146
|
| `#clear` | Remove all elements, reset state |
|
|
147
|
+
| `#resize(new_capacity)` | Change buffer capacity, keeping most recent elements |
|
|
148
|
+
| `#inspect` | Human-readable string representation |
|
|
111
149
|
| `#average` | Average of numeric elements |
|
|
112
150
|
| `#sum` | Sum of numeric elements |
|
|
113
151
|
| `#min` | Minimum element |
|
|
@@ -39,12 +39,53 @@ module Philiprehberger
|
|
|
39
39
|
def to_a
|
|
40
40
|
return [] if @count.zero?
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
start = (@head - @count) % @capacity
|
|
43
|
+
Array.new(@count) { |i| @buffer[(start + i) % @capacity] }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Remove and return the oldest element
|
|
47
|
+
#
|
|
48
|
+
# @return [Object, nil]
|
|
49
|
+
def shift
|
|
50
|
+
return nil if empty?
|
|
51
|
+
|
|
52
|
+
start = (@head - @count) % @capacity
|
|
53
|
+
value = @buffer[start]
|
|
54
|
+
@buffer[start] = nil
|
|
55
|
+
@count -= 1
|
|
56
|
+
value
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Remove and return the newest element
|
|
60
|
+
#
|
|
61
|
+
# @return [Object, nil]
|
|
62
|
+
def pop
|
|
63
|
+
return nil if empty?
|
|
64
|
+
|
|
65
|
+
newest_idx = (@head - 1) % @capacity
|
|
66
|
+
value = @buffer[newest_idx]
|
|
67
|
+
@buffer[newest_idx] = nil
|
|
68
|
+
@head = newest_idx
|
|
69
|
+
@count -= 1
|
|
70
|
+
value
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# Return the oldest element without removing it
|
|
74
|
+
#
|
|
75
|
+
# @return [Object, nil]
|
|
76
|
+
def oldest
|
|
77
|
+
return nil if empty?
|
|
78
|
+
|
|
79
|
+
@buffer[(@head - @count) % @capacity]
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Return the newest element without removing it
|
|
83
|
+
#
|
|
84
|
+
# @return [Object, nil]
|
|
85
|
+
def newest
|
|
86
|
+
return nil if empty?
|
|
87
|
+
|
|
88
|
+
@buffer[(@head - 1) % @capacity]
|
|
48
89
|
end
|
|
49
90
|
|
|
50
91
|
# Number of elements currently in the buffer
|
|
@@ -180,6 +221,36 @@ module Philiprehberger
|
|
|
180
221
|
end
|
|
181
222
|
end
|
|
182
223
|
|
|
224
|
+
# Change the buffer capacity, preserving elements
|
|
225
|
+
#
|
|
226
|
+
# If the new capacity is smaller than the current element count,
|
|
227
|
+
# the oldest elements are discarded and only the most recent
|
|
228
|
+
# new_capacity elements are kept.
|
|
229
|
+
#
|
|
230
|
+
# @param new_capacity [Integer] the new maximum number of elements
|
|
231
|
+
# @return [self]
|
|
232
|
+
def resize(new_capacity)
|
|
233
|
+
raise Error, 'capacity must be a positive integer' unless new_capacity.is_a?(Integer) && new_capacity.positive?
|
|
234
|
+
return self if new_capacity == @capacity
|
|
235
|
+
|
|
236
|
+
elements = to_a
|
|
237
|
+
elements = elements.last(new_capacity) if elements.length > new_capacity
|
|
238
|
+
|
|
239
|
+
@capacity = new_capacity
|
|
240
|
+
@buffer = Array.new(new_capacity)
|
|
241
|
+
@head = 0
|
|
242
|
+
@count = 0
|
|
243
|
+
elements.each { |e| push(e) }
|
|
244
|
+
self
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# Human-readable string representation
|
|
248
|
+
#
|
|
249
|
+
# @return [String]
|
|
250
|
+
def inspect
|
|
251
|
+
"#<#{self.class} capacity=#{@capacity} size=#{@count} elements=#{to_a.inspect}>"
|
|
252
|
+
end
|
|
253
|
+
|
|
183
254
|
# Iterate over elements (oldest first)
|
|
184
255
|
#
|
|
185
256
|
# @yield [element]
|
metadata
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: philiprehberger-ring_buffer
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Philip Rehberger
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-14 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: Fixed-capacity ring buffer that overwrites oldest entries on overflow,
|
|
14
|
-
with index access,
|
|
15
|
-
median), first/last-n retrieval, and
|
|
14
|
+
with index access, push/pop/shift mutation, oldest/newest peek, built-in statistics
|
|
15
|
+
(average, sum, min, max, variance, stddev, median), first/last-n retrieval, and
|
|
16
|
+
Enumerable support.
|
|
16
17
|
email:
|
|
17
18
|
- me@philiprehberger.com
|
|
18
19
|
executables: []
|