@@ -17,7 +17,6 @@ class TreeBuffer extends TastyBuffer(50000) {
17
17
private val initialOffsetSize = bytes.length / (AddrWidth * ItemsOverOffsets )
18
18
private var offsets = new Array [Int ](initialOffsetSize)
19
19
private var isRelative = new Array [Boolean ](initialOffsetSize)
20
- private var delta : Array [Int ] = _
21
20
private var numOffsets = 0
22
21
23
22
/** A map from trees to the address at which a tree is pickled. */
@@ -68,109 +67,113 @@ class TreeBuffer extends TastyBuffer(50000) {
68
67
}
69
68
70
69
/** The amount by which the bytes at the given address are shifted under compression */
71
- def deltaAt (at : Addr ): Int = {
70
+ def deltaAt (at : Addr , scratch : ScratchData ): Int = {
72
71
val idx = bestFit(offsets, numOffsets, at.index - 1 )
73
- if (idx < 0 ) 0 else delta(idx)
72
+ if (idx < 0 ) 0 else scratch. delta(idx)
74
73
}
75
74
76
75
/** The address to which `x` is translated under compression */
77
- def adjusted (x : Addr ): Addr = x - deltaAt(x)
76
+ def adjusted (x : Addr , scratch : ScratchData ): Addr = x - deltaAt(x, scratch)
77
+
78
+ /** Final assembly, involving the following steps:
79
+ * - compute deltas
80
+ * - adjust deltas until additional savings are < 1% of total
81
+ * - adjust offsets according to the adjusted deltas
82
+ * - shrink buffer, skipping zeroes.
83
+ */
84
+ def compactify (scratch : ScratchData ): Unit =
78
85
79
86
/** Compute all shift-deltas */
80
- private def computeDeltas () = {
81
- delta = new Array [Int ](numOffsets)
82
- var lastDelta = 0
83
- var i = 0
84
- while (i < numOffsets) {
85
- val off = offset(i)
86
- val skippedOff = skipZeroes(off)
87
- val skippedCount = skippedOff.index - off.index
88
- assert(skippedCount < AddrWidth , s " unset field at position $off" )
89
- lastDelta += skippedCount
90
- delta(i) = lastDelta
91
- i += 1
87
+ def computeDeltas () = {
88
+ if scratch.delta.length < numOffsets then
89
+ scratch.delta = new Array [Int ](numOffsets)
90
+ scratch.delta1 = new Array [Int ](numOffsets)
91
+ var lastDelta = 0
92
+ var i = 0
93
+ while (i < numOffsets) {
94
+ val off = offset(i)
95
+ val skippedOff = skipZeroes(off)
96
+ val skippedCount = skippedOff.index - off.index
97
+ assert(skippedCount < AddrWidth , s " unset field at position $off" )
98
+ lastDelta += skippedCount
99
+ scratch.delta(i) = lastDelta
100
+ i += 1
101
+ }
92
102
}
93
- }
94
103
95
- /** The absolute or relative adjusted address at index `i` of `offsets` array*/
96
- private def adjustedOffset (i : Int ): Addr = {
97
- val at = offset(i)
98
- val original = getAddr(at)
99
- if (isRelative(i)) {
100
- val start = skipNat(at)
101
- val len1 = original + delta(i) - deltaAt(original + start.index)
102
- val len2 = adjusted(original + start.index) - adjusted(start).index
103
- assert(len1 == len2,
104
- s " adjusting offset # $i: $at, original = $original, len1 = $len1, len2 = $len2" )
105
- len1
104
+ /** The absolute or relative adjusted address at index `i` of `offsets` array*/
105
+ def adjustedOffset (i : Int ): Addr = {
106
+ val at = offset(i)
107
+ val original = getAddr(at)
108
+ if (isRelative(i)) {
109
+ val start = skipNat(at)
110
+ val len1 = original + scratch.delta(i) - deltaAt(original + start.index, scratch)
111
+ val len2 = adjusted(original + start.index, scratch) - adjusted(start, scratch).index
112
+ assert(len1 == len2,
113
+ s " adjusting offset # $i: $at, original = $original, len1 = $len1, len2 = $len2" )
114
+ len1
115
+ }
116
+ else adjusted(original, scratch)
106
117
}
107
- else adjusted(original)
108
- }
109
118
110
- /** Adjust all offsets according to previously computed deltas */
111
- private def adjustOffsets (): Unit =
112
- var i = 0
113
- while i < numOffsets do
114
- val corrected = adjustedOffset(i)
115
- fillAddr(offset(i), corrected)
116
- i += 1
117
-
118
- /** Adjust deltas to also take account references that will shrink (and thereby
119
- * generate additional zeroes that can be skipped) due to previously
120
- * computed adjustments.
121
- */
122
- private def adjustDeltas (): Int = {
123
- val delta1 = new Array [Int ](delta.length)
124
- var lastDelta = 0
125
- var i = 0
126
- while i < numOffsets do
127
- val corrected = adjustedOffset(i)
128
- lastDelta += AddrWidth - TastyBuffer .natSize(corrected.index)
129
- delta1(i) = lastDelta
130
- i += 1
131
- val saved =
132
- if (numOffsets == 0 ) 0
133
- else delta1(numOffsets - 1 ) - delta(numOffsets - 1 )
134
- delta = delta1
135
- saved
136
- }
119
+ /** Adjust all offsets according to previously computed deltas */
120
+ def adjustOffsets (): Unit =
121
+ var i = 0
122
+ while i < numOffsets do
123
+ val corrected = adjustedOffset(i)
124
+ fillAddr(offset(i), corrected)
125
+ i += 1
126
+
127
+ /** Adjust deltas to also take account references that will shrink (and thereby
128
+ * generate additional zeroes that can be skipped) due to previously
129
+ * computed adjustments.
130
+ */
131
+ def adjustDeltas (): Int = {
132
+ var lastDelta = 0
133
+ var i = 0
134
+ while i < numOffsets do
135
+ val corrected = adjustedOffset(i)
136
+ lastDelta += AddrWidth - TastyBuffer .natSize(corrected.index)
137
+ scratch.delta1(i) = lastDelta
138
+ i += 1
139
+ val saved =
140
+ if (numOffsets == 0 ) 0
141
+ else scratch.delta1(numOffsets - 1 ) - scratch.delta(numOffsets - 1 )
142
+ val tmp = scratch.delta
143
+ scratch.delta = scratch.delta1
144
+ scratch.delta1 = tmp
145
+ saved
146
+ }
137
147
138
- /** Compress pickle buffer, shifting bytes to close all skipped zeroes. */
139
- private def compress (): Int = {
140
- var lastDelta = 0
141
- var start = 0
142
- var i = 0
143
- var wasted = 0
144
- def shift (end : Int ) =
145
- System .arraycopy(bytes, start, bytes, start - lastDelta, end - start)
146
- while (i < numOffsets) {
147
- val next = offsets(i)
148
- shift(next)
149
- start = next + delta(i) - lastDelta
150
- val pastZeroes = skipZeroes(Addr (next)).index
151
- assert(pastZeroes >= start, s " something's wrong: eliminated non-zero " )
152
- wasted += (pastZeroes - start)
153
- lastDelta = delta(i)
154
- i += 1
148
+ /** Compress pickle buffer, shifting bytes to close all skipped zeroes. */
149
+ def compress (): Int = {
150
+ var lastDelta = 0
151
+ var start = 0
152
+ var i = 0
153
+ var wasted = 0
154
+ def shift (end : Int ) =
155
+ System .arraycopy(bytes, start, bytes, start - lastDelta, end - start)
156
+ while (i < numOffsets) {
157
+ val next = offsets(i)
158
+ shift(next)
159
+ start = next + scratch.delta(i) - lastDelta
160
+ val pastZeroes = skipZeroes(Addr (next)).index
161
+ assert(pastZeroes >= start, s " something's wrong: eliminated non-zero " )
162
+ wasted += (pastZeroes - start)
163
+ lastDelta = scratch.delta(i)
164
+ i += 1
165
+ }
166
+ shift(length)
167
+ length -= lastDelta
168
+ wasted
155
169
}
156
- shift(length)
157
- length -= lastDelta
158
- wasted
159
- }
160
170
161
- def adjustTreeAddrs (): Unit =
162
- var i = 0
163
- while i < treeAddrs.size do
164
- treeAddrs.setValue(i, adjusted(Addr (treeAddrs.value(i))).index)
165
- i += 1
171
+ def adjustTreeAddrs (): Unit =
172
+ var i = 0
173
+ while i < treeAddrs.size do
174
+ treeAddrs.setValue(i, adjusted(Addr (treeAddrs.value(i)), scratch ).index)
175
+ i += 1
166
176
167
- /** Final assembly, involving the following steps:
168
- * - compute deltas
169
- * - adjust deltas until additional savings are < 1% of total
170
- * - adjust offsets according to the adjusted deltas
171
- * - shrink buffer, skipping zeroes.
172
- */
173
- def compactify (): Unit = {
174
177
val origLength = length
175
178
computeDeltas()
176
179
// println(s"offsets: ${offsets.take(numOffsets).deep}")
@@ -185,5 +188,5 @@ class TreeBuffer extends TastyBuffer(50000) {
185
188
adjustTreeAddrs()
186
189
val wasted = compress()
187
190
pickling.println(s " original length: $origLength, compressed to: $length, wasted: $wasted" ) // DEBUG, for now.
188
- }
191
+ end compactify
189
192
}
0 commit comments