Skip to content

Commit

Permalink
This PR adds a first test for #nextKeyCloseTo: (for now just with a t…
Browse files Browse the repository at this point in the history
…ransaction)

- add #testNextKeyCloseToWithTransaction
- fix on the iterator #nextKeyCloseTo: to return a value and move up to be usable for BTree, too
- move some methods up in the page hierachy to make it work for BTree
  • Loading branch information
MarcusDenker committed Jan 17, 2024
1 parent 321cb4b commit fade3d5
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 35 deletions.
15 changes: 15 additions & 0 deletions src/Soil-Core-Tests/SoilIndexedDictionaryTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,21 @@ SoilIndexedDictionaryTest >> testNextAfterWithTransaction [
self assert: (tx2 root nextAfter: 1) value equals: #two
]

{ #category : #tests }
SoilIndexedDictionaryTest >> testNextKeyCloseToWithTransaction [
| tx tx2 |
tx := soil newTransaction.
tx root: dict.
dict at: 10 put: #one.
dict at: 20 put: #two.
"self assert: dict last equals: #two."
tx commit.
"open a second transaction ..."
tx2 := soil newTransaction.
"and test last"
self assert: (tx2 root nextKeyCloseTo: 15) value equals: 20
]

{ #category : #tests }
SoilIndexedDictionaryTest >> testRemoveKey [
dict at: #foo put: #bar.
Expand Down
20 changes: 20 additions & 0 deletions src/Soil-Core/SoilIndexItemsPage.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,32 @@ SoilIndexItemsPage >> items [
^ items
]

{ #category : #accessing }
SoilIndexItemsPage >> keyOrClosestAfter: key [
"find the closest key in this page. This returns the exact key if
present or the key that comes after. Else returns nil. This is useful if we enter the
list at an unknown point"
items isEmpty ifTrue: [ ^ nil ].
self lastKey < key ifTrue: [ ^ nil ].
^ items
findBinaryIndex: [ :each | key - each key ]
do: [ :e | (items at: e) key]
ifNone: [ :a :b |
(items at: (b min: items size)) key ]
]

{ #category : #accessing }
SoilIndexItemsPage >> lastItem [

^ items isNotEmpty ifTrue: [ items last ] ifFalse: [ nil ]
]

{ #category : #accessing }
SoilIndexItemsPage >> lastKey [

^ items isNotEmpty ifTrue: [ items last key ]
]

{ #category : #accessing }
SoilIndexItemsPage >> numberOfItems [
^ items size
Expand Down
15 changes: 15 additions & 0 deletions src/Soil-Core/SoilIndexIterator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,21 @@ SoilIndexIterator >> nextAssociation [
^ nextValue ifNil: [ self nextAssociation ] ifNotNil: [ key -> nextValue ]
]

{ #category : #private }
SoilIndexIterator >> nextKeyCloseTo: key [

| binKey |
binKey := (key asSkipListKeyOfSize: index keySize) asInteger.
self findPageFor: binKey.
nextKey := currentPage keyOrClosestAfter: binKey.
^ nextKey
ifNil: [ "if there is no close key found, we position the cursor at the end, so that asking for the next association will return nil"
currentKey := currentPage lastKey ]
ifNotNil: [
"if there is a close key found, we make sure the cursor get properly positioned"
currentKey := nextKey ]
]

{ #category : #accessing }
SoilIndexIterator >> pageAt: anInteger [
^ index store pageAt: anInteger
Expand Down
5 changes: 5 additions & 0 deletions src/Soil-Core/SoilIndexedDictionary.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ SoilIndexedDictionary >> nextAfter: key [
assoc key -> (transaction objectWithId: assoc value asSoilObjectId) ]
]

{ #category : #private }
SoilIndexedDictionary >> nextKeyCloseTo: aKey [
^ self newIterator nextKeyCloseTo: aKey
]

{ #category : #private }
SoilIndexedDictionary >> prepareNewValues [
newValues copy keysAndValuesDo: [ :key :object |
Expand Down
15 changes: 0 additions & 15 deletions src/Soil-Core/SoilSkipListIterator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,6 @@ SoilSkipListIterator >> levelAt: anInteger [
^ levels at: anInteger
]

{ #category : #private }
SoilSkipListIterator >> nextKeyCloseTo: key [

| binKey |
binKey := (key asSkipListKeyOfSize: index keySize) asInteger.
self findPageFor: binKey.
nextKey := currentPage keyOrClosestAfter: binKey.
nextKey
ifNil: [ "if there is no close key found, we position the cursor at the end, so that asking for the next association will return nil"
currentKey := currentPage lastKey ]
ifNotNil: [
"if there is a close key found, we make sure the cursor get properly positioned"
currentKey := nextKey ]
]

{ #category : #printing }
SoilSkipListIterator >> printOn: aStream [
aStream << 'path: ' << levels asString
Expand Down
20 changes: 0 additions & 20 deletions src/Soil-Core/SoilSkipListPage.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -64,20 +64,6 @@ SoilSkipListPage >> isOlderThan: aVersionNumber [
^ lastTransaction <= aVersionNumber
]

{ #category : #accessing }
SoilSkipListPage >> keyOrClosestAfter: key [
"find the closest key in this page. This returns the exact key if
present or the key that comes after. Else returns nil. This is useful if we enter the
list at an unknown point"
items isEmpty ifTrue: [ ^ nil ].
self lastKey < key ifTrue: [ ^ nil ].
^ items
findBinaryIndex: [ :each | key - each key ]
do: [ :e | (items at: e) key]
ifNone: [ :a :b |
(items at: (b min: items size)) key ]
]

{ #category : #accessing }
SoilSkipListPage >> keySize [
^ keySize
Expand All @@ -89,12 +75,6 @@ SoilSkipListPage >> keySize: anInteger [
keySize := anInteger.
]

{ #category : #accessing }
SoilSkipListPage >> lastKey [

^ items isNotEmpty ifTrue: [ items last key ]
]

{ #category : #accessing }
SoilSkipListPage >> lastTransaction [
^ lastTransaction
Expand Down

0 comments on commit fade3d5

Please sign in to comment.