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
49 package jdbm.recman;
50
51 import java.io.IOException;
52
53 import java.util.HashMap;
54 import java.util.Map;
55
56 import jdbm.RecordManager;
57 import jdbm.helper.Serializer;
58 import jdbm.helper.DefaultSerializer;
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83 public final class BaseRecordManager
84 implements RecordManager
85 {
86
87
88
89
90 private RecordFile _file;
91
92
93
94
95
96 private PhysicalRowIdManager _physMgr;
97
98
99
100
101
102 private LogicalRowIdManager _logMgr;
103
104
105
106
107
108 private PageManager _pageman;
109
110
111
112
113
114 public static final int NAME_DIRECTORY_ROOT = 0;
115
116
117
118
119
120 public static final boolean DEBUG = false;
121
122
123
124
125
126
127
128 private Map _nameDirectory;
129
130
131
132
133
134
135
136
137 public BaseRecordManager( String filename )
138 throws IOException
139 {
140 _file = new RecordFile( filename );
141 _pageman = new PageManager( _file );
142 _physMgr = new PhysicalRowIdManager( _file, _pageman );
143 _logMgr = new LogicalRowIdManager( _file, _pageman );
144 }
145
146
147
148
149
150 public synchronized TransactionManager getTransactionManager()
151 {
152 checkIfClosed();
153
154 return _file.txnMgr;
155 }
156
157
158
159
160
161
162
163
164
165
166
167 public synchronized void disableTransactions()
168 {
169 checkIfClosed();
170
171 _file.disableTransactions();
172 }
173
174
175
176
177
178
179
180 public synchronized void close()
181 throws IOException
182 {
183 checkIfClosed();
184
185 _pageman.close();
186 _pageman = null;
187
188 _file.close();
189 _file = null;
190 }
191
192
193
194
195
196
197
198
199
200 public long insert( Object obj )
201 throws IOException
202 {
203 return insert( obj, DefaultSerializer.INSTANCE );
204 }
205
206
207
208
209
210
211
212
213
214
215 public synchronized long insert( Object obj, Serializer serializer )
216 throws IOException
217 {
218 byte[] data;
219 long recid;
220 Location physRowId;
221
222 checkIfClosed();
223
224 data = serializer.serialize( obj );
225 physRowId = _physMgr.insert( data, 0, data.length );
226 recid = _logMgr.insert( physRowId ).toLong();
227 if ( DEBUG ) {
228 System.out.println( "BaseRecordManager.insert() recid " + recid + " length " + data.length ) ;
229 }
230 return recid;
231 }
232
233
234
235
236
237
238
239 public synchronized void delete( long recid )
240 throws IOException
241 {
242 checkIfClosed();
243 if ( recid <= 0 ) {
244 throw new IllegalArgumentException( "Argument 'recid' is invalid: "
245 + recid );
246 }
247
248 if ( DEBUG ) {
249 System.out.println( "BaseRecordManager.delete() recid " + recid ) ;
250 }
251
252 Location logRowId = new Location( recid );
253 Location physRowId = _logMgr.fetch( logRowId );
254 _physMgr.delete( physRowId );
255 _logMgr.delete( logRowId );
256 }
257
258
259
260
261
262
263
264
265
266 public void update( long recid, Object obj )
267 throws IOException
268 {
269 update( recid, obj, DefaultSerializer.INSTANCE );
270 }
271
272
273
274
275
276
277
278
279
280
281 public synchronized void update( long recid, Object obj, Serializer serializer )
282 throws IOException
283 {
284 checkIfClosed();
285 if ( recid <= 0 ) {
286 throw new IllegalArgumentException( "Argument 'recid' is invalid: "
287 + recid );
288 }
289
290 Location logRecid = new Location( recid );
291 Location physRecid = _logMgr.fetch( logRecid );
292
293 byte[] data = serializer.serialize( obj );
294 if ( DEBUG ) {
295 System.out.println( "BaseRecordManager.update() recid " + recid + " length " + data.length ) ;
296 }
297
298 Location newRecid = _physMgr.update( physRecid, data, 0, data.length );
299 if ( ! newRecid.equals( physRecid ) ) {
300 _logMgr.update( logRecid, newRecid );
301 }
302 }
303
304
305
306
307
308
309
310
311
312 public Object fetch( long recid )
313 throws IOException
314 {
315 return fetch( recid, DefaultSerializer.INSTANCE );
316 }
317
318
319
320
321
322
323
324
325
326
327 public synchronized Object fetch( long recid, Serializer serializer )
328 throws IOException
329 {
330 byte[] data;
331
332 checkIfClosed();
333 if ( recid <= 0 ) {
334 throw new IllegalArgumentException( "Argument 'recid' is invalid: "
335 + recid );
336 }
337 data = _physMgr.fetch( _logMgr.fetch( new Location( recid ) ) );
338 if ( DEBUG ) {
339 System.out.println( "BaseRecordManager.fetch() recid " + recid + " length " + data.length ) ;
340 }
341 return serializer.deserialize( data );
342 }
343
344
345
346
347
348
349
350
351 public int getRootCount()
352 {
353 return FileHeader.NROOTS;
354 }
355
356
357
358
359
360
361 public synchronized long getRoot( int id )
362 throws IOException
363 {
364 checkIfClosed();
365
366 return _pageman.getFileHeader().getRoot( id );
367 }
368
369
370
371
372
373
374
375 public synchronized void setRoot( int id, long rowid )
376 throws IOException
377 {
378 checkIfClosed();
379
380 _pageman.getFileHeader().setRoot( id, rowid );
381 }
382
383
384
385
386
387
388 public long getNamedObject( String name )
389 throws IOException
390 {
391 checkIfClosed();
392
393 Map nameDirectory = getNameDirectory();
394 Long recid = (Long) nameDirectory.get( name );
395 if ( recid == null ) {
396 return 0;
397 }
398 return recid.longValue();
399 }
400
401
402
403
404 public void setNamedObject( String name, long recid )
405 throws IOException
406 {
407 checkIfClosed();
408
409 Map nameDirectory = getNameDirectory();
410 if ( recid == 0 ) {
411
412 nameDirectory.remove( name );
413 } else {
414 nameDirectory.put( name, new Long( recid ) );
415 }
416 saveNameDirectory( nameDirectory );
417 }
418
419
420
421
422
423 public synchronized void commit()
424 throws IOException
425 {
426 checkIfClosed();
427
428 _pageman.commit();
429 }
430
431
432
433
434
435 public synchronized void rollback()
436 throws IOException
437 {
438 checkIfClosed();
439
440 _pageman.rollback();
441 }
442
443
444
445
446
447 private Map getNameDirectory()
448 throws IOException
449 {
450
451 long nameDirectory_recid = getRoot( NAME_DIRECTORY_ROOT );
452 if ( nameDirectory_recid == 0 ) {
453 _nameDirectory = new HashMap();
454 nameDirectory_recid = insert( _nameDirectory );
455 setRoot( NAME_DIRECTORY_ROOT, nameDirectory_recid );
456 } else {
457 _nameDirectory = (Map) fetch( nameDirectory_recid );
458 }
459 return _nameDirectory;
460 }
461
462
463 private void saveNameDirectory( Map directory )
464 throws IOException
465 {
466 long recid = getRoot( NAME_DIRECTORY_ROOT );
467 if ( recid == 0 ) {
468 throw new IOException( "Name directory must exist" );
469 }
470 update( recid, _nameDirectory );
471 }
472
473
474
475
476
477
478 private void checkIfClosed()
479 throws IllegalStateException
480 {
481 if ( _file == null ) {
482 throw new IllegalStateException( "RecordManager has been closed" );
483 }
484 }
485 }