1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 package jdbm.recman;
49
50 import java.io.*;
51
52
53
54
55
56
57
58
59
60
61 public final class BlockIo implements java.io.Externalizable {
62
63 public final static long serialVersionUID = 2L;
64
65 private long blockId;
66
67 private transient byte[] data;
68 private transient BlockView view = null;
69 private transient boolean dirty = false;
70 private transient int transactionCount = 0;
71
72
73
74
75 public BlockIo() {
76
77 }
78
79
80
81
82
83 BlockIo(long blockId, byte[] data) {
84
85 if (blockId > 10000000000L)
86 throw new Error("bogus block id " + blockId);
87 this.blockId = blockId;
88 this.data = data;
89 }
90
91
92
93
94 byte[] getData() {
95 return data;
96 }
97
98
99
100
101 void setBlockId(long id) {
102 if (isInTransaction())
103 throw new Error("BlockId assigned for transaction block");
104
105 if (id > 10000000000L)
106 throw new Error("bogus block id " + id);
107 blockId = id;
108 }
109
110
111
112
113 long getBlockId() {
114 return blockId;
115 }
116
117
118
119
120 public BlockView getView() {
121 return view;
122 }
123
124
125
126
127 public void setView(BlockView view) {
128 this.view = view;
129 }
130
131
132
133
134 void setDirty() {
135 dirty = true;
136 }
137
138
139
140
141 void setClean() {
142 dirty = false;
143 }
144
145
146
147
148 boolean isDirty() {
149 return dirty;
150 }
151
152
153
154
155
156 boolean isInTransaction() {
157 return transactionCount != 0;
158 }
159
160
161
162
163
164
165 synchronized void incrementTransactionCount() {
166 transactionCount++;
167
168 setClean();
169 }
170
171
172
173
174
175 synchronized void decrementTransactionCount() {
176 transactionCount--;
177 if (transactionCount < 0)
178 throw new Error("transaction count on block "
179 + getBlockId() + " below zero!");
180
181 }
182
183
184
185
186 public byte readByte(int pos) {
187 return data[pos];
188 }
189
190
191
192
193 public void writeByte(int pos, byte value) {
194 data[pos] = value;
195 setDirty();
196 }
197
198
199
200
201 public short readShort(int pos) {
202 return (short)
203 (((short) (data[pos+0] & 0xff) << 8) |
204 ((short) (data[pos+1] & 0xff) << 0));
205 }
206
207
208
209
210 public void writeShort(int pos, short value) {
211 data[pos+0] = (byte)(0xff & (value >> 8));
212 data[pos+1] = (byte)(0xff & (value >> 0));
213 setDirty();
214 }
215
216
217
218
219 public int readInt(int pos) {
220 return
221 (((int)(data[pos+0] & 0xff) << 24) |
222 ((int)(data[pos+1] & 0xff) << 16) |
223 ((int)(data[pos+2] & 0xff) << 8) |
224 ((int)(data[pos+3] & 0xff) << 0));
225 }
226
227
228
229
230 public void writeInt(int pos, int value) {
231 data[pos+0] = (byte)(0xff & (value >> 24));
232 data[pos+1] = (byte)(0xff & (value >> 16));
233 data[pos+2] = (byte)(0xff & (value >> 8));
234 data[pos+3] = (byte)(0xff & (value >> 0));
235 setDirty();
236 }
237
238
239
240
241 public long readLong( int pos )
242 {
243
244
245 return
246 ( (long)( ((data[pos+0] & 0xff) << 24) |
247 ((data[pos+1] & 0xff) << 16) |
248 ((data[pos+2] & 0xff) << 8) |
249 ((data[pos+3] & 0xff) ) ) << 32 ) |
250 ( (long)( ((data[pos+4] & 0xff) << 24) |
251 ((data[pos+5] & 0xff) << 16) |
252 ((data[pos+6] & 0xff) << 8) |
253 ((data[pos+7] & 0xff) ) ) & 0xffffffff );
254
255
256
257
258
259
260
261
262
263
264
265 }
266
267
268
269
270 public void writeLong(int pos, long value) {
271 data[pos+0] = (byte)(0xff & (value >> 56));
272 data[pos+1] = (byte)(0xff & (value >> 48));
273 data[pos+2] = (byte)(0xff & (value >> 40));
274 data[pos+3] = (byte)(0xff & (value >> 32));
275 data[pos+4] = (byte)(0xff & (value >> 24));
276 data[pos+5] = (byte)(0xff & (value >> 16));
277 data[pos+6] = (byte)(0xff & (value >> 8));
278 data[pos+7] = (byte)(0xff & (value >> 0));
279 setDirty();
280 }
281
282
283
284 public String toString() {
285 return "BlockIO("
286 + blockId + ","
287 + dirty + ","
288 + view + ")";
289 }
290
291
292 public void readExternal(ObjectInput in)
293 throws IOException, ClassNotFoundException {
294 blockId = in.readLong();
295 int length = in.readInt();
296 data = new byte[length];
297 in.readFully(data);
298 }
299
300
301 public void writeExternal(ObjectOutput out) throws IOException {
302 out.writeLong(blockId);
303 out.writeInt(data.length);
304 out.write(data);
305 }
306
307 }