Skip to content

Commit c1893b1

Browse files
authored
Merge pull request #3 from Alokzh/refactor-buffer-implementation
Refactor buffer implementation to include FIFO & LIFO Variations
2 parents 71de9ba + 3a7ada5 commit c1893b1

6 files changed

Lines changed: 932 additions & 256 deletions

File tree

README.md

Lines changed: 84 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Containers-Buffer
2-
A Circular Buffer implementation providing efficient temporary storage with fixed capacity and automatic wraparound functionality.
2+
A Circular Buffer implementation providing efficient temporary storage with fixed capacity and automatic wraparound functionality. Available in both FIFO (First In, First Out) and LIFO (Last In, First Out) variants.
33

44
![Pharo Version](https://img.shields.io/badge/Pharo-10+-blue)
55
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](LICENSE)
@@ -8,6 +8,30 @@ A Circular Buffer implementation providing efficient temporary storage with fixe
88

99
A Buffer (also known as a circular buffer or ring buffer) is a data structure that uses a fixed-size array as if it were connected end-to-end. It provides efficient insertion and removal operations with constant time complexity O(1). When the buffer reaches its maximum capacity, new elements overwrite the oldest ones, making it perfect for streaming data and producer-consumer scenarios.
1010

11+
### We provide two types of buffers:
12+
- FIFO Buffer - First In, First Out (Queue behavior)
13+
- LIFO Buffer - Last In, First Out (Stack behavior)
14+
15+
## Loading
16+
The following script installs Containers-Buffer in Pharo.
17+
18+
```smalltalk
19+
Metacello new
20+
baseline: 'ContainersBuffer';
21+
repository: 'github://pharo-containers/Containers-Buffer/src';
22+
load.
23+
```
24+
25+
## If you want to depend on it
26+
27+
Add the following code to your Metacello baseline or configuration
28+
29+
```smalltalk
30+
spec
31+
baseline: 'ContainersBuffer'
32+
with: [ spec repository: 'github://pharo-containers/Containers-Buffer/src' ].
33+
```
34+
1135
## Why use Containers-Buffer?
1236
Buffers solve a critical problem in modern applications: **handling continuous data streams safely**. Perfect for keeping "recent N items" automatically without memory bloat or performance degradation.
1337

@@ -16,35 +40,81 @@ Buffers solve a critical problem in modern applications: **handling continuous d
1640
- **O(1) Performance**: Lightning-fast operations regardless of data volume
1741
- **Zero Memory Leaks**: Automatic cleanup of old data
1842
- **Streaming Optimized**: Designed for continuous data flow
43+
- **Flexible Ordering**: Choose FIFO or LIFO based on your needs
44+
45+
46+
## FIFO Buffer Use Cases
1947

2048
### Chat Applications
49+
This example demonstrates how to use a FIFO buffer to maintain a chat history, automatically removing the oldest messages when new ones are added.
50+
2151
```smalltalk
2252
"Chat room - keep last 50 messages automatically"
23-
chat := CTBuffer withCapacity: 50.
53+
chat := CTFIFOBuffer withCapacity: 50.
2454
25-
chat put: 'User1: Hello everyone!'.
26-
chat put: 'User2: How are you doing?'.
55+
chat push: 'User1: Hello everyone!'.
56+
chat push: 'User2: How are you doing?'.
2757
2858
"... more messages flow in ..."
29-
chat put: 'User3: Good morning!'. "Oldest message automatically removed"
59+
chat push: 'User3: Good morning!'. "Oldest message automatically removed"
3060
3161
"Always has recent 50 messages, zero manual cleanup"
3262
```
3363

3464
### File Processing in Chunks
65+
This example shows how to process large files in manageable chunks without loading the entire file into memory, using a FIFO buffer to handle data efficiently.
66+
3567
```smalltalk
3668
"Process massive files without loading everything into memory"
37-
fileBuffer := CTBuffer withCapacity: 1024. "1KB processing chunks"
69+
fileBuffer := CTFIFOBuffer withCapacity: 1024. "1KB processing chunks"
3870
stream := 'huge-dataset.csv' asFileReference readStream.
3971
[ stream atEnd ] whileFalse: [
4072
chunk := stream next: 1024.
41-
fileBuffer put: chunk.
42-
self processDataChunk: fileBuffer get "Process and auto-remove"
73+
fileBuffer push: chunk.
74+
self processDataChunk: fileBuffer pop "Process and auto-remove"
4375
].
4476
4577
"Memory usage stays constant - handles files of any size!"
4678
```
4779

