transforms/Xtreams__CollectReadStream.st
author mkobetic
Sun, 15 Jan 2012 22:38:15 +0000
changeset 50 475076a05319
parent 40 9cf7a05861e6
child 51 79cd91a589d8
permissions -rw-r--r--
packaging
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
50
475076a05319 packaging
mkobetic
parents: 40
diff changeset
     1
'From Smalltalk/X, Version:6.2.1 on 15-01-2012 at 05:38:19 PM'                  !
40
9cf7a05861e6 sockets and files
mkobetic
parents: 35
diff changeset
     2
10
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     3
"{ Package: 'stx:goodies/xtreams/transforms' }"
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     4
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     5
"{ NameSpace: Xtreams }"
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     6
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     7
ReadStream subclass:#CollectReadStream
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     8
	instanceVariableNames:'block cache contentsSpecies direct'
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
     9
	classVariableNames:''
40
9cf7a05861e6 sockets and files
mkobetic
parents: 35
diff changeset
    10
	poolDictionaries:'XtreamsPool'
27
2cc5a8a3ca14 added XtreamsPool to fix DefaultBufferSize; set proper category names
mkobetic
parents: 10
diff changeset
    11
	category:'Xtreams-Transforms'
10
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    12
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    13
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    14
CollectReadStream comment:'Converts elements being read using the provided conversion block. When the contentSpecies of the source doesn''t match the desired contentSpecies of this stream, we optimize bulk reads by reading into an internal buffer.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    15
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    16
Instance Variables
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    17
	block	<BlockClosure> collecting block (same style as collect: blocks)
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    18
	cache	<SequenceableCollection | nil> caches elements before transformation when direct is false
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    19
	contentsSpecies	<Class> species for collections of elements of this stream
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    20
	direct	<Boolean> are we using an intermediate buffer (when source''s contentSpecies doesn''t match ours)
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    21
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    22
'
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    23
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    24
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    25
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    26
!CollectReadStream class methodsFor:'instance creation'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    27
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    28
on: aReadStream block: block
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    29
	^self new on: aReadStream block: block
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    30
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    31
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    32
!CollectReadStream methodsFor:'accessing'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    33
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    34
block
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    35
	^block
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    36
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    37
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    38
get
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    39
	^block value: source get
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    40
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    41
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    42
read: anInteger into: aSequenceableCollection at: startIndex
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    43
	direct
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    44
		ifTrue:	[self directRead: anInteger into: aSequenceableCollection at: startIndex]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    45
		ifFalse:	[self bufferRead: anInteger into: aSequenceableCollection at: startIndex].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    46
	^anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    47
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    48
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    49
!CollectReadStream methodsFor:'initialize-release'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    50
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    51
close
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    52
	super close.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    53
	cache ifNotNil: [ cache recycle ]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    54
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    55
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    56
contentsSpecies
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    57
	^contentsSpecies
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    58
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    59
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    60
contentsSpecies: aClass
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    61
	contentsSpecies := aClass.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    62
	cache ifNotNil: [ cache recycle ].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    63
	cache := (direct := contentsSpecies == source contentsSpecies)
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    64
		ifTrue:	[nil]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    65
		ifFalse:	[
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    66
			source contentsSpecies newRecycled: (
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    67
				(cache notNil and: [ cache size > 0 ])
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    68
					ifTrue: [cache size]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    69
					ifFalse: [DefaultBufferSize])]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    70
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    71
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    72
on: aSource block: aBlock
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    73
	self on: aSource.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    74
	block := aBlock.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    75
	contentsSpecies := aSource contentsSpecies.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    76
	direct := true
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    77
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    78
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    79
!CollectReadStream methodsFor:'private'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    80
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    81
bufferRead: anInteger into: aSequenceableCollection at: startIndex
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    82
	| amount count read |
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    83
	count := 0.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    84
	[count < anInteger] whileTrue:
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    85
		[amount := (anInteger - count) min: cache size.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    86
		read := [source read: amount into: cache at: 1. amount] on: Incomplete do: [ :ex | ex count ].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    87
		1 to: read do: [:index | aSequenceableCollection at: count + startIndex + index - 1 put: (block value: (cache at: index))].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    88
		count := count + read.
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    89
		read < amount ifTrue: [(Incomplete on: aSequenceableCollection count: count at: startIndex) raise]]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    90
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    91
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    92
directRead: anInteger into: aSequenceableCollection at: startIndex
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    93
	| count |
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    94
	count := [source read: anInteger into: aSequenceableCollection at: startIndex. anInteger] on: Incomplete do: [ :ex | ex count ].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    95
	startIndex to: startIndex + count - 1 do: [:index | aSequenceableCollection at: index put: (block value: (aSequenceableCollection at: index))].
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    96
	count < anInteger ifTrue: [(Incomplete on: aSequenceableCollection count: count at: startIndex) raise]
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    97
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    98
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
    99
!CollectReadStream methodsFor:'seeking'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   100
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   101
++ anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   102
	^source ++ anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   103
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   104
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   105
-- anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   106
	^source -- anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   107
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   108
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   109
length
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   110
	^source length
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   111
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   112
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   113
position
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   114
	^source position
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   115
!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   116
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   117
position: anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   118
	^source position: anInteger
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   119
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   120
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   121
!CollectReadStream methodsFor:'testing'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   122
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   123
isPositionable
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   124
	^source isPositionable
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   125
! !
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   126
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   127
!CollectReadStream class methodsFor:'documentation'!
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   128
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   129
version_SVN
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   130
    ^ '$Id$'
3813193bdf4e first cut
Martin Kobetic <mkobetic@gmail.com>
parents:
diff changeset
   131
! !