Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions Pharo64-12.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><testsuite name="Pharo64-12" tests="13" failures="0" errors="0" time="0.01"> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testAddGarantyFIFOOrder" time="0.002"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testIsEmpty" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testQueueGarantyFIFOOrder" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testPeek" time="0.001"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testAddAll" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testEmptyQueue" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testLargeQueuePerformance" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testAdd" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testQueue" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testRemove" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testEmptyQueueRemove" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testRemoveIfNone" time="0.0"></testcase> <testcase classname="Containers.Queue.Tests.CTQueueTest" name="testPoll" time="0.0"></testcase> <system-out><![CDATA[]]></system-out> <system-err><![CDATA[]]></system-err></testsuite>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this file?

Expand Down
11 changes: 11 additions & 0 deletions src/Containers-Queue-Tests/CTQueueTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -127,4 +127,15 @@ CTQueueTest >> testRemoveIfNone[
queue := self queueClass new.
result := queue removeIfNone: [ 'fallback' ].
self assert: result equals: 'fallback'.
]

{ #category : #tests }
CTQueueTest >> testLargeQueuePerformance [
"Verify FIFO behavior and performance with a large queue."
| queue size |
queue := self queueClass new.
size := 1000.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would say that 1000 is not that large

1 to: size do: [ :i | queue add: i ].
1 to: size do: [ :i | self assert: queue remove equals: i ].
self assert: queue isEmpty.
]
96 changes: 61 additions & 35 deletions src/Containers-Queue/CTQueue.class.st
Original file line number Diff line number Diff line change
@@ -1,85 +1,111 @@
"
I'm a simple FIFO queue i.e., first in first out structure. I support basic collection protocol and in addition enqueue and dequeue as in Scala.
My basic support of collection API should be reviewd and probably improved (should check atomic queue protocol).


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,
#instVars : [
'elements'
'head',
'tail',
'size'
],
#category : #'Containers-Queue'
}

{ #category : #adding }
CTQueue >> add: anElement [
"Add an element to the receiver. Note that the addition makes sure that when iterating over the receiver added first element are accessed first."

elements addLast: anElement.
"Add an element to the end of the queue (FIFO order)."
| newNode |
newNode := CTQueueNode new value: anElement.
head ifNil: [
head := newNode.
tail := newNode.
] ifNotNil: [
tail next: newNode.
tail := newNode.
].
size := size + 1.
^ anElement
]

{ #category : #adding }
CTQueue >> addAll: aCollection [
"Add the elements contained in the argument to the receiver. Note that the addition makes sure that when iterating over the receiver added first element are accessed first."

elements addAllLast: aCollection.
"Add all elements from aCollection to the end of the queue."
aCollection do: [ :each | self add: each ].
^ aCollection
]

{ #category : #iterating }
CTQueue >> do: aBlock [
"iterates the elements of the receiver starting first by first added elements."

elements do: aBlock
"Iterate over elements in FIFO order."
| current |
current := head.
[ current notNil ] whileTrue: [
aBlock value: current value.
current := current next.
]
]

{ #category : #testing }
CTQueue >> includes: anElement [

^ elements includes: anElement
"Check if anElement exists in the queue."
| current |
current := head.
[ current notNil ] whileTrue: [
current value = anElement ifTrue: [ ^ true ].
current := current next.
].
^ false
]

{ #category : #initialization }
CTQueue >> initialize [
"Initialize an empty queue."
super initialize.
elements := OrderedCollection new.
head := nil.
tail := nil.
size := 0.
]

{ #category : #testing }
CTQueue >> isEmpty [

^ elements isEmpty
"Return true if the queue is empty."
^ head isNil
]

{ #category : #removing }
CTQueue >> remove [
"Return the older element of the receiver.."

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

{ #category : #removing }
CTQueue >> removeIfNone: aBlock [
"Return the older element of the receiver.."
elements ifEmpty: [ ^ aBlock value ].
^ elements removeFirst
CTQueue >> poll [
"Return and remove the front element, or nil if empty."
^ self remove
]

{ #category : #removing }
CTQueue >> poll [
"Returns and removes the front element, or nil if empty."
^ elements ifEmpty: [ nil ] ifNotEmpty: [ elements removeFirst ].
CTQueue >> remove [
"Return and remove the oldest element, or nil if empty."
| value |
head ifNil: [ ^ nil ].
value := head value.
head := head next.
head ifNil: [ tail := nil ].
size := size - 1.
^ value
]

{ #category : #accessing }
CTQueue >> peek [
^ elements ifEmpty: [ nil ] ifNotEmpty: [ elements first ].
{ #category : #removing }
CTQueue >> removeIfNone: aBlock [
"Return and remove the oldest element, or evaluate aBlock if empty."
head ifNil: [ ^ aBlock value ].
^ self remove
]

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

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

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

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

{ #category : #accessing }
CTQueueNode >> value: anObject [
value := anObject
]
Loading