Skip to content

Commit bef31c5

Browse files
authored
Merge pull request #882 from ApptiveGrid/new-visitors-consistency-and-gc
New visitors consistency and gc
2 parents 14d51fb + 71f4ba2 commit bef31c5

23 files changed

+737
-235
lines changed

src/Soil-Core-Tests/SoilBackupTest.class.st

+33
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,39 @@ SoilBackupTest >> testBackupOldVersion [
159159
tx3 abort ].
160160
]
161161

162+
{ #category : #tests }
163+
SoilBackupTest >> testBackupTheBackup [
164+
| tx visitor dict secondBackup txn |
165+
dict := SoilSkipListDictionary new
166+
keySize: 10;
167+
maxLevel: 8;
168+
yourself.
169+
tx := soil newTransaction.
170+
tx root: dict.
171+
1 to: 100 do: [ :n | dict at: n put: n asString ].
172+
tx commit.
173+
174+
backupSoil := Soil createOnPath: self path, #backup1.
175+
visitor := SoilBackupVisitor new
176+
target: backupSoil;
177+
backup: soil.
178+
179+
backupSoil close; open.
180+
181+
secondBackup := Soil createOnPath: self path, #backup2.
182+
visitor := SoilBackupVisitor new
183+
target: secondBackup;
184+
backup: backupSoil.
185+
secondBackup open.
186+
187+
txn := secondBackup newTransaction.
188+
self assert: txn root values size equals: 100.
189+
txn abort.
190+
191+
secondBackup close; destroy
192+
193+
]
194+
162195
{ #category : #tests }
163196
SoilBackupTest >> testBackupWithIndex [
164197
| tx backup tx2 dict object |

src/Soil-Core-Tests/SoilIndexedDictionaryTest.class.st

+31-30
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,37 @@ SoilIndexedDictionaryTest >> testFlushIndexPages [
420420
txn2 abort
421421
]
422422

423+
{ #category : #tests }
424+
SoilIndexedDictionaryTest >> testFreePageAfterReopen [
425+
| tx tx2 tx3 blockTx tx4 tx5 |
426+
(classToTest = SoilBTreeDictionary) ifTrue: [ self skip ].
427+
tx := soil newTransaction.
428+
tx root: dict.
429+
1 to: 1125 do: [ :n | dict at: n put: n asString ].
430+
tx commit.
431+
432+
"open a second transaction ..."
433+
blockTx := soil newTransaction.
434+
tx2 := soil newTransaction.
435+
224 to: 899 do: [ :n |tx2 root removeKey: n ].
436+
tx2 commit.
437+
blockTx abort.
438+
439+
soil
440+
close;
441+
reopen.
442+
tx3 := soil newTransaction.
443+
900 to: 905 do: [ :n | tx3 root removeKey: n ].
444+
tx3 root index wrapped markAllDirty.
445+
tx3 commit.
446+
tx4 := soil newTransaction.
447+
tx4 root at: 906 put: 906 asString.
448+
tx4 root removeKey: 223.
449+
tx4 commit.
450+
tx5 := soil newTransaction.
451+
self deny: (tx5 root index wrapped store headerPage right includes: 2)
452+
]
453+
423454
{ #category : #tests }
424455
SoilIndexedDictionaryTest >> testFreePageNotSavedRegression [
425456
| tx blockTx iterator |
@@ -481,36 +512,6 @@ SoilIndexedDictionaryTest >> testFreePageReuse [
481512

482513
]
483514

484-
{ #category : #tests }
485-
SoilIndexedDictionaryTest >> testFreePageReuseExact [
486-
| tx tx2 tx3 blockTx tx4 tx5 tx15 |
487-
(classToTest = SoilBTreeDictionary) ifTrue: [ self skip ].
488-
tx := soil newTransaction.
489-
tx root: dict.
490-
1 to: 674 do: [ :n | dict at: n put: n asString ].
491-
tx commit.
492-
493-
494-
tx15 := soil newTransaction.
495-
1 to: 223 do: [ :n | tx15 root removeKey: n ].
496-
tx15 commit.
497-
"open a second transaction ..."
498-
blockTx := soil newTransaction.
499-
tx2 := soil newTransaction.
500-
224 to: 448 do: [ :n | tx2 root removeKey: n ].
501-
tx2 commit.
502-
tx3 := soil newTransaction.
503-
449 to: 449 do: [ :n | tx3 root removeKey: n ].
504-
tx3 commit.
505-
blockTx abort.
506-
tx4 := soil newTransaction.
507-
tx4 root at: 675 put: 675 asString.
508-
tx4 root removeKey: 450.
509-
tx4 commit.
510-
tx5 := soil newTransaction.
511-
self deny: (tx5 root index wrapped store headerPage right includes: 2)
512-
]
513-
514515
{ #category : #tests }
515516
SoilIndexedDictionaryTest >> testFreePages [
516517
| tx tx2 index indexManager |
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Class {
2+
#name : #AnObsoleteSoilCloneVisitor,
3+
#superclass : #SoilVisitor,
4+
#category : #'Soil-Core'
5+
}

src/Soil-Core/Soil.class.st

+7
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,13 @@ Soil >> findRecord: aBlock [
217217
ensure: [ tx abort ]
218218
]
219219

220+
{ #category : #'memory space' }
221+
Soil >> garbageCollect [
222+
SoilGarbageCollectVisitor new
223+
soil: self;
224+
run
225+
]
226+
220227
{ #category : #initialization }
221228
Soil >> initialize [
222229
super initialize.

src/Soil-Core/SoilBackupVisitor.class.st

+21-34
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,21 @@ Class {
22
#name : #SoilBackupVisitor,
33
#superclass : #SoilVisitor,
44
#instVars : [
5-
'source',
6-
'target',
7-
'seen',
8-
'toBeProcessed',
9-
'version'
5+
'target'
106
],
117
#category : #'Soil-Core-Visitor'
128
}
139

1410
{ #category : #api }
1511
SoilBackupVisitor >> backup: aSoil [
16-
| objectId |
17-
source := aSoil.
12+
soil := aSoil.
1813
"if there is no version set we take the actual database version. This
1914
is to create a consistent backup regardless if transactions are committed
2015
while we are doing the backup"
21-
version ifNil: [
22-
version := aSoil control databaseVersion ].
16+
databaseVersion ifNil: [
17+
databaseVersion := aSoil control databaseVersion ].
2318

24-
self visit: source.
25-
26-
[ toBeProcessed isEmpty ] whileFalse: [
27-
objectId := toBeProcessed removeFirst.
28-
self visit: (source objectRepository at: objectId version: version) ].
19+
self visit: soil.
2920
target close
3021
]
3122

@@ -35,7 +26,7 @@ SoilBackupVisitor >> copyAllClusterVersions: aSoilPersistentClusterVersion [
3526
"if there is no previous version is a single copy"
3627
aSoilPersistentClusterVersion hasPreviousVersion
3728
ifFalse: [ ^ self copySourceCluster: aSoilPersistentClusterVersion ].
38-
versions := (source objectRepository segmentAt: aSoilPersistentClusterVersion objectId segment)
29+
versions := (soil objectRepository segmentAt: aSoilPersistentClusterVersion objectId segment)
3930
allVersionsAt: aSoilPersistentClusterVersion objectId index.
4031
position := 0.
4132
"for multiple versions we need to iterate from oldest to newest to set the
@@ -53,7 +44,7 @@ SoilBackupVisitor >> copyCluster: aSoilPersistentClusterVersion [
5344
at: aSoilPersistentClusterVersion objectId
5445
putBytes: aSoilPersistentClusterVersion serialize.
5546
aSoilPersistentClusterVersion references do: [ :reference |
56-
self process: reference ].
47+
self processObjectId: reference ].
5748
aSoilPersistentClusterVersion indexIds do:[ :indexId |
5849
self copyIndexAt: indexId segment: aSoilPersistentClusterVersion segment ].
5950
^ position
@@ -64,7 +55,7 @@ SoilBackupVisitor >> copyCluster: aSoilPersistentClusterVersion [
6455
SoilBackupVisitor >> copyIndexAt: indexId segment: segmentId [
6556
| sourceSegment sourceIndex targetSegment targetIndex iterator assoc |
6657

67-
sourceSegment := source objectRepository segmentAt: segmentId.
58+
sourceSegment := soil objectRepository segmentAt: segmentId.
6859
sourceIndex := sourceSegment indexManager
6960
loadIndexWithId: indexId
7061
ifNone: [ ^ self indexNotFound: indexId ].
@@ -82,7 +73,7 @@ SoilBackupVisitor >> copyIndexAt: indexId segment: segmentId [
8273
assoc value isRemoved ifFalse: [
8374
targetIndex basicAt: assoc key put: assoc value.
8475
"recurse further into the values of the index"
85-
self process: assoc value asSoilObjectId ] ].
76+
self processObjectId: assoc value asSoilObjectId ] ].
8677
targetIndex
8778
flush;
8879
close.
@@ -95,18 +86,17 @@ SoilBackupVisitor >> copySourceCluster: aSoilPersistentClusterVersion [
9586
^ self copyCluster: clusterCopy
9687
]
9788

89+
{ #category : #accessing }
90+
SoilBackupVisitor >> databaseVersion: anObject [
91+
92+
databaseVersion := anObject
93+
]
94+
9895
{ #category : #visiting }
9996
SoilBackupVisitor >> indexNotFound: indexId [
10097
Error signal: 'cannot find index with id ', indexId printString
10198
]
10299

103-
{ #category : #initialization }
104-
SoilBackupVisitor >> initialize [
105-
super initialize.
106-
seen := Set new.
107-
toBeProcessed := OrderedCollection new
108-
]
109-
110100
{ #category : #visiting }
111101
SoilBackupVisitor >> makeCopy: aSoilPersistentClusterVersion [
112102
^ aSoilPersistentClusterVersion copy
@@ -117,13 +107,10 @@ SoilBackupVisitor >> makeCopy: aSoilPersistentClusterVersion [
117107
resetPreviousVersion.
118108
]
119109

120-
{ #category : #accessing }
121-
SoilBackupVisitor >> process: aSoilObjectId [
122-
"don't continue if the objectId is the behavior description meta object"
123-
((aSoilObjectId segment = 0) and: [ aSoilObjectId index = 2 ]) ifTrue: [ ^ self ].
124-
(seen includes: aSoilObjectId) ifTrue: [ ^ self ].
125-
seen add: aSoilObjectId.
126-
toBeProcessed add: aSoilObjectId
110+
{ #category : #api }
111+
SoilBackupVisitor >> processLoop [
112+
super processLoop.
113+
target close
127114
]
128115

129116
{ #category : #accessing }
@@ -134,7 +121,7 @@ SoilBackupVisitor >> target: aSoil [
134121
{ #category : #accessing }
135122
SoilBackupVisitor >> version: anObject [
136123

137-
version := anObject
124+
databaseVersion := anObject
138125
]
139126

140127
{ #category : #visiting }
@@ -167,7 +154,7 @@ SoilBackupVisitor >> visitMetaSegment: aSoilMetaSegment [
167154

168155
{ #category : #visiting }
169156
SoilBackupVisitor >> visitObjectSegment: aSoilObjectSegment [
170-
self process: SoilObjectId root.
157+
self processObjectId: SoilObjectId root.
171158
super visitObjectSegment: aSoilObjectSegment.
172159
]
173160

src/Soil-Core/SoilBasicSkipList.class.st

+3-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ SoilBasicSkipList class >> isAbstract [
1919

2020
{ #category : #adding }
2121
SoilBasicSkipList >> addDirtyPage: aPage [
22-
dirtyPages at: aPage offset put: aPage
22+
dirtyPages
23+
at: aPage offset
24+
ifAbsentPut: [ aPage ]
2325
]
2426

2527
{ #category : #'instance creation' }

0 commit comments

Comments
 (0)