Skip to content

Commit 4c3622c

Browse files
authored
Merge pull request #12 from HossamSaberr/master
Add radix merge logic to CTOptimizedTrie deletion
2 parents 1fce6ed + 58b08c6 commit 4c3622c

15 files changed

Lines changed: 367 additions & 153 deletions

src/Containers-Trie-Tests/AbstractCTTrieTest.class.st

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,26 @@
11
Class {
2-
#name : #AbstractCTTrieTest,
3-
#superclass : #TestCase,
2+
#name : 'AbstractCTTrieTest',
3+
#superclass : 'TestCase',
44
#instVars : [
55
'trie'
66
],
7-
#category : #'Containers-Trie-Tests'
7+
#category : 'Containers-Trie-Tests',
8+
#package : 'Containers-Trie-Tests'
89
}
910

10-
{ #category : #utils }
11+
{ #category : 'utils' }
1112
AbstractCTTrieTest >> classUnderTest [
1213

1314
^ CTTrie
1415
]
1516

16-
{ #category : #utils }
17+
{ #category : 'utils' }
1718
AbstractCTTrieTest >> newInstance [
1819

1920
^ self classUnderTest new
2021
]
2122

22-
{ #category : #running }
23+
{ #category : 'running' }
2324
AbstractCTTrieTest >> setUp [
2425
"example taken from <http://en.wikipedia.org/wiki/Trie>"
2526

Lines changed: 186 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,193 @@
11
Class {
2-
#name : #CTOptimizedTrieTest,
3-
#superclass : #CTTrieTest,
4-
#category : #'Containers-Trie-Tests'
2+
#name : 'CTOptimizedTrieTest',
3+
#superclass : 'CTTrieTest',
4+
#category : 'Containers-Trie-Tests',
5+
#package : 'Containers-Trie-Tests'
56
}
67

7-
{ #category : #utils }
8+
{ #category : 'utils' }
89
CTOptimizedTrieTest >> classUnderTest [
910

1011
^ CTOptimizedTrie
1112
]
13+
14+
{ #category : 'tests' }
15+
CTOptimizedTrieTest >> testCompressNodeDoesNotMergeWhenAncestorsTooSmall [
16+
| rootNode nodeToCheck ancestors |
17+
trie := CTOptimizedTrie new.
18+
19+
trie at: 'cat' put: 1.
20+
21+
rootNode := trie instVarNamed: 'root'.
22+
nodeToCheck := rootNode children first.
23+
24+
ancestors := OrderedCollection new.
25+
ancestors add: nodeToCheck.
26+
27+
trie compressNode: nodeToCheck ancestors: ancestors.
28+
29+
self assert: rootNode keys size equals: 1.
30+
self assert: rootNode keys first equals: 'cat'.
31+
self assert: (trie at: 'cat') equals: 1.
32+
]
33+
34+
{ #category : 'tests' }
35+
CTOptimizedTrieTest >> testCompressNodeDoesNotMergeWhenHasValue [
36+
| rootNode nodeToCheck ancestors |
37+
trie := CTOptimizedTrie new.
38+
39+
trie at: 'cat' put: 1.
40+
trie at: 'ca' put: 2.
41+
42+
rootNode := trie instVarNamed: 'root'.
43+
nodeToCheck := rootNode children first.
44+
45+
ancestors := OrderedCollection new.
46+
ancestors add: rootNode.
47+
ancestors add: nodeToCheck.
48+
49+
trie compressNode: nodeToCheck ancestors: ancestors.
50+
51+
self assert: rootNode keys size equals: 1.
52+
self assert: rootNode keys first equals: 'ca'.
53+
self assert: (trie at: 'ca') equals: 2.
54+
]
55+
56+
{ #category : 'tests' }
57+
CTOptimizedTrieTest >> testCompressNodeDoesNotMergeWithMultipleChildren [
58+
| rootNode nodeToCheck ancestors |
59+
trie := CTOptimizedTrie new.
60+
61+
trie at: 'cat' put: 1.
62+
trie at: 'car' put: 2.
63+
64+
rootNode := trie instVarNamed: 'root'.
65+
nodeToCheck := rootNode children first.
66+
67+
nodeToCheck instVarNamed: 'nodeValue' put: nil.
68+
69+
ancestors := OrderedCollection new.
70+
ancestors add: rootNode.
71+
ancestors add: nodeToCheck.
72+
73+
trie compressNode: nodeToCheck ancestors: ancestors.
74+
75+
self assert: rootNode keys size equals: 1.
76+
self assert: rootNode keys first equals: 'ca'.
77+
self assert: nodeToCheck keys size equals: 2.
78+
self assert: (nodeToCheck keys includesAll: #('t' 'r')).
79+
self assert: (trie at: 'cat') equals: 1.
80+
self assert: (trie at: 'car') equals: 2.
81+
]
82+
83+
{ #category : 'tests' }
84+
CTOptimizedTrieTest >> testCompressNodeMergesDeepSingleChild [
85+
| rootNode parentNode nodeToCheck ancestors |
86+
trie := CTOptimizedTrie new.
87+
88+
trie at: 'a' put: 1.
89+
trie at: 'ab' put: 2.
90+
trie at: 'abc' put: 3.
91+
92+
rootNode := trie instVarNamed: 'root'.
93+
parentNode := rootNode children first.
94+
nodeToCheck := parentNode children first.
95+
96+
nodeToCheck instVarNamed: 'nodeValue' put: nil.
97+
98+
ancestors := OrderedCollection new.
99+
ancestors add: rootNode.
100+
ancestors add: parentNode.
101+
ancestors add: nodeToCheck.
102+
103+
trie compressNode: nodeToCheck ancestors: ancestors.
104+
105+
self assert: parentNode keys size equals: 1.
106+
self assert: parentNode keys first equals: 'bc'.
107+
108+
self assert: (trie at: 'abc') equals: 3.
109+
self assert: (trie at: 'a') equals: 1.
110+
]
111+
112+
{ #category : 'tests' }
113+
CTOptimizedTrieTest >> testCompressNodeMergesSingleChildWithoutValue [
114+
| rootNode nodeToCheck ancestors |
115+
trie := CTOptimizedTrie new.
116+
117+
trie at: 'cat' put: 1.
118+
trie at: 'ca' put: 2.
119+
120+
rootNode := trie instVarNamed: 'root'.
121+
nodeToCheck := rootNode children first.
122+
123+
nodeToCheck instVarNamed: 'nodeValue' put: nil.
124+
125+
ancestors := OrderedCollection new.
126+
ancestors add: rootNode.
127+
ancestors add: nodeToCheck.
128+
129+
trie compressNode: nodeToCheck ancestors: ancestors.
130+
131+
self assert: rootNode keys size equals: 1.
132+
self assert: rootNode keys first equals: 'cat'.
133+
self assert: (trie at: 'cat') equals: 1.
134+
]
135+
136+
{ #category : 'tests' }
137+
CTOptimizedTrieTest >> testOptimizedTrieCompressesOnDeletion [
138+
| trie rootNode |
139+
trie := CTOptimizedTrie new.
140+
trie at: 'car' put: 1.
141+
trie at: 'cat' put: 2.
142+
143+
trie removeKey: 'cat'.
144+
145+
self assert: (trie at: 'car') equals: 1.
146+
147+
rootNode := trie instVarNamed: 'root'.
148+
149+
self assert: rootNode children first children isEmpty.
150+
]
151+
152+
{ #category : 'tests' }
153+
CTOptimizedTrieTest >> testOptimizedTrieDoesNotMergeWhenParentIsWord [
154+
| trie rootNode parentNode |
155+
trie := CTOptimizedTrie new.
156+
157+
trie at: 'ca' put: 1.
158+
trie at: 'cat' put: 2.
159+
trie at: 'car' put: 3.
160+
161+
trie removeKey: 'cat'.
162+
163+
self assert: (trie at: 'ca') equals: 1.
164+
self assert: (trie at: 'car') equals: 3.
165+
166+
rootNode := trie instVarNamed: 'root'.
167+
parentNode := rootNode children first.
168+
169+
self assert: parentNode isWord.
170+
self assert: parentNode nodeValue equals: 1.
171+
self assert: parentNode keys size equals: 1.
172+
]
173+
174+
{ #category : 'tests' }
175+
CTOptimizedTrieTest >> testOptimizedTrieDoesNotMergeWithMultipleChildren [
176+
| trie rootNode parentNode |
177+
trie := CTOptimizedTrie new.
178+
179+
trie at: 'cat' put: 1.
180+
trie at: 'car' put: 2.
181+
trie at: 'cab' put: 3.
182+
183+
trie removeKey: 'cat'.
184+
185+
self assert: (trie at: 'car') equals: 2.
186+
self assert: (trie at: 'cab') equals: 3.
187+
188+
rootNode := trie instVarNamed: 'root'.
189+
parentNode := rootNode children first.
190+
191+
self assert: parentNode isWord not.
192+
self assert: parentNode keys size equals: 2.
193+
]

src/Containers-Trie-Tests/CTSuffixTreeTest.class.st

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
Class {
2-
#name : #CTSuffixTreeTest,
3-
#superclass : #TestCase,
2+
#name : 'CTSuffixTreeTest',
3+
#superclass : 'TestCase',
44
#instVars : [
55
'suffixTree'
66
],
7-
#category : #'Containers-Trie-Tests'
7+
#category : 'Containers-Trie-Tests',
8+
#package : 'Containers-Trie-Tests'
89
}
910

10-
{ #category : #running }
11+
{ #category : 'running' }
1112
CTSuffixTreeTest >> setUp [
1213

1314
super setUp.
1415
suffixTree := CTSuffixTree new
1516
]
1617

17-
{ #category : #tests }
18+
{ #category : 'tests' }
1819
CTSuffixTreeTest >> testAddingAStringAddsAllSubstring [
1920

2021
suffixTree atSuffixesOf: 'banana' put: 1.
@@ -24,7 +25,7 @@ CTSuffixTreeTest >> testAddingAStringAddsAllSubstring [
2425

2526
]
2627

27-
{ #category : #tests }
28+
{ #category : 'tests' }
2829
CTSuffixTreeTest >> testRemovingAStringRemovesAllSuffixes [
2930

3031
suffixTree atSuffixesOf: 'banana' put: 1.

src/Containers-Trie-Tests/CTTrieNodeTest.class.st

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
Class {
2-
#name : #CTTrieNodeTest,
3-
#superclass : #AbstractCTTrieTest,
4-
#category : #'Containers-Trie-Tests'
2+
#name : 'CTTrieNodeTest',
3+
#superclass : 'AbstractCTTrieTest',
4+
#category : 'Containers-Trie-Tests',
5+
#package : 'Containers-Trie-Tests'
56
}
67

7-
{ #category : #'tests - nodes' }
8+
{ #category : 'tests - nodes' }
89
CTTrieNodeTest >> testIsLeaf [
910
| aTrie aWord aLongerWord aNode |
1011
aTrie := self newInstance.
@@ -26,7 +27,7 @@ CTTrieNodeTest >> testIsLeaf [
2627
self assert: aLongerWord isLeaf
2728
]
2829

29-
{ #category : #'tests - nodes' }
30+
{ #category : 'tests - nodes' }
3031
CTTrieNodeTest >> testIsLeafWikipediaExample [
3132

3233
self assert: (trie find: 'to') isLeaf.
@@ -41,7 +42,7 @@ CTTrieNodeTest >> testIsLeafWikipediaExample [
4142
self assert: (trie isCompressed)
4243
]
4344

44-
{ #category : #'tests - nodes' }
45+
{ #category : 'tests - nodes' }
4546
CTTrieNodeTest >> testIsNode [
4647
| aTrie aWord aLongerWord aNode |
4748
aTrie := self newInstance.
@@ -74,7 +75,7 @@ CTTrieNodeTest >> testIsNode [
7475
self deny: trie rootNode isNode
7576
]
7677

77-
{ #category : #'tests - nodes' }
78+
{ #category : 'tests - nodes' }
7879
CTTrieNodeTest >> testIsNotCompressed [
7980

8081
| aTrie |
@@ -90,7 +91,7 @@ CTTrieNodeTest >> testIsNotCompressed [
9091
self deny: aTrie isCompressed
9192
]
9293

93-
{ #category : #'tests - nodes' }
94+
{ #category : 'tests - nodes' }
9495
CTTrieNodeTest >> testIsRoot [
9596
| aTrie aWord aLongerWord aNode |
9697
aTrie := self newInstance.
@@ -123,7 +124,7 @@ CTTrieNodeTest >> testIsRoot [
123124
self assert: trie rootNode isRoot
124125
]
125126

126-
{ #category : #'tests - nodes' }
127+
{ #category : 'tests - nodes' }
127128
CTTrieNodeTest >> testIsWord [
128129
| aTrie aWord aLongerWord aNode |
129130
aTrie := self newInstance.
@@ -145,7 +146,7 @@ CTTrieNodeTest >> testIsWord [
145146
self assert: aLongerWord isWord
146147
]
147148

148-
{ #category : #'tests - nodes' }
149+
{ #category : 'tests - nodes' }
149150
CTTrieNodeTest >> testIsWordWikipediaExample [
150151

151152
self assert: (trie find: 'to') isWord.

0 commit comments

Comments
 (0)