Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ This example demonstrates how to use a FIFO buffer to maintain a chat history, a

```smalltalk
"Chat room - keep last 50 messages automatically"
chat := CTFIFOBuffer withCapacity: 50.
chat := CTFIFOBuffer new: 50.

chat push: 'User1: Hello everyone!'.
chat push: 'User2: How are you doing?'.
Expand All @@ -68,7 +68,7 @@ This example shows how to implement undo/redo functionality in an editor using a

```smalltalk
"Implementing undo/redo in an editor"
undoBuffer := CTLIFOBuffer withCapacity: 20. "Keep last 20 actions"
undoBuffer := CTLIFOBuffer new: 20. "Keep last 20 actions"
undoBuffer push: 'Hello World'.
undoBuffer push: 'Add bold formatting'.
undoBuffer push: 'Add italic formatting'.
Expand All @@ -86,7 +86,7 @@ This example demonstrates how to implement a simple browser history using a LIFO

```smalltalk
"Browser back button - show most recent pages first"
browserHistory := CTLIFOBuffer withCapacity: 20.
browserHistory := CTLIFOBuffer new: 20.

browserHistory push: 'https://pharo.org'.
browserHistory push: 'https://github.com/pharo-containers'.
Expand All @@ -111,7 +111,7 @@ log := OrderedCollection new.
].

"Buffer - Fast and automatic"
log := CTFIFOBuffer withCapacity: 1000.
log := CTFIFOBuffer new: 1000.
1 to: 100000 do: [ :i |
log push: 'entry ', i asString. "O(1) operation - Automatic Management !"
].
Expand Down
12 changes: 6 additions & 6 deletions docs/Circular_Buffer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ A Circular buffer is a fixed-size data structure that automatically overwrites t

```smalltalk
"Circular buffer approach - elegant and efficient"
recentMessages := CTFIFOBuffer withCapacity: 100.
recentMessages := CTFIFOBuffer new: 100.
recentMessages push: newMessage. "That's it! Always O(1) & No Manual Cleanup"
```

Expand All @@ -46,7 +46,7 @@ FIFO buffers work like a queue - the first element added is the first one retrie

### Dry Run Example
```smalltalk
buffer := CTFIFOBuffer withCapacity: 2.
buffer := CTFIFOBuffer new: 2.
buffer push: 'A'. "Buffer state: [A, _] readIndex=1, writeIndex=2"
buffer push: 'B'. "Buffer state: [A, B] readIndex=1, writeIndex=1"
buffer push: 'C'. "Buffer state: [C, B] readIndex=2, writeIndex=2 (A overwritten)"
Expand All @@ -60,7 +60,7 @@ buffer pop. "Returns 'C', Buffer state: [_, _] (empty)"

```smalltalk
"Chat room that keeps last 4 messages for display"
chatHistory := CTFIFOBuffer withCapacity: 4.
chatHistory := CTFIFOBuffer new: 4.

"Users send messages throughout the day"
chatHistory push: 'Alok: Hello everyone!'.
Expand Down Expand Up @@ -100,7 +100,7 @@ LIFO buffers work like a stack - the last element added is the first one retriev

### Dry Run Example
```smalltalk
buffer := CTLIFOBuffer withCapacity: 2.
buffer := CTLIFOBuffer new: 2.
buffer push: 'A'. "Buffer state: [A, _] readIndex=1, writeIndex=2"
buffer push: 'B'. "Buffer state: [A, B] readIndex=2, writeIndex=1"
buffer push: 'C'. "Buffer state: [C, B] readIndex=1, writeIndex=2 (A overwritten)"
Expand All @@ -114,7 +114,7 @@ buffer pop. "Returns 'B', Buffer state: [_, _] (empty)"

