philiprehberger-ring_buffer 0.6.0 → 0.8.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 296d9b4ccfe2ca3cacba6bf34911e142381b0f8e40d2cdf0ed8f23432ff957a3
4
- data.tar.gz: cfe72d59c6b58f6d0be55488a17d1760c3914ecad2ed5a91bd2dc903c8d8c8a1
3
+ metadata.gz: 7c4971ce57872af1d067144dcc2f47be6361c2223b33f3d3fe64e52be9a5b436
4
+ data.tar.gz: da55e74cbcb7de740c01f7867f4667de5e605f64cb3d2c87e36dd7ab5cfe80ac
5
5
  SHA512:
6
- metadata.gz: 5268f470fe0f0ca1ba767f7e4c5c4f121686d2b6ae57a83b2aafae19600f88dc1dbef2b5a097001d407afeaa8d0e48613df80aafccf7cf745aff47b247fd8f7f
7
- data.tar.gz: 00c612791299049a02e35df9c4d3ff9fe8e0106beb37408b351df13a8875b7ea40b53540d61139f98ec814122dbee73bee7a6c62ba5b571dd7c1bf0101d9fe77
6
+ metadata.gz: c1d3172843fb04b1c5a1119899b1977cfaf1e4d8f04d5035615a05813cc364377f86b05dd2206e845582e23fa4eee273adfa7bd6f34a5b1f9fd4ebfdff531d91
7
+ data.tar.gz: c644de2e1a605a9675b318aae413e5de527ed08e51d2987ffd936bde5de97391ac8c005b60402799f605e01ff93f1281336a1659f3caf11d21f00628c6bbc7ff
data/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.8.0] - 2026-04-28
11
+
12
+ ### Added
13
+ - `RingBuffer#each_chunk(size)` — yield successive non-overlapping chunks of `size` elements (oldest first). Returns an Enumerator without a block. Raises `Error` for non-positive sizes.
14
+
15
+ ## [0.7.0] - 2026-04-21
16
+
17
+ ### Added
18
+ - `RingBuffer#range` — spread between min and max
19
+ - `RingBuffer#count_by` — bucketed counts by block return value
20
+
10
21
  ## [0.6.0] - 2026-04-15
11
22
 
12
23
  ### Added
@@ -91,6 +102,7 @@ and this gem adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
91
102
  - Last-n element retrieval
92
103
  - Enumerable support
93
104
 
105
+ [0.7.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.7.0
94
106
  [0.6.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.6.0
95
107
  [0.5.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.5.0
96
108
  [0.4.0]: https://github.com/philiprehberger/rb-ring-buffer/releases/tag/v0.4.0
data/README.md CHANGED
@@ -147,6 +147,16 @@ buf.moving_average(window: 3) # => [2.0, 3.0, 4.0]
147
147
  buf.ema(alpha: 0.5) # => 4.0625
148
148
  ```
149
149
 
150
+ ### Descriptive Helpers
151
+
152
+ ```ruby
153
+ buf = Philiprehberger::RingBuffer.new(10)
154
+ [1, 2, 3, 4, 5, 6].each { |v| buf.push(v) }
155
+
156
+ buf.range # => 5 (max - min)
157
+ buf.count_by(&:even?) # => { false => 3, true => 3 }
158
+ ```
159
+
150
160
  ### Random Sampling
151
161
 
152
162
  ```ruby
@@ -157,6 +167,22 @@ buf.sample # => random element
157
167
  buf.sample(2) # => [random, random]
158
168
  ```
159
169
 
170
+ ### Chunked Iteration
171
+
172
+ Yield successive non-overlapping chunks of fixed size in oldest-first order.
173
+ The final chunk may be shorter:
174
+
175
+ ```ruby
176
+ buf = Philiprehberger::RingBuffer.new(10)
177
+ (1..7).each { |v| buf.push(v) }
178
+
179
+ buf.each_chunk(2).to_a # => [[1, 2], [3, 4], [5, 6], [7]]
180
+
181
+ buf.each_chunk(3) do |chunk|
182
+ process_batch(chunk)
183
+ end
184
+ ```
185
+
160
186
  ### Enumerable
161
187
 
162
188
  ```ruby
@@ -198,6 +224,9 @@ buf.select(&:odd?) # => [1, 3]
198
224
  | `#median` | Median value |
199
225
  | `#moving_average(window:)` | Sliding window averages (oldest to newest) |
200
226
  | `#ema(alpha:)` | Exponential moving average (single float) |
227
+ | `#range` | Spread between min and max numeric elements |
228
+ | `#count_by(&block)` | Bucketed counts by block return value |
229
+ | `#each_chunk(size)` | Yield successive non-overlapping chunks of `size` elements (oldest first) |
201
230
 
202
231
  ## Development
203
232
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  class RingBuffer
5
- VERSION = '0.6.0'
5
+ VERSION = '0.8.0'
6
6
  end
7
7
  end
@@ -335,5 +335,48 @@ module Philiprehberger
335
335
  def each(&)
336
336
  to_a.each(&)
337
337
  end
338
+
339
+ # Spread between the minimum and maximum numeric elements
340
+ #
341
+ # @return [Numeric] the difference between max and min
342
+ # @raise [Error] if the buffer is empty
343
+ def range
344
+ raise Error, 'buffer is empty' if empty?
345
+
346
+ max - min
347
+ end
348
+
349
+ # Bucket elements by the block's return value and count each bucket
350
+ #
351
+ # Iterates oldest-to-newest via {#each}. An empty buffer returns `{}`.
352
+ #
353
+ # @yield [element] block whose return value is used as the bucket key
354
+ # @yieldparam element [Object] each element in oldest-to-newest order
355
+ # @return [Hash{Object => Integer}] bucket key to count mapping
356
+ # @return [Enumerator] if no block is given
357
+ def count_by(&block)
358
+ return enum_for(:count_by) unless block
359
+
360
+ result = Hash.new(0)
361
+ each { |element| result[block.call(element)] += 1 }
362
+ result
363
+ end
364
+
365
+ # Yield successive non-overlapping chunks of `size` elements (oldest first)
366
+ #
367
+ # The final chunk may be shorter than `size` if the buffer length is not
368
+ # a multiple of `size`. An empty buffer yields nothing.
369
+ #
370
+ # @param size [Integer] chunk size (must be positive)
371
+ # @yield [chunk] each chunk in oldest-to-newest order
372
+ # @yieldparam chunk [Array] up to `size` elements
373
+ # @return [Enumerator] when no block is given
374
+ # @raise [Error] when `size` is not a positive integer
375
+ def each_chunk(size, &block)
376
+ raise Error, 'size must be a positive integer' unless size.is_a?(Integer) && size.positive?
377
+ return enum_for(:each_chunk, size) unless block
378
+
379
+ to_a.each_slice(size, &block)
380
+ end
338
381
  end
339
382
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-ring_buffer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.8.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-16 00:00:00.000000000 Z
11
+ date: 2026-04-29 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Fixed-capacity ring buffer that overwrites oldest entries on overflow,
14
14
  with index access, push/pop/shift mutation, oldest/newest peek, built-in statistics