Skip to content
Open
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
72 changes: 47 additions & 25 deletions src/Containers-Queue-Tests/CTQueueTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,18 @@ I'm a simple queue i.e., first in first out structure.
I support basic collection protocol and in addition enqueue and dequeue as in Scala.
"
Class {
#name : #CTQueueTest,
#superclass : #TestCase,
#category : #'Containers-Queue-Tests'
#name : 'CTQueueTest',
#superclass : 'TestCase',
#category : 'Containers-Queue-Tests',
#package : 'Containers-Queue-Tests'
}

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> queueClass [
^ CTQueue
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAdd [
| queue |
queue := self queueClass new.
Expand All @@ -23,7 +24,7 @@ CTQueueTest >> testAdd [
self assert: (queue includes: 2)
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAddAll [
"Ensure queueAll adds multiple elements at once."
| queue |
Expand All @@ -35,7 +36,7 @@ CTQueueTest >> testAddAll [
self assert: queue remove equals: 40.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAddAllLargeCollection [
"Test adding a large collection via addAll."
| queue collection size |
Expand All @@ -48,7 +49,7 @@ CTQueueTest >> testAddAllLargeCollection [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAddGarantyFIFOOrder [
"Ensure elements are dequeued in FIFO order."
| queue |
Expand All @@ -62,7 +63,7 @@ CTQueueTest >> testAddGarantyFIFOOrder [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAddNilElement [
"Test adding a nil element to the queue."
| queue |
Expand All @@ -74,7 +75,28 @@ CTQueueTest >> testAddNilElement [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testAddUnless [
| queue |
queue := self queueClass new.
queue add: 1 unless: [ :v | (v rem: 2) = 0].
self assert: (queue includes: 1).
self assert: queue size equals: 1 .
queue add: 2 unless: [ :v | (v rem: 2) = 0].
self assert: (queue includes: 1).
self assert: (queue includes: 2) .
self assert: queue size equals: 2 .
queue add: 4 unless: [ :v | (v rem: 2) = 0].
self assert: (queue includes: 1).
self assert: (queue includes: 2) .
self assert: queue size equals: 2 .
queue add: 3 unless: [ :v | (v rem: 2) = 0].
self assert: (queue includes: 1).
self assert: (queue includes: 2) .
self assert: queue size equals: 2
]

{ #category : 'tests' }
CTQueueTest >> testDoIteration [
"Test iterating over the queue with do: in FIFO order."
| queue collected |
Expand All @@ -86,19 +108,19 @@ CTQueueTest >> testDoIteration [
self assert: queue size equals: 4. "Iteration should not modify the queue"
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testEmptyQueue [
self assert: self queueClass new isEmpty
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testEmptyQueueRemove [
| queue |
queue := self queueClass new.
self assert: queue remove isNil.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testIncludes [
"Test the includes: method for existing and non-existing elements."
| queue |
Expand All @@ -109,7 +131,7 @@ CTQueueTest >> testIncludes [
self assert: queue size equals: 3. "includes: should not modify the queue"
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testInterleavedAddRemove [
"Test interleaved add and remove operations to ensure FIFO order and correctness."
| queue |
Expand All @@ -125,7 +147,7 @@ CTQueueTest >> testInterleavedAddRemove [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testIsEmpty [
"Ensure isEmpty works correctly."
| queue |
Expand All @@ -137,7 +159,7 @@ CTQueueTest >> testIsEmpty [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testLargeQueuePerformance [
"Verify FIFO behavior and performance with a large queue."
| queue size startTime endTime duration maxDuration |
Expand All @@ -162,7 +184,7 @@ CTQueueTest >> testLargeQueuePerformance [
self assert: queue isEmpty.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testPeek [
"Ensure peek returns the first element without removing it."
| queue |
Expand All @@ -173,7 +195,7 @@ CTQueueTest >> testPeek [
self assert: queue size equals: 2. "Peek should not remove elements"
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testPoll [
"Ensure poll behaves correctly, returning nil when empty."
| queue |
Expand All @@ -185,17 +207,17 @@ CTQueueTest >> testPoll [
self assert: queue poll isNil.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testQueue [
self assert: self queueClass new isEmpty
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testQueueGarantyFIFOOrder [
self assert: self queueClass new isEmpty
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testRemove [
"Ensure remove behaves correctly, returning nil when empty."
| queue |
Expand All @@ -207,7 +229,7 @@ CTQueueTest >> testRemove [
self assert: queue remove equals: 2
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testRemoveIfNone [
"Ensure removeIfNone works correctly."
| queue result |
Expand All @@ -216,7 +238,7 @@ CTQueueTest >> testRemoveIfNone [
self assert: result equals: 'fallback'.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testSizeAccuracy [
"Test that the size method accurately reflects the number of elements."
| queue |
Expand All @@ -232,7 +254,7 @@ CTQueueTest >> testSizeAccuracy [
self assert: queue size equals: 2.
]

{ #category : #tests }
{ #category : 'tests' }
CTQueueTest >> testStressAddRemove [
"Stress test with many add and remove operations."
| queue iterations |
Expand All @@ -248,4 +270,4 @@ CTQueueTest >> testStressAddRemove [
queue addAll: (1 to: 1000).
1 to: 1000 do: [ :i | self assert: queue remove equals: i ].
self assert: queue isEmpty.
]
]
2 changes: 1 addition & 1 deletion src/Containers-Queue-Tests/package.st
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Package { #name : #'Containers-Queue-Tests' }
Package { #name : 'Containers-Queue-Tests' }
56 changes: 41 additions & 15 deletions src/Containers-Queue/CTQueue.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
I'm a simple FIFO queue i.e., first in first out structure. I support basic collection protocol with efficient O(1) add and remove operations using a singly linked list.
"
Class {
#name : #CTQueue,
#superclass : #Object,
#name : 'CTQueue',
#superclass : 'Object',
#instVars : [
'head',
'tail',
'size'
],
#category : #'Containers-Queue'
#category : 'Containers-Queue',
#package : 'Containers-Queue'
}

{ #category : #adding }
{ #category : 'adding' }
CTQueue >> add: anElement [
"Add an element to the end of the queue (FIFO order)."
| newNode |
Expand All @@ -28,14 +29,39 @@ CTQueue >> add: anElement [
^ anElement
]

{ #category : #adding }
{ #category : 'adding' }
CTQueue >> add: anElement unless: aTestIsTrue [
"Add an element to the end of the queue (FIFO order)."
| newNode |

head ifNil: [
newNode := CTQueueNode new value: anElement.
head := newNode.
tail := newNode.
] ifNotNil: [
|current|
current := head .
[ current = tail ] whileFalse: [
(aTestIsTrue value: current value) ifTrue: [ ^ current value ] .
current := current next
] .
(aTestIsTrue value: tail value) ifTrue: [ ^ tail value ] .
newNode := CTQueueNode new value: anElement.
tail next: newNode.
tail := newNode.
].
size := size + 1.
^ anElement
]

{ #category : 'adding' }
CTQueue >> addAll: aCollection [
"Add all elements from aCollection to the end of the queue."
aCollection do: [ :each | self add: each ].
^ aCollection
]

{ #category : #iterating }
{ #category : 'iterating' }
CTQueue >> do: aBlock [
"Iterate over elements in FIFO order."
| current |
Expand All @@ -46,7 +72,7 @@ CTQueue >> do: aBlock [
]
]

{ #category : #testing }
{ #category : 'testing' }
CTQueue >> includes: anElement [
"Check if anElement exists in the queue."
| current |
Expand All @@ -58,7 +84,7 @@ CTQueue >> includes: anElement [
^ false
]

{ #category : #initialization }
{ #category : 'initialization' }
CTQueue >> initialize [
"Initialize an empty queue."
super initialize.
Expand All @@ -67,25 +93,25 @@ CTQueue >> initialize [
size := 0.
]

{ #category : #testing }
{ #category : 'testing' }
CTQueue >> isEmpty [
"Return true if the queue is empty."
^ head isNil
]

{ #category : #accessing }
{ #category : 'accessing' }
CTQueue >> peek [
"Return the front element without removing it, or nil if empty."
^ head ifNil: [ nil ] ifNotNil: [ head value ]
]

{ #category : #removing }
{ #category : 'removing' }
CTQueue >> poll [
"Return and remove the front element, or nil if empty."
^ self remove
]

{ #category : #removing }
{ #category : 'removing' }
CTQueue >> remove [
"Return and remove the oldest element, or nil if empty."
| value |
Expand All @@ -97,15 +123,15 @@ CTQueue >> remove [
^ value
]

{ #category : #removing }
{ #category : 'removing' }
CTQueue >> removeIfNone: aBlock [
"Return and remove the oldest element, or evaluate aBlock if empty."
head ifNil: [ ^ aBlock value ].
^ self remove
]

{ #category : #accessing }
{ #category : 'accessing' }
CTQueue >> size [
"Return the number of elements in the queue."
^ size
]
]
17 changes: 9 additions & 8 deletions src/Containers-Queue/CTQueueNode.class.st
Original file line number Diff line number Diff line change
@@ -1,29 +1,30 @@
Class {
#name : #CTQueueNode,
#superclass : #Object,
#name : 'CTQueueNode',
#superclass : 'Object',
#instVars : [
'value',
'next'
],
#category : #'Containers-Queue'
#category : 'Containers-Queue',
#package : 'Containers-Queue'
}

{ #category : #accessing }
{ #category : 'accessing' }
CTQueueNode >> next [
^ next
]

{ #category : #accessing }
{ #category : 'accessing' }
CTQueueNode >> next: aNode [
next := aNode
]

{ #category : #accessing }
{ #category : 'accessing' }
CTQueueNode >> value [
^ value
]

{ #category : #accessing }
{ #category : 'accessing' }
CTQueueNode >> value: anObject [
value := anObject
]
]
2 changes: 1 addition & 1 deletion src/Containers-Queue/package.st
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Package { #name : #'Containers-Queue' }
Package { #name : 'Containers-Queue' }