KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mckoi > database > V1MasterTableDataSource


1 /**
2  * com.mckoi.database.V1MasterTableDataSource 01 Sep 2002
3  *
4  * Mckoi SQL Database ( http://www.mckoi.com/database )
5  * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * Version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License Version 2 for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * Version 2 along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  *
20  * Change Log:
21  *
22  *
23  */

24
25 package com.mckoi.database;
26
27 import java.util.ArrayList JavaDoc;
28 import java.io.*;
29 import com.mckoi.util.IntegerListInterface;
30 import com.mckoi.util.ByteArrayUtil;
31 import com.mckoi.util.UserTerminal;
32 import com.mckoi.debug.*;
33
34 /**
35  * A MasterTableDataSource that uses IndexStore and VariableSizeDataStore as
36  * its backing mechanism for representing the table structure in a file on
37  * disk.
38  * <p>
39  * The MasterTableDataSource is basically backed by a VariableSizeDataStore
40  * for data and an IndexStore for storing indexing information.
41  *
42  * @author Tobias Downer
43  */

44
45 public final class V1MasterTableDataSource extends MasterTableDataSource {
46
47   // ---------- State information ----------
48

49   /**
50    * The file name of this store in the conglomerate path.
51    */

52   private String JavaDoc file_name;
53   
54   /**
55    * A VariableSizeDataStore object that physically contains the information
56    * stored in the file system in the contents of the data source.
57    */

58   private VariableSizeDataStore data_store;
59
60   /**
61    * An IndexStore object that manages the indexes for this table.
62    */

63   private IndexStore index_store;
64
65   /**
66    * The object we use to serialize TObject objects.
67    */

68   private final DataCellSerialization data_cell_serializer =
69                                             new DataCellSerialization();
70
71   /**
72    * The persistent object we use to read information from a row stream.
73    */

74   private CellInputStream cell_in;
75   
76   
77
78   /**
79    * The Constructor.
80    */

81   public V1MasterTableDataSource(TransactionSystem system,
82                                  StoreSystem store_system,
83                                  OpenTransactionList open_transactions) {
84     super(system, store_system, open_transactions, null);
85     cell_in = new CellInputStream(null);
86   }
87   
88   /**
89    * Returns the name of the file in the conglomerate that represents this
90    * store in the file system.
91    */

92   String JavaDoc getFileName() {
93     return file_name;
94   }
95   
96   /**
97    * Returns the path of where this table is located.
98    */

99   File getPath() {
100     return getSystem().getDatabasePath();
101   }
102   
103   /**
104    * Physically create this master table in the file system at the given
105    * path. This will initialise the various file objects and result in a
106    * new empty master table to store data in.
107    * <p>
108    * The 'data_sector_size' and 'index_sector_size' are for fine grain
109    * performance and size optimization of the data files. The default
110    * 'index_sector_size' is 1024.
111    *
112    * @param data_sector_size used to configure the size of the sectors in the
113    * data files. For tables with small records this number should be low.
114    * @param index_sector_size used to configure the size of the sectors in the
115    * index file. For small tables it is best to keep the index sector size
116    * low. Recommend 1024 for normal use, 128 for minimalist use.
117    */

118   synchronized void create(int table_id, DataTableDef table_def,
119                            int data_sector_size, int index_sector_size)
120                                                         throws IOException {
121
122     // Setup the internal methods
123
setupDataTableDef(table_def);
124     
125     // Generate the name of the store file name.
126
this.file_name = makeTableFileName(getSystem(), table_id, getTableName());
127     
128     // Create the store.
129
data_store = new VariableSizeDataStore(new File(getPath(), file_name),
130                                            data_sector_size, Debug());
131     // Open the store in read/write mode
132
data_store.open(false);
133
134     // Open table indices
135
index_store = new IndexStore(
136                             new File(getPath(), file_name + ".iid"), Debug());
137     // Open the table index file.
138
index_store.create(index_sector_size);
139     index_store.init();
140     // Make room for columns+1 indices in the index store file
141
index_store.addIndexLists(table_def.columnCount() + 1, (byte) 1);
142     index_store.flush();
143
144     // Save the table definition to the new store.
145
saveDataTableDef(table_def);
146
147     // Write the 'table_id' of this table to the reserved area of the data
148
// store.
149
byte[] reserved_buffer = new byte[64];
150     ByteArrayUtil.setInt(table_id, reserved_buffer, 0);
151     data_store.writeReservedBuffer(reserved_buffer, 0, 64);
152
153     // Set up internal state of this object
154
this.table_id = table_id;
155
156     // Load internal state
157
loadInternal();
158
159   }
160
161   /**
162    * Returns true if the master table data source with the given filename
163    * exists.
164    */

165   synchronized boolean exists(String JavaDoc file_name) throws IOException {
166     VariableSizeDataStore data_store =
167             new VariableSizeDataStore(new File(getPath(), file_name), Debug());
168     return data_store.exists();
169   }
170
171   /**
172    * Opens an existing master table from the file system at the path of the
173    * conglomerate this belongs to. This will set up the internal state of
174    * this object with the data read in.
175    */

176   synchronized void open(String JavaDoc file_name) throws IOException {
177
178     // Open the store.
179
data_store = new VariableSizeDataStore(
180                                      new File(getPath(), file_name), Debug());
181     boolean need_check = data_store.open(isReadOnly());
182
183     // Set up the internal state of this object
184
// Get the 'table_id' of this table from the reserved area of the data
185
// store.
186
byte[] reserved_buffer = new byte[64];
187     data_store.readReservedBuffer(reserved_buffer, 0, 64);
188     table_id = ByteArrayUtil.getInt(reserved_buffer, 0);
189
190     // Set the file name.
191
this.file_name = file_name;
192
193     // Load the table definition from the store.
194
table_def = loadDataTableDef();
195
196     // Set the column count
197
column_count = table_def.columnCount();
198
199     // Open table indices
200
table_indices = new MultiVersionTableIndices(getSystem(),
201                            table_def.getTableName(), table_def.columnCount());
202     // The column rid list cache
203
column_rid_list = new RIDList[table_def.columnCount()];
204     
205     // Open table indices
206
index_store = new IndexStore(
207                             new File(getPath(), file_name + ".iid"), Debug());
208     // If the index store doesn't exist then create it.
209
if (!index_store.exists()) {
210       if (!isReadOnly()) {
211         // Does the original .ijf file exist?
212
File original_ijf = new File(getPath(), file_name + ".ijf");
213         if (original_ijf.exists()) {
214           // Message
215
String JavaDoc str = "Converting index file for: " + file_name;
216           System.out.println(str);
217           Debug().write(Lvl.INFORMATION, this, str);
218           // NOTE: The following method leaves the index store open.
219
ArrayList JavaDoc transaction_journals =
220                   ConvertUtils.convertIndexFiles1(original_ijf, index_store,
221                                                   table_def, Debug());
222           if (transaction_journals.size() > 0) {
223             // Notify the user that this may be a problem
224
Debug().write(Lvl.ERROR, this,
225                     "There are uncommitted changes that were not " +
226                     "converted because the pre 0.92 database was not closed " +
227                     "cleanly.");
228           }
229           // Force a full table scan
230
need_check = true;
231         }
232         else {
233           throw new IOException("The index file for '" + file_name +
234                                 "' does not exist.");
235         }
236       }
237       else {
238         throw new IOException(
239                          "Can not create .iid index file in read-only mode.");
240       }
241     }
242     else {
243       // Open the table index file.
244
index_store.open(isReadOnly());
245       index_store.init();
246     }
247
248     // Load internal state
249
loadInternal();
250
251     // Setup a DataIndexSetDef from the information here
252
setupDataIndexSetDef();
253
254     if (need_check) {
255       // Do an opening scan of the table. Any records that are uncommited
256
// must be marked as deleted.
257
doOpeningScan();
258     }
259
260   }
261
262   /**
263    * Opens this source in the most minimal way. This should only be used
264    * for diagnostics of the data. This will not load the index.
265    */

266   synchronized void dirtyOpen(String JavaDoc file_name) throws IOException {
267
268     // We have to open this...
269
// Open the store.
270
data_store = new VariableSizeDataStore(
271                                      new File(getPath(), file_name), Debug());
272     data_store.open(false);
273
274     // Set up the internal state of this object
275
// Get the 'table_id' of this table from the reserved area of the data
276
// store.
277
byte[] reserved_buffer = new byte[64];
278     data_store.readReservedBuffer(reserved_buffer, 0, 64);
279     table_id = ByteArrayUtil.getInt(reserved_buffer, 0);
280
281     // Set the file name.
282
this.file_name = file_name;
283
284     // Load the table definition from the store.
285
table_def = loadDataTableDef();
286
287   }
288
289   /**
290    * Closes this master table in the file system. This frees up all the
291    * resources associated with this master table.
292    * <p>
293    * This method is typically called when the database is shut down.
294    */

295   synchronized void close() throws IOException {
296     if (table_indices != null) {
297       // Merge all journal changes when we close
298
mergeJournalChanges(Integer.MAX_VALUE);
299
300       if (!isReadOnly()) {
301         // Synchronize the current state with the file system.
302
index_store.flush();
303         //table_indices.synchronizeIndexFile();
304
}
305     }
306
307     // Close the index store.
308
index_store.close();
309     data_store.close();
310
311     table_id = -1;
312 // file_name = null;
313
table_def = null;
314     table_indices = null;
315     column_rid_list = null;
316     is_closed = true;
317   }
318
319   /**
320    * Returns the number of bytes the row takes up in the data file. This is
321    * the actual space used. If a cell is compressed then it includes the
322    * compressed size, not the uncompressed.
323    */

324   synchronized int rawRecordSize(int row_number) throws IOException {
325
326     int size = 2;
327
328     ++row_number;
329
330     // Open a stream for this row.
331
InputStream in = data_store.getRecordInputStream(row_number);
332     cell_in.setParentStream(in);
333
334     cell_in.skip(2);
335
336     for (int i = 0; i < column_count; ++i) {
337       int len = data_cell_serializer.skipSerialization(cell_in);
338       if (len <= 0) {
339         throw new Error JavaDoc("Corrupt data - cell size is <= 0");
340       }
341       cell_in.skip(len);
342       size += 4 + len;
343     }
344
345     cell_in.close();
346
347     return size;
348
349   }
350   
351   /**
352    * Returns the current sector size for this data source.
353    */

354   synchronized int rawDataSectorSize() throws IOException {
355     return data_store.sectorSize();
356   }
357   
358   /**
359    * This may only be called from the 'fix' method. It performs a full scan of
360    * the records and rebuilds all the index information from the information.
361    * <p>
362    * This should only be used as a recovery mechanism and may not accurately
363    * rebuild in some cases (but should rebuild as best as possible non the
364    * less).
365    */

366   private synchronized void rebuildAllIndices(File path, String JavaDoc file_name)
367                                                          throws IOException {
368
369     // Temporary name of the index store
370
File temporary_name = new File(path, file_name + ".id2");
371     // Actual name of the index store
372
File actual_name = new File(path, file_name + ".iid");
373
374     // Make a new blank index store
375
IndexStore temp_store = new IndexStore(temporary_name, Debug());
376     // Copy the same block size as the original
377
temp_store.create(index_store.getBlockSize());
378     temp_store.init();
379     temp_store.addIndexLists(column_count + 1, (byte) 1);
380
381     // Get the index of rows in this table
382
IndexSet index_set = temp_store.getSnapshotIndexSet();
383
384     // The master index,
385
IntegerListInterface master_index = index_set.getIndex(0);
386
387     // The selectable schemes for the table.
388
TableDataSource table = minimalTableDataSource(master_index);
389
390     // Create a set of index for this table.
391
SelectableScheme[] cols = new SelectableScheme[column_count];
392     for (int i = 0; i < column_count; ++i) {
393       cols[i] = createSelectableSchemeForColumn(index_set, table, i);
394     }
395
396     // For each row
397
int row_count = rawRowCount();
398     for (int i = 0 ; i < row_count; ++i) {
399       // Is this record marked as deleted?
400
if (!recordDeleted(i)) {
401         // Get the type flags for this record.
402
int type = recordTypeInfo(i);
403         // Check if this record is marked as committed removed, or is an
404
// uncommitted record.
405
if (type == RawDiagnosticTable.COMMITTED_ADDED) {
406           // Insert into the master index
407
master_index.uniqueInsertSort(i);
408           // Insert into schemes
409
for (int n = 0; n < column_count; ++n) {
410             cols[n].insert(i);
411           }
412         }
413       } // if not deleted
414
} // for each row
415

416     // Commit the index store
417

418     // Write the modified index set to the index store
419
// (Updates the index file)
420
temp_store.commitIndexSet(index_set);
421     index_set.dispose();
422     temp_store.flush();
423
424     // Close and delete the original index_store
425
index_store.close();
426     index_store.delete();
427     // Close the temporary store
428
temp_store.close();
429     // Rename temp file to the actual file
430
boolean b = temporary_name.renameTo(actual_name);
431     if (b == false) {
432       throw new IOException("Unable to rename " +
433                             temporary_name + " to " + actual_name);
434     }
435     temp_store = null;
436
437     // Copy and open the new reference
438
index_store = new IndexStore(actual_name, Debug());
439     index_store.open(false);
440     index_store.init();
441
442   }
443
444   /**
445    * Copies the persistant information in this table data source to the given
446    * directory in the file system. This makes an exact copy of the table as
447    * it currently is. It is recommended that when this is used, there is a
448    * lock to prevent committed changes to the database.
449    */

450   synchronized void copyTo(File path) throws IOException {
451     data_store.copyTo(path);
452     index_store.copyTo(path);
453   }
454
455
456
457   
458   // ---------- Diagnostic and repair ----------
459

460   /**
461    * Performs a complete check and repair of the table. The table must not
462    * have been opened before this method is called. The given UserTerminal
463    * parameter is an implementation of a user interface that is used to ask
464    * any questions and output the results of the check.
465    */

466   public synchronized void checkAndRepair(String JavaDoc file_name,
467                                    UserTerminal terminal) throws IOException {
468
469     // Open the store.
470
data_store = new VariableSizeDataStore(
471                                      new File(getPath(), file_name), Debug());
472     boolean need_check = data_store.open(isReadOnly());
473 // if (need_check) {
474
data_store.fix(terminal);
475 // }
476

477     // Set up the internal state of this object
478
// Get the 'table_id' of this table from the reserved area of the data
479
// store.
480
byte[] reserved_buffer = new byte[64];
481     data_store.readReservedBuffer(reserved_buffer, 0, 64);
482     table_id = ByteArrayUtil.getInt(reserved_buffer, 0);
483
484     // Set the file name.
485
this.file_name = file_name;
486
487     // Load the table definition from the store.
488
table_def = loadDataTableDef();
489
490
491
492
493     // Table journal information
494
table_indices = new MultiVersionTableIndices(getSystem(),
495                            table_def.getTableName(), table_def.columnCount());
496     // The column rid list cache
497
column_rid_list = new RIDList[table_def.columnCount()];
498
499     // Open table indices
500
index_store = new IndexStore(
501                             new File(getPath(), file_name + ".iid"), Debug());
502     // Open the table index file.
503
need_check = index_store.open(isReadOnly());
504     // Attempt to fix the table index file.
505
boolean index_store_stable = index_store.fix(terminal);
506
507     // Load internal state
508
loadInternal();
509
510     // Merge all journal changes when we open
511
mergeJournalChanges(Integer.MAX_VALUE);
512
513     // If the index store is not stable then clear it and rebuild the
514
// indices.
515
// if (!index_store_stable) {
516
terminal.println("+ Rebuilding all index information for table!");
517       rebuildAllIndices(getPath(), file_name);
518 // }
519

520     // Do an opening scan of the table. Any records that are uncommited
521
// must be marked as deleted.
522
doOpeningScan();
523
524   }
525
526   
527   public synchronized void checkForCleanup() {
528     // No-op
529
}
530
531   
532   // ---------- Implemented from AbstractMasterTableDataSource ----------
533

534   String JavaDoc getSourceIdent() {
535     return getFileName();
536   }
537
538
539   synchronized void synchAll() throws IOException {
540
541     // Flush the indices.
542
index_store.flush();
543
544     // Synchronize the data store.
545
if (!getSystem().dontSynchFileSystem()) {
546       data_store.hardSynch();
547     }
548
549     // Synchronize the file handle. When this returns, we are guarenteed that
550
// the index store and the data store are nore persistantly stored in the
551
// file system.
552
if (!getSystem().dontSynchFileSystem()) {
553       index_store.hardSynch();
554     }
555
556   }
557
558   
559   synchronized int writeRecordType(int row_index, int row_state)
560                                                           throws IOException {
561     return data_store.writeRecordType(row_index + 1, row_state);
562   }
563
564
565   synchronized int readRecordType(int row_index) throws IOException {
566     return data_store.readRecordType(row_index + 1);
567   }
568
569   
570   synchronized boolean recordDeleted(int row_index) throws IOException {
571     return data_store.recordDeleted(row_index + 1);
572   }
573
574
575   synchronized int rawRowCount() throws IOException {
576     return data_store.rawRecordCount() - 1;
577   }
578
579
580   
581   synchronized void internalDeleteRow(int row_index) throws IOException {
582     // Delete the row permanently from the data store.
583
data_store.delete(row_index + 1);
584   }
585
586
587   IndexSet createIndexSet() {
588     return index_store.getSnapshotIndexSet();
589   }
590
591   
592   synchronized void commitIndexSet(IndexSet index_set) {
593     index_store.commitIndexSet(index_set);
594     index_set.dispose();
595   }
596
597   
598   synchronized DataTableDef loadDataTableDef() throws IOException {
599     
600     // Read record 0 which contains all this info.
601
byte[] d = new byte[65536];
602     int read = data_store.read(0, d, 0, 65536);
603     if (read == 65536) {
604       throw new IOException(
605                      "Buffer overflow when reading table definition, > 64k");
606     }
607     ByteArrayInputStream bin = new ByteArrayInputStream(d, 0, read);
608
609     DataTableDef def;
610
611     DataInputStream din = new DataInputStream(bin);
612     int mn = din.readInt();
613     // This is the latest format...
614
if (mn == 0x0bebb) {
615       // Read the DataTableDef object from the input stream,
616
def = DataTableDef.read(din);
617     }
618     else {
619       // Legacy no longer supported...
620
throw new IOException(
621                 "Couldn't find magic number for table definition data.");
622     }
623
624     return def;
625     
626   }
627
628
629   synchronized void saveDataTableDef(DataTableDef def) throws IOException {
630     
631     ByteArrayOutputStream bout = new ByteArrayOutputStream();
632     DataOutputStream dout = new DataOutputStream(bout);
633
634     dout.writeInt(0x0bebb);
635     def.write(dout);
636
637     // Write the byte array to the data store,
638

639     byte[] d = bout.toByteArray();
640     int rindex = data_store.write(d, 0, d.length);
641
642     // rindex MUST be 0 else we buggered.
643
if (rindex != 0) {
644       throw new IOException("Couldn't write table fields to record 0.");
645     }
646     
647   }
648
649   
650   synchronized int internalAddRow(RowData data) throws IOException {
651
652     OutputStream out = data_store.getRecordOutputStream();
653     DataOutputStream temp_out = new DataOutputStream(out);
654
655     // Reserved for future use.
656
temp_out.writeShort(0);
657
658     int row_cells = data.getColumnCount();
659
660     // Write out the data,
661
for (int i = 0; i < row_cells; ++i) {
662       TObject cell = data.getCellData(i);
663       data_cell_serializer.setToSerialize(cell);
664       data_cell_serializer.writeSerialization(temp_out);
665     }
666
667     // Close the stream and complete it.
668
temp_out.close();
669     int record_index = data_store.completeRecordStreamWrite();
670
671     // Update the cell cache as appropriate
672
if (DATA_CELL_CACHING) {
673       for (int i = 0; i < row_cells; ++i) {
674         // Put the row/column/TObject into the cache.
675
cache.put(table_id, record_index, i, data.getCellData(i));
676       }
677     }
678
679     // Record index is -1 because sector 0 is DataTableDef.
680
int row_number = record_index - 1;
681
682     // If we have a rid_list for any of the columns, then update the indexing
683
// there,
684
for (int i = 0; i < column_count; ++i) {
685       RIDList rid_list = column_rid_list[i];
686       if (rid_list != null) {
687         rid_list.insertRID(data.getCellData(i), row_number);
688       }
689     }
690
691     // Return the record index of the new data in the table
692
return row_number;
693
694   }
695
696
697   // ---- getCellContents ----
698

699   private short s_run_total_hits = 0;
700   private short s_run_file_hits = 0;
701
702   // ---- Optimization that saves some cycles -----
703

704   /**
705    * Some variables that are used for optimization in the 'getCellContents'
706    * method.
707    */

708   private int OPT_last_row = -1;
709   private int OPT_last_col = -1;
710   private int OPT_last_skip_offset = -1;
711
712   synchronized TObject internalGetCellContents(int column, int row) {
713
714     // NOTES:
715
// This is called *A LOT*. It's a key part of the 20% of the program
716
// that's run 80% of the time.
717
// This performs very nicely for rows that are completely contained within
718
// 1 sector. However, rows that contain large cells (eg. a large binary
719
// or a large string) and spans many sectors will not be utilizing memory
720
// as well as it could.
721
// The reason is because all the data for a row is read from the store even
722
// if only 1 cell of the column is requested. This will have a big
723
// impact on column scans and searches. The cell cache takes some of this
724
// performance bottleneck away.
725
// However, a better implementation of this method is made difficult by
726
// the fact that sector spans can be compressed. We should perhaps
727
// revise the low level data storage so only sectors can be compressed.
728

729     // If the database stats need updating then do so now.
730
if (s_run_total_hits >= 1600) {
731       getSystem().stats().add(s_run_total_hits, total_hits_key);
732       getSystem().stats().add(s_run_file_hits, file_hits_key);
733       s_run_total_hits = 0;
734       s_run_file_hits = 0;
735     }
736     
737     // Increment the total hits counter
738
++s_run_total_hits;
739     
740     // Row 0 is reserved for DataTableDef
741
++row;
742
743     // First check if this is within the cache before we continue.
744
TObject cell;
745     if (DATA_CELL_CACHING) {
746       cell = cache.get(table_id, row, column);
747       if (cell != null) {
748         return cell;
749       }
750     }
751
752     // Increment the file hits counter
753
++s_run_file_hits;
754
755     // We maintain a cache of byte[] arrays that contain the rows read in
756
// from the file. If consequtive reads are made to the same row, then
757
// this will cause lots of fast cache hits.
758

759     try {
760
761       // Open a stream for this row.
762
InputStream in = data_store.getRecordInputStream(row);
763       cell_in.setParentStream(in);
764
765       // NOTE: This is an optimization for a common sequence of pulling cells
766
// from a row. It remembers the index of the last column read in, and
767
// if the next column requested is > than the last column read, then
768
// it trivially skips the file pointer to the old point.
769
// Variables starting with 'OPT_' are member variables used for
770
// keeping the optimization state information.
771

772       int start_col;
773       if (OPT_last_row == row && column >= OPT_last_col) {
774         cell_in.skip(OPT_last_skip_offset);
775         start_col = OPT_last_col;
776       }
777       else {
778         cell_in.skip(2);
779         OPT_last_row = row;
780         OPT_last_skip_offset = 2;
781         OPT_last_col = 0;
782         start_col = 0;
783       }
784
785       for (int i = start_col; i < column; ++i) {
786         int len = data_cell_serializer.skipSerialization(cell_in);
787         if (len <= 0) {
788           throw new Error JavaDoc("Corrupt data - cell size is <= 0");
789         }
790         cell_in.skip(len);
791         ++OPT_last_col;
792         OPT_last_skip_offset += len + 4; // ( +4 for the header )
793
}
794       // Read the cell
795
Object JavaDoc ob = data_cell_serializer.readSerialization(cell_in);
796       // Get the TType for this column
797
// NOTE: It's possible this call may need optimizing?
798
TType ttype = getDataTableDef().columnAt(column).getTType();
799       // Wrap it around a TObject
800
cell = new TObject(ttype, ob);
801
802       // And close the reader.
803
cell_in.close();
804
805       // And put in the cache and return it.
806
if (DATA_CELL_CACHING) {
807         cache.put(table_id, row, column, cell);
808       }
809       return cell;
810
811     }
812     catch (IOException e) {
813       Debug().writeException(e);
814       throw new Error JavaDoc("IOError getting cell at (" + column + ", " +
815                       row + ").");
816     }
817
818   }
819
820
821   synchronized long currentUniqueID() {
822     return index_store.currentUniqueID();
823   }
824
825   synchronized long nextUniqueID() {
826     return index_store.nextUniqueID();
827   }
828
829   synchronized void setUniqueID(long value) {
830     index_store.setUniqueID(value);
831   }
832
833
834   synchronized void dispose(boolean pending_close) throws IOException {
835     close();
836   }
837   
838   synchronized boolean drop() throws IOException {
839     if (!is_closed) {
840       close();
841     }
842     
843     Debug().write(Lvl.MESSAGE, this, "Dropping: " + getFileName());
844     data_store.delete();
845     index_store.delete();
846
847     return true;
848   }
849   
850   void shutdownHookCleanup() {
851     // This does nothing...
852
}
853   
854   /**
855    * For diagnostic.
856    */

857   public String JavaDoc toString() {
858     return "[V1MasterTableDataSource: " + file_name + "]";
859   }
860   
861 }
862
863
Popular Tags