```smalltalk
"Browser that remembers last 3 visited pages"
browserHistory := CTLIFOBuffer withCapacity: 3.
browserHistory := CTLIFOBuffer new: 3.

"User browses during the day"
browserHistory push: 'https://pharo.org'.
Expand Down Expand Up @@ -180,7 +180,7 @@ Transcript show: 'Average result after running each benchmark for 100 times...';

bufferResults add: ([
| buffer |
buffer := CTFIFOBuffer withCapacity: capacity.
buffer := CTFIFOBuffer new: capacity.
1 to: totalOperations do: [ :i |
buffer push: i.
].
Expand Down
22 changes: 14 additions & 8 deletions src/Containers-Buffer-Tests/CTAbstractBufferTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ CTAbstractBufferTest >> testAvailableSpace [
CTAbstractBufferTest >> testBufferCreationWithCapacity [

| testBuffer |
testBuffer := buffer class withCapacity: 5.
testBuffer := buffer class new: 5.

self assert: testBuffer capacity equals: 5.
self assert: testBuffer size equals: 0.
self assert: testBuffer isEmpty.
Expand All @@ -53,9 +53,12 @@ CTAbstractBufferTest >> testBufferCreationWithInvalidCapacity [
{ #category : 'tests' }
CTAbstractBufferTest >> testClearBuffer [

buffer push: 'a'; push: 'b'; push: 'c'.
buffer clear.

buffer
push: 'a';
push: 'b';
push: 'c'.
buffer removeAll.

self assert: buffer isEmpty.
self assert: buffer size equals: 0.
self assert: buffer readIndex equals: 1.
Expand Down Expand Up @@ -100,10 +103,13 @@ CTAbstractBufferTest >> testEmptyBufferErrors [
{ #category : 'tests' }
CTAbstractBufferTest >> testIndicesAfterClear [

buffer push: 'a'; push: 'b'; push: 'c'.
buffer
push: 'a';
push: 'b';
push: 'c'.
buffer pop.
buffer clear.
buffer removeAll.

self assert: buffer readIndex equals: 1.
self assert: buffer writeIndex equals: 1
]
Expand Down
13 changes: 7 additions & 6 deletions src/Containers-Buffer-Tests/CTFIFOBufferTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,30 @@ Class {

{ #category : 'running' }
CTFIFOBufferTest >> setUp [

super setUp.
buffer := CTFIFOBuffer withCapacity: 3
buffer := CTFIFOBuffer new: 3
]

{ #category : 'tests' }
CTFIFOBufferTest >> testChatMessageQueue [

| chatQueue displayedMessages |
chatQueue := CTFIFOBuffer withCapacity: 4.
chatQueue := CTFIFOBuffer new: 4.
displayedMessages := OrderedCollection new.

chatQueue push: 'Alok: Hello everyone!'.
chatQueue push: 'Sebastian: Hey Alok!'.
chatQueue push: 'Gordana: How is everyone doing?'.
chatQueue push: 'Sebastian: Great to see you all!'.

displayedMessages add: chatQueue pop.
self assert: displayedMessages last equals: 'Alok: Hello everyone!'.

chatQueue push: 'Alok: Sorry I was late!'.
[ chatQueue isEmpty ] whileFalse: [
displayedMessages add: chatQueue pop ].

self assert: displayedMessages size equals: 5.
self assert: (displayedMessages at: 2) equals: 'Sebastian: Hey Alok!'.
self assert: displayedMessages last equals: 'Alok: Sorry I was late!'
Expand Down
21 changes: 12 additions & 9 deletions src/Containers-Buffer-Tests/CTLIFOBufferTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -11,34 +11,37 @@ Class {

{ #category : 'running' }
CTLIFOBufferTest >> setUp [
super setUp.
buffer := CTLIFOBuffer withCapacity: 3

super setUp.
buffer := CTLIFOBuffer new: 3
]

{ #category : 'tests' }
CTLIFOBufferTest >> testBrowserHistory [

| browserHistory visitedPages |
browserHistory := CTLIFOBuffer withCapacity: 3.
| browserHistory visitedPages |
browserHistory := CTLIFOBuffer new: 3.
visitedPages := OrderedCollection new.

browserHistory push: 'https://google.com'.
browserHistory push: 'https://github.com/pharo-containers'.
browserHistory push: 'https://stackoverflow.com'.
browserHistory push: 'https://reddit.com'.

visitedPages add: browserHistory pop.
self assert: visitedPages last equals: 'https://reddit.com'.

browserHistory push: 'https://pharo.org'.
[ browserHistory isEmpty ] whileFalse: [
visitedPages add: browserHistory pop ].

self assert: visitedPages size equals: 4.
self assert: visitedPages first equals: 'https://reddit.com'.
self assert: (visitedPages at: 2) equals: 'https://pharo.org'.
self assert: (visitedPages at: 3) equals: 'https://stackoverflow.com'.
self assert: visitedPages last equals: 'https://github.com/pharo-containers'
self
assert: visitedPages last
equals: 'https://github.com/pharo-containers'
]

{ #category : 'tests' }
Expand Down
57 changes: 33 additions & 24 deletions src/Containers-Buffer/CTAbstractBuffer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,21 @@ Class {
}

{ #category : 'instance creation' }
CTAbstractBuffer class >> withCapacity: anInteger [
CTAbstractBuffer class >> new [

"Create a new buffer with default capacity"

^ self new: 10
]

{ #category : 'instance creation' }
CTAbstractBuffer class >> new: anInteger [

"Create a new buffer with the specified capacity"

anInteger < 1 ifTrue: [ self error: 'Capacity must be positive' ].
^ self new
capacity: anInteger;
^ self basicNew
initializeWithCapacity: anInteger;
yourself
]

Expand All @@ -40,24 +50,6 @@ CTAbstractBuffer >> capacity [
^ capacity
]

{ #category : 'accessing' }
CTAbstractBuffer >> capacity: anInteger [

capacity := anInteger.
elements := Array new: capacity
]

{ #category : 'actions' }
CTAbstractBuffer >> clear [

"Remove all elements from the buffer"

1 to: capacity do: [ :i | elements at: i put: nil ].
readIndex := 1.
writeIndex := 1.
currentSize := 0
]

{ #category : 'copying' }
CTAbstractBuffer >> copy [

Expand All @@ -80,7 +72,13 @@ CTAbstractBuffer >> elements [
CTAbstractBuffer >> initialize [

super initialize.
capacity := 10.
self initializeWithCapacity: 10
]

{ #category : 'private' }
CTAbstractBuffer >> initializeWithCapacity: anInteger [

capacity := anInteger.
elements := Array new: capacity.
readIndex := 1.
writeIndex := 1.
Expand Down Expand Up @@ -130,7 +128,7 @@ CTAbstractBuffer >> pop [
^ element
]

{ #category : 'testing' }
{ #category : 'adding' }
CTAbstractBuffer >> push: anObject [
"Add an element to the buffer"

Expand Down Expand Up @@ -159,7 +157,7 @@ CTAbstractBuffer >> push: anObject [
^ anObject
]

{ #category : 'testing' }
{ #category : 'adding' }
CTAbstractBuffer >> pushAll: aCollection [

aCollection do: [ :e | self push: e ].
Expand All @@ -173,6 +171,17 @@ CTAbstractBuffer >> readIndex [
^ readIndex
]

{ #category : 'removing' }
CTAbstractBuffer >> removeAll [

"Remove all elements from the buffer"

1 to: capacity do: [ :i | elements at: i put: nil ].
readIndex := 1.
writeIndex := 1.
currentSize := 0
]

{ #category : 'accessing' }
CTAbstractBuffer >> size [

Expand Down
2 changes: 1 addition & 1 deletion src/Containers-Buffer/CTFIFOBuffer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Class {
CTFIFOBuffer >> copy [

| copy |
copy := self class withCapacity: capacity.
copy := self class new: capacity.
self do: [ :each | copy push: each ].
^ copy
]
Expand Down
16 changes: 8 additions & 8 deletions src/Containers-Buffer/CTLIFOBuffer.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ CTLIFOBuffer >> copy [
"Return a copy of the LIFO buffer with same contents and order"

| copy index |
copy := self class withCapacity: capacity.
copy := self class new: capacity.
self isEmpty ifTrue: [ ^ copy ].

index := readIndex.
(currentSize - 1) timesRepeat: [
index := index = 1 ifTrue: [ capacity ] ifFalse: [ index - 1 ]
].

currentSize - 1 timesRepeat: [
index := index = 1
ifTrue: [ capacity ]
ifFalse: [ index - 1 ] ].

currentSize timesRepeat: [
copy push: (elements at: index).
index := index \\ capacity + 1
].
copy push: (elements at: index).
index := index \\ capacity + 1 ].
^ copy
]

Expand Down
Loading