80+
## LIFO Buffer Use Cases
81+
82+
### Undo/Redo Functionality
83+
This example shows how to implement undo/redo functionality in an editor using a LIFO buffer, allowing users to revert their last actions easily.
84+
85+
```smalltalk
86+
"Implementing undo/redo in an editor"
87+
undoBuffer := CTLIFOBuffer withCapacity: 20. "Keep last 20 actions"
88+
undoBuffer push: 'Hello World'.
89+
undoBuffer push: 'Add bold formatting'.
90+
undoBuffer push: 'Add italic formatting'.
91+
92+
"User presses undo"
93+
lastAction := undoBuffer pop. "Returns 'Add italic formatting' and removes it"
94+
95+
"User can redo by pushing it back"
96+
undoBuffer push: lastAction. "Puts 'Add italic formatting' back on top"
97+
"Now 'Add italic formatting' is on top, ready to be undone next"
98+
```
99+
100+
### Browser History
101+
This example demonstrates how to implement a simple browser history using a LIFO buffer, allowing users to navigate back through their most recent pages.
102+
103+
```smalltalk
104+
"Browser back button - show most recent pages first"
105+
browserHistory := CTLIFOBuffer withCapacity: 20.
106+
107+
browserHistory push: 'https://pharo.org'.
108+
browserHistory push: 'https://github.com/pharo-containers'.
109+
browserHistory push: 'https://stackoverflow.com/questions/...'.
110+
111+
"Back button gets most recent page"
112+
previousPage := browserHistory pop. "Gets 'https://stackoverflow.com/questions/...' (most recent)"
113+
previousPage := browserHistory pop. "Gets 'https://github.com/pharo-containers' (second most recent)"
114+
previousPage := browserHistory pop. "Gets 'https://pharo.org' (third most recent)"
115+
```
116+
117+
48118
### Performance Degradation
49119
```smalltalk
50120
"OrderedCollection - Gets slower and slower"
@@ -58,43 +128,20 @@ log := OrderedCollection new.
58128
"Performance degrades from 1ms to 100ms+ per operation"
59129
60130
"Buffer - Lightning fast forever"
61-
log := CTBuffer withCapacity: 1000.
131+
log := CTFIFOBuffer withCapacity: 1000.
62132
1 to: 100000 do: [ :i |
63-
log put: 'entry ', i asString. "O(1) operation - always instant!"
133+
log push: 'entry ', i asString. "O(1) operation - always instant!"
64134
].
65135
66136
"Consistent 0.01ms performance whether it's operation #10 or #10,000,000"
67137
```
68-
69-
### Performance Comparison
70-
71-
| Operation | OrderedCollection | Array | CTBuffer |
72-
|-----------|------------------|--------|----------|
73-
| Add item | O(1) | O(n)* | O(1) |
138+
### Comparison
139+
| Operation | OrderedCollection | Array | CTFIFOBuffer |
140+
|-----------|------------------|--------|-------------|
141+
| Add item | O(1) | O(1) | O(1) |
74142
| Remove old | O(n) | O(n) | O(1) |
75143
| Memory usage | Unlimited growth | Fixed/reallocated | Fixed |
76-
| Cache efficiency | Poor (fragmented) | Good | Excellent |
77-
78144

79-
## Loading
80-
The following script installs Containers-Buffer in Pharo.
81-
82-
```smalltalk
83-
Metacello new
84-
baseline: 'ContainersBuffer';
85-
repository: 'github://pharo-containers/Containers-Buffer/src';
86-
load.
87-
```
88-
89-
## If you want to depend on it
90-
91-
Add the following code to your Metacello baseline or configuration
92-
93-
```smalltalk
94-
spec
95-
baseline: 'ContainersBuffer'
96-
with: [ spec repository: 'github://pharo-containers/Containers-Buffer/src' ].
97-
```
98145

99146
## Contributing
100147

0 commit comments

Comments
 (0)