From 07b5c7c7998aee25a3c69606034236e684042625 Mon Sep 17 00:00:00 2001 From: Sneharaj7645653 Date: Fri, 28 Mar 2025 13:05:09 +0530 Subject: [PATCH 1/5] grow improved --- .../CTSmallOrderedSet.class.st | 49 ++++++++++--------- .../CTSmallOrderedSetTest.class.st | 35 ++++++------- src/Containers-SmallOrderedSet/package.st | 2 +- 3 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st index a396016..9829ef6 100644 --- a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st +++ b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st @@ -2,47 +2,48 @@ I am an implementation of an ordered set. Compared to other sets I am very efficient for small sizes, speed- and space-wise. I also mantain the order in which elements are added when iterating. " Class { - #name : #CTSmallOrderedSet, - #superclass : #Object, + #name : 'CTSmallOrderedSet', + #superclass : 'Object', #instVars : [ 'size', 'table' ], - #category : #'Containers-SmallOrderedSet' + #category : 'Containers-SmallOrderedSet', + #package : 'Containers-SmallOrderedSet' } -{ #category : #'instance creation' } +{ #category : 'instance creation' } CTSmallOrderedSet class >> new [ ^ self new: 3 ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } CTSmallOrderedSet class >> new: anInteger [ ^ self basicNew initialize: anInteger; yourself ] -{ #category : #'instance creation' } +{ #category : 'instance creation' } CTSmallOrderedSet class >> withAll: aDictionary [ ^ (self new: aDictionary size) addAll: aDictionary; yourself ] -{ #category : #adding } +{ #category : 'adding' } CTSmallOrderedSet >> add: newObject [ (self findIndexFor: newObject) = 0 ifTrue: [ self privateAdd: newObject ]. ^ newObject ] -{ #category : #adding } +{ #category : 'adding' } CTSmallOrderedSet >> addAll: aCollection [ aCollection do: [ :each | self add: each ]. ^ aCollection ] -{ #category : #converting } +{ #category : 'converting' } CTSmallOrderedSet >> asArray [ | array index | array := Array new: self size. @@ -54,25 +55,25 @@ CTSmallOrderedSet >> asArray [ ^ array ] -{ #category : #enumerating } +{ #category : 'enumerating' } CTSmallOrderedSet >> do: aOneArgumentBlock [ 1 to: size do: [ :i | aOneArgumentBlock value: (table at: i) ] ] -{ #category : #enumerating } +{ #category : 'enumerating' } CTSmallOrderedSet >> do: aOneArgumentBlock separatedBy: aNiladicBlock [ 1 to: size do: [ :i | i > 1 ifTrue: [ aNiladicBlock value ]. aOneArgumentBlock value: (table at: i) ] ] -{ #category : #'private ' } +{ #category : 'private ' } CTSmallOrderedSet >> errorNotFound [ self error: 'Not found' ] -{ #category : #'private ' } +{ #category : 'private ' } CTSmallOrderedSet >> findIndexFor: aKey [ 1 to: size do: [ :index | (table at: index) = aKey @@ -80,7 +81,7 @@ CTSmallOrderedSet >> findIndexFor: aKey [ ^ 0 ] -{ #category : #'private ' } +{ #category : 'private ' } CTSmallOrderedSet >> grow [ | newTable | "#replaceFrom:to:with:startingAt: would be better but not portable" @@ -90,46 +91,46 @@ CTSmallOrderedSet >> grow [ table := newTable ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSet >> includes: anObject [ ^ (self findIndexFor: anObject) ~= 0 ] -{ #category : #initialization } +{ #category : 'initialization' } CTSmallOrderedSet >> initialize: anInteger [ self initialize. size := 0. table := Array new: anInteger ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSet >> isCollection [ ^ true ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSet >> isEmpty [ ^ size = 0 ] -{ #category : #copying } +{ #category : 'copying' } CTSmallOrderedSet >> postCopy [ super postCopy. table := table copy ] -{ #category : #'private ' } +{ #category : 'private ' } CTSmallOrderedSet >> privateAdd: newObject [ size = table size ifTrue: [ self grow ]. table at: (size := size + 1) put: newObject. ] -{ #category : #removing } +{ #category : 'removing' } CTSmallOrderedSet >> remove: anObject [ ^ self remove: anObject ifAbsent: [ self errorNotFound ] ] -{ #category : #removing } +{ #category : 'removing' } CTSmallOrderedSet >> remove: anObject ifAbsent: aNiladicBlock [ | index | index := self findIndexFor: anObject. @@ -139,7 +140,7 @@ CTSmallOrderedSet >> remove: anObject ifAbsent: aNiladicBlock [ ^ anObject ] -{ #category : #'private ' } +{ #category : 'private ' } CTSmallOrderedSet >> removeIndex: index [ table at: index put: nil. index to: size - 1 do: [ :i | @@ -147,7 +148,7 @@ CTSmallOrderedSet >> removeIndex: index [ size := size - 1 ] -{ #category : #accessing } +{ #category : 'accessing' } CTSmallOrderedSet >> size [ ^ size ] diff --git a/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st b/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st index 7546dd0..b6b1500 100644 --- a/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st +++ b/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st @@ -1,24 +1,25 @@ Class { - #name : #CTSmallOrderedSetTest, - #superclass : #TestCase, + #name : 'CTSmallOrderedSetTest', + #superclass : 'TestCase', #instVars : [ 'collection' ], - #category : #'Containers-SmallOrderedSet' + #category : 'Containers-SmallOrderedSet', + #package : 'Containers-SmallOrderedSet' } -{ #category : #configuration } +{ #category : 'configuration' } CTSmallOrderedSetTest >> collectionClass [ ^ CTSmallOrderedSet ] -{ #category : #running } +{ #category : 'running' } CTSmallOrderedSetTest >> setUp [ super setUp. collection := CTSmallOrderedSet new ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testAdd [ | object | object := Object new. @@ -28,7 +29,7 @@ CTSmallOrderedSetTest >> testAdd [ self assert: (collection add: object) equals: object ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testAddAll [ collection addAll: #(2 1 1). self assert: collection size equals: 2. @@ -36,26 +37,26 @@ CTSmallOrderedSetTest >> testAddAll [ self assert: (collection includes: 2) ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testAddAllKeepsOrder [ collection addAll: #(2 1 1 3 4 5 5 5 6). self assert: collection size equals: 6. self assert: collection asArray equals: #(2 1 3 4 5 6). ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testAsArray [ collection addAll: #(2 1 1). self assert: collection asArray equals: #(2 1). ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testAsArrayWithStrangeOrder [ collection addAll: #(2 1 3 2 1). self assert: collection asArray equals: #(2 1 3). ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testCopy [ | copy | collection add: 1. @@ -69,7 +70,7 @@ CTSmallOrderedSetTest >> testCopy [ self deny: (copy includes: 2). ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testDo [ | seen | collection addAll: #(2 1 1). @@ -81,14 +82,14 @@ CTSmallOrderedSetTest >> testDo [ self assert: (seen at: 2) equals: 1 ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testIncludes [ self deny: (collection includes: 0). collection add: 0. self assert: (collection includes: 0) ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testIsEmpty [ self assert: collection isEmpty. collection add: 1. @@ -97,14 +98,14 @@ CTSmallOrderedSetTest >> testIsEmpty [ self assert: collection isEmpty ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testRemove [ collection add: 1. self assert: (collection remove: 1) equals: 1. self should: [ collection remove: 1 ] raise: Error ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testRemoveIfAbsent [ | absent | collection add: 1. @@ -117,7 +118,7 @@ CTSmallOrderedSetTest >> testRemoveIfAbsent [ self assert: absent. ] -{ #category : #testing } +{ #category : 'testing' } CTSmallOrderedSetTest >> testSize [ self assert: collection size equals: 0. collection addAll: #(2 1 1). diff --git a/src/Containers-SmallOrderedSet/package.st b/src/Containers-SmallOrderedSet/package.st index c0a029c..3750e30 100644 --- a/src/Containers-SmallOrderedSet/package.st +++ b/src/Containers-SmallOrderedSet/package.st @@ -1 +1 @@ -Package { #name : #'Containers-SmallOrderedSet' } +Package { #name : 'Containers-SmallOrderedSet' } From 29551b76595fc406bf921d3ae82a2d6c7be3d29e Mon Sep 17 00:00:00 2001 From: Sneharaj7645653 Date: Fri, 28 Mar 2025 13:05:32 +0530 Subject: [PATCH 2/5] grow improved --- .../CTSmallOrderedSet.class.st | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st index 9829ef6..048dc21 100644 --- a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st +++ b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st @@ -81,14 +81,14 @@ CTSmallOrderedSet >> findIndexFor: aKey [ ^ 0 ] -{ #category : 'private ' } +{ #category : 'private' } CTSmallOrderedSet >> grow [ - | newTable | - "#replaceFrom:to:with:startingAt: would be better but not portable" - newTable := Array new: 2 * size. - 1 to: size do: [ :index | - newTable at: index put: (table at: index) ]. - table := newTable + | newTable newSize | + newSize := (table isEmpty) ifTrue: [1] ifFalse: [2 * table size]. "Ensure it grows from 0" + newTable := Array new: newSize. + 1 to: size do: [ :index | + newTable at: index put: (table at: index) ]. + table := newTable ] { #category : 'testing' } From 6c9b65383de33db580f2b1998a5f4c2b0d6bee3b Mon Sep 17 00:00:00 2001 From: Sneharaj7645653 Date: Fri, 28 Mar 2025 13:11:19 +0530 Subject: [PATCH 3/5] removed improved From ddbaea1faa8ca370b15fda8f699f641566eb1045 Mon Sep 17 00:00:00 2001 From: Sneharaj7645653 Date: Fri, 28 Mar 2025 13:11:40 +0530 Subject: [PATCH 4/5] removeIndex improved --- .../CTSmallOrderedSet.class.st | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st index 048dc21..6767e44 100644 --- a/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st +++ b/src/Containers-SmallOrderedSet/CTSmallOrderedSet.class.st @@ -140,12 +140,15 @@ CTSmallOrderedSet >> remove: anObject ifAbsent: aNiladicBlock [ ^ anObject ] -{ #category : 'private ' } -CTSmallOrderedSet >> removeIndex: index [ - table at: index put: nil. - index to: size - 1 do: [ :i | - table at: i put: (table at: i + 1) ]. - size := size - 1 +{ #category : 'private' } +CTSmallOrderedSet >> removeIndex: index [ +(index < 1 or: [ index > size ]) + ifTrue: [ self error: 'Index out of bounds' ]. + table at: index put: nil. + index to: size - 1 do: [ :i | + table at: i put: (table at: i + 1) ]. + table at: size put: nil. + size := size - 1. ] { #category : 'accessing' } From 471933aba1af6c1525600713308d1399f2ed5a31 Mon Sep 17 00:00:00 2001 From: Sneharaj7645653 Date: Fri, 28 Mar 2025 13:17:27 +0530 Subject: [PATCH 5/5] test for withAll added --- .../CTSmallOrderedSetTest.class.st | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st b/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st index b6b1500..067ee2f 100644 --- a/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st +++ b/src/Containers-SmallOrderedSet/CTSmallOrderedSetTest.class.st @@ -124,3 +124,50 @@ CTSmallOrderedSetTest >> testSize [ collection addAll: #(2 1 1). self assert: collection size equals: 2. ] + +{ #category : 'testing' } +CTSmallOrderedSetTest >> testWithAll [ + | emptySet singleSet duplicateSet orderedSet mixedSet largeSet unorderedSet specialCharSet expected | + + "Empty Collection Input" + emptySet := CTSmallOrderedSet withAll: #(). + self assert: emptySet isEmpty. + + "Single Element Collection" + singleSet := CTSmallOrderedSet withAll: #(42). + self assert: singleSet size equals: 1. + self assert: (singleSet includes: 42). + + "Collection With Only Duplicates" + duplicateSet := CTSmallOrderedSet withAll: #(7 7 7 7 7). + self assert: duplicateSet size equals: 1. + self assert: (duplicateSet includes: 7). + + "Already Ordered Input" + orderedSet := CTSmallOrderedSet withAll: #(10 20 30). + expected := #(10 20 30). + self assert: orderedSet asArray equals: expected. + + "Mixed Data Types" + mixedSet := CTSmallOrderedSet withAll: #(1 'a' 2 'b' 1 'a'). + self assert: mixedSet size equals: 4. + self assert: (mixedSet includes: 1). + self assert: (mixedSet includes: 'a'). + self assert: (mixedSet includes: 2). + self assert: (mixedSet includes: 'b'). + + "Large Input Collection" + largeSet := CTSmallOrderedSet withAll: (1 to: 10000). + self assert: largeSet size equals: 10000. + + "Unordered Input" + unorderedSet := CTSmallOrderedSet withAll: #(5 2 8 1 3). + self assert: unorderedSet asArray equals: #(5 2 8 1 3). + + "Collection With Special Characters" + specialCharSet := CTSmallOrderedSet withAll: #('hello' 'world' 'hello!' 'world#'). + self assert: specialCharSet size equals: 4. + self assert: (specialCharSet includes: 'hello!'). + self assert: (specialCharSet includes: 'world#'). + +]