Skip to content

Commit

Permalink
Merge pull request #577 from ApptiveGrid/nextKeyCloseTo-Fix
Browse files Browse the repository at this point in the history
Add test and fix #nextKeyCloseTo:
  • Loading branch information
noha authored Jan 22, 2024
2 parents 3010813 + fade3d5 commit 2a697e6
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 >> testNextAssociationAfterWithTransaction [
self assert: (tx2 root nextAssociationAfter: 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 >> nextAssociationAfter: key [

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 @@ -222,6 +222,11 @@ SoilIndexedDictionary >> nextAssociationAfter: 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 2a697e6

Please sign in to comment.