Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cherrypicking from feenkcom Bloc repo #480

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 26 additions & 5 deletions src/Bloc-Examples/BlFileCollectionRopeExamples.class.st
Expand Up @@ -4,15 +4,36 @@ Class {
#category : #'Bloc-Examples-Rope'
}

{ #category : #'instance creation' }
BlFileCollectionRopeExamples >> testBufferedIndexes [
"Test that buffering + index calculations work"

| rope result file |
file := FileSystem memory / 'test.txt'.
file writeStreamDo: [ :stream | stream << 'foobarbaz' ].
rope :=
BlRopeableCollectionFile new
bufferSize: 3;
fileReference: file.

"The following test uses an explicit whileTrue: loop instead of to:do: since `rope size` can be different every time"
result :=
String streamContents: [ :str |
| i |
i := 1.
[ i <= rope size ] whileTrue: [
str nextPut: (rope at: i).
i := i + 1 ] ].

self assert: result equals: 'foobarbaz'
]

{ #category : #'instance creation' }
BlFileCollectionRopeExamples >> testSmall [
"Creates an instance of the rope of size smaller than combineLength"
"Test a rope of size smaller than combineLength"

<sampleInstance>
| aRope file |
file := FileReference
newTempFilePrefix: 'BlFileCollectionRopeExamples-'
suffix: '-small'.
file := FileSystem memory / 'test.txt'.
file writeStreamDo: [ :stream | stream << 'Hello' ].
aRope := BlCollectionRope collection:
(BlRopeableCollectionFile new fileReference: file).
Expand Down
6 changes: 3 additions & 3 deletions src/Bloc-Examples/BlRopeableCollectionFileTest.class.st
Expand Up @@ -24,14 +24,14 @@ BlRopeableCollectionFileTest >> emptyFile [
{ #category : #'test seed' }
BlRopeableCollectionFileTest >> largeFile [

^largeFile ifNil:
[ largeFile := FileReference newTempFilePrefix: 'BlRopeableCollectionFileExamples-' suffix: '-largeFile'.
^ largeFile ifNil: [
largeFile := FileSystem memory / 'test.txt'.
largeFile writeStreamDo: [ :stream |
1 to: 10000 do: [ :l |
1 to: 9 do: [ :i |
stream << (((l-1)*10 + i-1) printPaddedWith: $0 to: 10) ].
stream << 'abcdefghi'; lf. ] ].
largeFile ].
largeFile ]
]

{ #category : #'test seed' }
Expand Down
10 changes: 4 additions & 6 deletions src/Bloc/BlElement.class.st
Expand Up @@ -545,7 +545,7 @@ BlElement >> attachChild: anElement at: anIndex [
eachElement isRemovedFromSceneGraph
ifTrue: [
eachElement attachSpace.
eachElement onAddedToSceneGraph ] ] ]
eachElement dispatchAddedToSceneGraph ] ] ]
]

{ #category : #'api - space' }
Expand Down Expand Up @@ -1328,6 +1328,7 @@ BlElement >> dispatchAddedToParent [
"Sent after I was added to another element as direct child.
I dispatch or fire all necessary events, clean internal caches and send a corresponding hooks"

boundsCache invalidateBoundsInSpace.
self onAddedToParent.
self eventDispatcher dispatchAddedToParent
]
Expand All @@ -1342,6 +1343,8 @@ BlElement >> dispatchAddedToSceneGraph [
description: [ 'I must already be attached to the scene graph' ].

self onAddedToSceneGraph.
self eventDispatcher dispatchAddedToSceneGraph.

self childrenDo: [ :anElement |

anElement isAttachedToSceneGraph
Expand Down Expand Up @@ -2864,11 +2867,6 @@ BlElement >> onAddedToSceneGraph [
At this point #isAttachedToSceneGraph results in true.
Note: Always send onAddedToSceneGraph to superclass if you override me!"

self
assert: [ self isAttachedToSceneGraph ]
description: [ 'I must already be attached to the scene graph' ].

self eventDispatcher dispatchAddedToSceneGraph
]

{ #category : #'hooks - children' }
Expand Down
140 changes: 52 additions & 88 deletions src/Bloc/BlRopeableCollectionFile.class.st
Expand Up @@ -51,7 +51,6 @@ Class {
#instVars : [
'fileReference',
'strict',
'binaryStream',
'map',
'bufferSize',
'buffer',
Expand Down Expand Up @@ -98,6 +97,12 @@ BlRopeableCollectionFile >> at: anInteger [
^ buffer at: (anInteger - bufferStart + 1) asInteger.
]

{ #category : #enumerating }
BlRopeableCollectionFile >> binaryReadStreamDo: aBlock [

^ fileReference binaryReadStreamDo: aBlock
]

{ #category : #accessing }
BlRopeableCollectionFile >> bufferSize [
^ bufferSize
Expand All @@ -108,48 +113,26 @@ BlRopeableCollectionFile >> bufferSize: anInteger [

bufferSize := anInteger.
buffer := String new: bufferSize.
bufferStart := nil.
bufferStart := 0.
bufferedSize := 0.
]

{ #category : #private }
BlRopeableCollectionFile >> characterStream [
"Answer a read stream with character decoding on the receiver's binary stream"

^ ZnCharacterReadStream
on: binaryStream
encoding: 'utf8'
]

{ #category : #'initialize-release' }
BlRopeableCollectionFile >> close [

binaryStream close
{ #category : #enumerating }
BlRopeableCollectionFile >> characterStreamDo: aBlock [
"Evaluate aBlock with a ZnCharacterReadStream on the receiver's file."

^ self binaryReadStreamDo: [ :bStream |
aBlock value:
(ZnCharacterReadStream
on: bStream
encoding: 'utf8') ]
]

{ #category : #copying }
BlRopeableCollectionFile >> copyFrom: startIndex to: endIndex [
| length results receiverIndex bufferIndex resultIndex |

self ensureBuffered: startIndex.
length := endIndex - startIndex + 1.
length <= 0 ifTrue: [ ^ '' ].
results := String new: length.
receiverIndex := startIndex.
resultIndex := 1.
bufferIndex := startIndex - bufferStart + 1.

[ receiverIndex <= endIndex ] whileTrue:
[ bufferIndex > bufferedSize ifTrue:
[ self ensureBuffered: receiverIndex.
bufferIndex := receiverIndex - bufferStart ].
results at: resultIndex put: (buffer at: bufferIndex).
receiverIndex := receiverIndex + 1.
resultIndex := resultIndex + 1.
bufferIndex := bufferIndex + 1. ].

^ results

^ String streamContents: [ :aStream |
startIndex to: endIndex do: [ :i | aStream nextPut: (self at: i) ] ]
]

{ #category : #copying }
Expand Down Expand Up @@ -183,43 +166,37 @@ BlRopeableCollectionFile >> copyToEndFrom: startIndex [

{ #category : #enumerating }
BlRopeableCollectionFile >> do: aBlock [
| characterStream ch |

fileReference ifNil: [ ^ self ].
binaryStream position: 0.
characterStream := self characterStream.
[ characterStream atEnd ] whileFalse:
[ ch := characterStream next.
ch ifNotNil: [ aBlock value: ch ] ]

self characterStreamDo: [ :stream |
stream position: 0.
[ stream atEnd ] whileFalse: [
stream next ifNotNil: [ :ch | aBlock value: ch ] ] ]
]

{ #category : #private }
BlRopeableCollectionFile >> ensureBuffered: anInteger [
"Ensure the character at anInteger is buffered"
| mapEntry characterStream rawBuffer |
"Ensure the character at anInteger is buffered.
anInteger is the position in the underlying binary stream, not the character position."

((anInteger between: bufferStart and: bufferStart + bufferedSize - 1) and: [ bufferStart > 0 ]) ifTrue: [ ^self ].
(haveSize and: [ anInteger > self size ]) ifTrue: [ ^self ].
| mapEntry rawBuffer |
((anInteger between: bufferStart and: bufferStart + bufferedSize - 1)
and: [ bufferStart > 0 ]) ifTrue: [ ^ self ].
(haveSize and: [ anInteger > self size ]) ifTrue: [ ^ self ].

mapEntry := self mapEntryFor: anInteger.

binaryStream position: mapEntry value.
bufferStart := mapEntry key.
bufferedSize := 0.
characterStream := self characterStream.

"All of the below should be modified to work with existing collections,
not discarding and creating on each iteration"

[ (anInteger > (bufferStart + bufferedSize - 1)) or: [ bufferStart = 0 ] ] whileTrue:
[ bufferStart := bufferStart + bufferedSize.
rawBuffer := self loadNext: bufferSize with: characterStream.
buffer := rawBuffer.
bufferedSize := buffer size.
map add: (bufferStart + bufferedSize - 1) -> binaryStream position.
haveSize := haveSize or: [ binaryStream atEnd ].
(haveSize and: [ anInteger >= self size ]) ifTrue: [ ^self ] ].

self characterStreamDo: [ :stream |
stream position: mapEntry value.
bufferStart := mapEntry key.
bufferedSize := 0.
[ anInteger > (bufferStart + bufferedSize - 1) or: [ bufferStart = 0 ] ] whileTrue:
[ bufferStart := bufferStart + bufferedSize.
rawBuffer := self loadNext: bufferSize with: stream.
buffer := rawBuffer.
bufferedSize := buffer size.
map add: bufferStart + bufferedSize -> stream position.
haveSize := haveSize or: [ stream atEnd ].
(haveSize and: [ anInteger >= self size ]) ifTrue: [ ^ self ] ] ]
]

{ #category : #accessing }
Expand All @@ -230,13 +207,7 @@ BlRopeableCollectionFile >> fileReference [
{ #category : #accessing }
BlRopeableCollectionFile >> fileReference: aFileReference [

binaryStream ifNotNil: [ binaryStream close ].
fileReference := aFileReference asFileReference.
binaryStream := fileReference binaryReadStream.
WeakRegistry default
add: self
finalizer:
(BlRopeableCollectionFileFinalizer new binaryStream: binaryStream)
fileReference := aFileReference
]

{ #category : #comparing }
Expand Down Expand Up @@ -269,17 +240,19 @@ BlRopeableCollectionFile >> initialize [
BlRopeableCollectionFile >> loadNext: aNumber with: aReadStream [
"Answer the next aNumber characters using aReadstream.
If an encoding error occurs and strict is false, fall back to null encoding"
| startPosition |

startPosition := binaryStream position.
| startPosition |
startPosition := aReadStream position.
^ [ aReadStream next: aNumber ]
on: ZnCharacterEncodingError
do: [ :ex |
strict ifTrue:
[ ex pass ]
ifFalse:
[ binaryStream position: startPosition.
self loadNext: aNumber with: self nullEncodedStream ] ]
strict
ifTrue: [ ex pass ]
ifFalse: [
aReadStream position: startPosition.
self loadNext: aNumber with: (ZnCharacterReadStream
on: aReadStream wrappedStream
encoding: 'null') ] ]
]

{ #category : #'private - testing' }
Expand Down Expand Up @@ -326,15 +299,6 @@ BlRopeableCollectionFile >> mapEntryFor: anInteger [

]

{ #category : #private }
BlRopeableCollectionFile >> nullEncodedStream [
"Answer a read stream with null (ascii) character decoding on the receiver's binary stream"

^ ZnCharacterReadStream
on: binaryStream
encoding: 'null'
]

{ #category : #accessing }
BlRopeableCollectionFile >> size [
"Answer the receiver's size.
Expand All @@ -346,7 +310,7 @@ BlRopeableCollectionFile >> size [
self ensureBuffered: 1 ].

^ haveSize
ifTrue: [ map last key ]
ifTrue: [ map last key - 1 ]
ifFalse: [ BlTextIndexEOS new text: self ]
]

Expand Down
24 changes: 0 additions & 24 deletions src/Bloc/BlRopeableCollectionFileFinalizer.class.st

This file was deleted.