Package com.mckoi.database

## Class VariableSizeDataStore

- java.lang.Object
- - com.mckoi.database.VariableSizeDataStore

    public class VariableSizeDataStore
    extends java.lang.Object

Provides a mechanism for storing variable length data in a file which can quickly be indexed via a reference number. The store maintains a master index file that contains a reference to all individual data records stored in the system. The data file contains all the data that has been stored.

This file format is not intended to be a fully fledged file system. For example, we can not easily change the size of a data entry. To change the record, we must delete it then add a new.

This system uses two files. One file is the index, and the second file stores the data. The index file contains sectors as follows:

       4 (int) : index  - The sector index of the data in the data file.
       4 (int) : length - Length of the data that was stored.
       4 (int) : status - 32 status bits.

This employs a simple compression scheme when writing out data that would span more than one sector. It tries compressing the field. If the field can be compressed into less sectors than if left uncompressed, then the compressed field is put into the data store.

Author:
  Tobias Downer

### Constructor Summary

Constructors
`VariableSizeDataStore​(java.io.File name, int sector_size, DebugLogger logger)` Constructs the variable size store.
`VariableSizeDataStore​(java.io.File name, DebugLogger logger)`

### Method Summary

All Methods Static Methods Instance Methods Concrete Methods
`void` `close()` Closes the data store.
`int` `completeRecordStreamWrite()` Updates the record allocation table with the data in the output stream returned by 'getRecordOutputStream'.
`void` `copyTo​(java.io.File path)` Copies this data store to the given path.
`void` `delete()` Deletes the store from the file system.
`int` `delete​(int record)` Deletes the data at the given index position.
`static boolean` `delete​(java.io.File path, java.lang.String name)` Convenience for deleting a VariableSizeDataStore store.
`boolean` `exists()` Returns true if the data store exists.
`static boolean` `exists​(java.io.File path, java.lang.String name)` Convenience for checking if a given data store exists or not.
`void` `fix​(UserTerminal terminal)` Attempts to fix a corrupt VariableSizeDataStore object.
`java.io.InputStream` `getRecordInputStream​(int record)` Returns an InputStream that is used to read a record in this store with the given index.
`java.io.OutputStream` `getRecordOutputStream()` Returns an OutputStream object that can be used to write data into the store.
`void` `hardSynch()` Hard synchronizes the data from memory into the hard copy on disk.
`boolean` `isCompressed​(int record)` Returns true if the given record is compressed.
`boolean` `isReadOnly()` Returns true if the store was openned in read only mode.
`void` `lock()` Locks the store so that not deleted elements may be overwritten.
`boolean` `locked()` Returns true if we are locked.
`boolean` `open​(boolean read_only)` Opens the data store.
`int` `rawRecordCount()` Returns the total number of records that are in the store (including deleted records.
`int` `read​(int record, byte[] buf, int offset, int length)` Reads a variable length byte[] array from the given index position.
`byte[]` `readRecord​(int record)` Reads in a complete record and puts it into the returned byte[] array.
`int` `readRecordType​(int record_index)` Reads the 32-bit type_key int for the given record.
`void` `readReservedBuffer​(byte[] info, int offset, int length)` Reads reserved information from the variable data store.
`java.lang.String` `readString​(int record)`
`boolean` `recordDeleted​(int record_index)` Returns true if the given record is marked as deleted or not.
`int` `recordSectorCount​(int record)` Returns the number of sectors the given record takes up in the data store.
`int` `recordSize​(int record)` Returns the size of the given record number (compressed size if applicable).
`static boolean` `rename​(java.io.File path_source, java.lang.String name_source, java.io.File path_dest, java.lang.String name_dest)` Convenience for renaming a VariableSizeDataStore store to another name.
`int` `sectorSize()` Returns the size (in bytes) of the sectors used to store information in the data file.
`void` `synch()` Synchronizes all the data in memory with the hard copy on disk.
`long` `totalStoreSize()` Returns the size of the data file that keeps all the data in this store.
`void` `unlock()` Unlocks the store so that deleted elements can be reclaimed again.
`int` `usedRecordCount()` Returns the number of records that are being used.
`int` `write​(byte[] buf, int offset, int length)` Writes a variable length byte[] array to the first available index.
`int` `writeRecordType​(int record_index, int type_key)` Updates the 32-bit type_key int of a record.
`void` `writeReservedBuffer​(byte[] info, int offset, int length)`
`void` `writeReservedBuffer​(byte[] info, int offset, int length, int res_offset)` Writes reserved information to the variable data store.
`int` `writeString​(java.lang.String str)`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

### Constructor Detail

#### VariableSizeDataStore

    public VariableSizeDataStore​(java.io.File name,
                                 int sector_size,
                                 DebugLogger logger)

Constructs the variable size store.

#### VariableSizeDataStore

    public VariableSizeDataStore​(java.io.File name,
                                 DebugLogger logger)

### Method Detail

#### synch

    public void synch()
               throws java.io.IOException

Synchronizes all the data in memory with the hard copy on disk.

Throws:
  `java.io.IOException`

#### hardSynch

    public void hardSynch()
                   throws java.io.IOException

Hard synchronizes the data from memory into the hard copy on disk. This is guarenteed to ensure the image on the disk will match the image in memory.

Throws:
  `java.io.IOException`

#### locked

    public boolean locked()

Returns true if we are locked.

#### lock

    public void lock()

Locks the store so that not deleted elements may be overwritten.

#### unlock

    public void unlock()

Unlocks the store so that deleted elements can be reclaimed again.

#### recordDeleted

    public boolean recordDeleted​(int record_index)
                          throws java.io.IOException

Returns true if the given record is marked as deleted or not.

Throws:
  `java.io.IOException`

#### usedRecordCount

    public int usedRecordCount()

Returns the number of records that are being used.

#### rawRecordCount

    public int rawRecordCount()
                       throws java.io.IOException

Returns the total number of records that are in the store (including deleted records.

Throws:
  `java.io.IOException`

#### exists

    public boolean exists()
                   throws java.io.IOException

Returns true if the data store exists.

Throws:
  `java.io.IOException`

#### isReadOnly

    public boolean isReadOnly()

Returns true if the store was openned in read only mode.

#### open

    public boolean open​(boolean read_only)
                 throws java.io.IOException

Opens the data store. The data store can be opened in 'read only' mode. Returns 'true' if the open procedure should repair itself (dirty open) or false if the file was cleanly closed down.

It is not possible to open a damaged store in read only mode.

Parameters:
  `read_only` - if true, then the database is opened in read only mode, otherwise it is opened in read/write mode.
Throws:
  `java.io.IOException`

#### close

    public void close()
               throws java.io.IOException

Closes the data store.

Throws:
  `java.io.IOException`

#### delete

    public void delete()

Deletes the store from the file system. Must be called after a 'close'.

#### fix

    public void fix​(UserTerminal terminal)
             throws java.io.IOException

Attempts to fix a corrupt VariableSizeDataStore object.

The store should be open before this method is called.

Throws:
  `java.io.IOException`

#### copyTo

    public void copyTo​(java.io.File path)
                throws java.io.IOException

Copies this data store to the given path. The store must be open when this is called.

Throws:
  `java.io.IOException`

#### writeRecordType

    public int writeRecordType​(int record_index,
                               int type_key)
                        throws java.io.IOException

Updates the 32-bit type_key int of a record. Bit 1-8 are reserved for this data store, and are used to indicate such things as whether the record chain is compressed or not. The rest of the bits can be used for any purpose. It is recommended bits 8 through 16 are used for user-definable information.

Throws:
  `java.io.IOException`

#### readRecordType

    public int readRecordType​(int record_index)
                       throws java.io.IOException

Reads the 32-bit type_key int for the given record. The 'type_key' contains various bit flags set for the record.

Throws:
  `java.io.IOException`

#### write

    public int write​(byte[] buf,
                     int offset,
                     int length)
              throws java.io.IOException

Writes a variable length byte[] array to the first available index. Returns the index reference for this element.

Throws:
  `java.io.IOException`

#### read

    public int read​(int record,
                    byte[] buf,
                    int offset,
                    int length)
             throws java.io.IOException

Reads a variable length byte[] array from the given index position. This will read the first n bytes from the element, upto the maximum that was stored. It returns the number of bytes that were read.

Throws:
  `java.io.IOException`

#### readRecord

    public byte[] readRecord​(int record)
                      throws java.io.IOException

Reads in a complete record and puts it into the returned byte[] array.

Throws:
  `java.io.IOException`

#### delete

    public int delete​(int record)
               throws java.io.IOException

Deletes the data at the given index position.

Throws:
  `java.io.IOException`

#### getRecordOutputStream

    public java.io.OutputStream getRecordOutputStream()
                                               throws java.io.IOException

Returns an OutputStream object that can be used to write data into the store. When the 'completeWriteStream' method is called, the records in this store are updated appropriately for the data written in, and a record index is returned.

NOTE: Only one open stream may be active at a time. While this stream is open this VariableSizeDataStore object may not be used in any other way.

Throws:
  `java.io.IOException`

#### completeRecordStreamWrite

    public int completeRecordStreamWrite()
                                  throws java.io.IOException

Updates the record allocation table with the data in the output stream returned by 'getRecordOutputStream'. Returns an index for how to reference this data later.

After this method is called it is safe again to use this VariableSizeDataStore object.

Throws:
  `java.io.IOException`

#### getRecordInputStream

    public java.io.InputStream getRecordInputStream​(int record)
                                             throws java.io.IOException

Returns an InputStream that is used to read a record in this store with the given index.

NOTE: This can not handle compressed records.

NOTE: This does not detect the end of stream (reading past the end of the record will return undefined data).

Throws:
  `java.io.IOException`

#### sectorSize

    public int sectorSize()
                   throws java.io.IOException

Returns the size (in bytes) of the sectors used to store information in the data file.

Throws:
  `java.io.IOException`

#### recordSize

    public int recordSize​(int record)
                   throws java.io.IOException

Returns the size of the given record number (compressed size if applicable).

Throws:
  `java.io.IOException`

#### isCompressed

    public boolean isCompressed​(int record)
                         throws java.io.IOException

Returns true if the given record is compressed.

Throws:
  `java.io.IOException`

#### recordSectorCount

    public int recordSectorCount​(int record)
                          throws java.io.IOException

Returns the number of sectors the given record takes up in the data store.

Throws:
  `java.io.IOException`

#### totalStoreSize

    public long totalStoreSize()

Returns the size of the data file that keeps all the data in this store. This is the file size of the data store.

#### writeReservedBuffer

    public void writeReservedBuffer​(byte[] info,
                                    int offset,
                                    int length,
                                    int res_offset)
                             throws java.io.IOException

Writes reserved information to the variable data store. You may only write upto 128 bytes to the reserved data buffer.

Throws:
  `java.io.IOException`

#### writeReservedBuffer

    public void writeReservedBuffer​(byte[] info,
                                    int offset,
                                    int length)
                             throws java.io.IOException

Throws:
  `java.io.IOException`

#### readReservedBuffer

    public void readReservedBuffer​(byte[] info,
                                   int offset,
                                   int length)
                            throws java.io.IOException

Reads reserved information from the variable data store. You may only read upto 128 bytes from the reserved data buffer.

Throws:
  `java.io.IOException`

#### exists

    public static boolean exists​(java.io.File path,
                                 java.lang.String name)
                          throws java.io.IOException

Convenience for checking if a given data store exists or not. Returns true if it exists.

Throws:
  `java.io.IOException`

#### delete

    public static boolean delete​(java.io.File path,
                                 java.lang.String name)
                          throws java.io.IOException

Convenience for deleting a VariableSizeDataStore store.

Throws:
  `java.io.IOException`

#### rename

    public static boolean rename​(java.io.File path_source,
                                 java.lang.String name_source,
                                 java.io.File path_dest,
                                 java.lang.String name_dest)
                          throws java.io.IOException

Convenience for renaming a VariableSizeDataStore store to another name.

Throws:
  `java.io.IOException`

#### writeString

    public int writeString​(java.lang.String str)
                    throws java.io.IOException

Throws:
  `java.io.IOException`

#### readString

    public java.lang.String readString​(int record)
                                throws java.io.IOException

Throws:
  `java.io.IOException`