java.lang.Object
net.metanotion.io.block.BlockFile
- All Implemented Interfaces:
Closeable, AutoCloseable
Block-based file storage system with indexed access.
Provides paged file storage with skiplist indexes for efficient key-value data retrieval. Supports multiple named indexes within a single file.
On-disk format:
Magic number (6 bytes) Version major/minor (2 bytes) file length (long) free list start (unsigned int) is mounted (unsigned short) 0 = no, 1 = yes span size (unsigned short) block size (unsigned int)
Metaindex skiplist is on page 2. Pages are 1 KB and are numbered starting from 1.
Field Summary
Modifier and TypeFieldDescriptionprivate booleanTrue once the file is closed.private final booleanI2P was the file locked when we opened it?final RandomAccessInterfaceThe underlying file interface for this block fileprivate longnew BlockFile length, containing a superblock page and a metaindex page.private FreeListBlockcached list of free pages, only valid if freListStart > 0private intFirst block of the free block list.final LogLogger instance for this BlockFileprivate static final longThe magic number of the current format, version included.private static final longThe magic number with the version bits cleared.static final intMagic number for continuation pages ("CONT")private longThe magic number read from or written to the file.private static final intMajor version of the file format written.Index of the metadata records.static final intPage number for the metaindexprivate static final intOldest major version that can be read.private static final intOldest minor version that can be read.private static final intMinor version of the file format written.private intTrue once the file header was read.static final longFile offset where the mounted flag is storedThe indices kept open, by name.static final intPage size in bytes for block file pagesintDefault span size for new skiplistsConstructor Summary
ConstructorsConstructorDescriptionCreate a BlockFile from a File with optional initialization.Create a BlockFile from a RandomAccessFile.BlockFile(RandomAccessFile raf, boolean init) Create a BlockFile from a RandomAccessFile with optional initialization.Use this constructor with a readonly RAI for a readonly blockfile.BlockFile(RandomAccessInterface rai, boolean init) Create a BlockFile from a RandomAccessInterface with optional initialization.Method Summary
Modifier and TypeMethodDescriptionintAllocate a new page from the free list or extend the file.booleanbfck(boolean fix) Run an integrity check on the blockfile and all the skiplists in it.voidclose()Closes all open skiplists and then the blockfile itself.voidcloseIndex(String name) Close a skiplist if it is open.voidDelete a skiplist if it exists.voidfreePage(int page) Add the page to the free list.<K extends Comparable<? super K>, V>
BSkipList<K, V> getIndex(String name, Serializer<K> key, Serializer<V> val) Open a skiplist if it exists.static voidRun an integrity check on the blockfile and all the skiplists in it.<K extends Comparable<? super K>, V>
BSkipList<K, V> makeIndex(String name, Serializer<K> key, Serializer<V> val) Create and open a new skiplist if it does not exist.private voidmount()Reads the file header or writes a new one.static voidpageSeek(RandomAccessInterface file, int page) Go to any page but the superblock.intreadMultiPageData(byte[] arr, int page, int[] curPageOff, int[] nextPage) Read bytes from multiple pages.private voidReads and validates the file header block.<K extends Comparable<? super K>, V>
voidreformatIndex(String name, Serializer<K> oldKey, Serializer<V> oldVal, Serializer<K> newKey, Serializer<V> newVal) Reformat a skiplist with new Serializers if it exists.intskipMultiPageBytes(int length, int page, int[] curPageOff, int[] nextPage) Skip length bytes across multiple pages.booleanCheck if the file was locked when opened.intwriteMultiPageData(byte[] data, int page, int[] curPageOff, int[] nextPage) Write bytes to multiple pages.private voidWrites the file header block.
Field Details
PAGESIZE
public static final int PAGESIZEPage size in bytes for block file pages- See Also:
OFFSET_MOUNTED
public static final long OFFSET_MOUNTEDFile offset where the mounted flag is stored- See Also:
log
Logger instance for this BlockFilefile
The underlying file interface for this block fileMAJOR
private static final int MAJORMajor version of the file format written.- See Also:
MINOR
private static final int MINORMinor version of the file format written.- See Also:
MIN_MAJOR
private static final int MIN_MAJOROldest major version that can be read.- See Also:
MIN_MINOR
private static final int MIN_MINOROldest minor version that can be read.- See Also:
MAGIC_BASE
private static final long MAGIC_BASEThe magic number with the version bits cleared. I2P changed the magic number and the format, the magic numbers are now on all pages.- See Also:
MAGIC
private static final long MAGICThe magic number of the current format, version included.- See Also:
magicBytes
private long magicBytesThe magic number read from or written to the file.MAGIC_CONT
public static final int MAGIC_CONTMagic number for continuation pages ("CONT")- See Also:
METAINDEX_PAGE
fileLen
private long fileLennew BlockFile length, containing a superblock page and a metaindex page.freeListStart
private int freeListStartFirst block of the free block list.mounted
private int mountedTrue once the file header was read.spanSize
public int spanSizeDefault span size for new skiplists_wasMounted
private final boolean _wasMountedI2P was the file locked when we opened it?metaIndex
_isClosed
private boolean _isClosedTrue once the file is closed.flb
cached list of free pages, only valid if freListStart > 0openIndices
Constructor Details
BlockFile
Use this constructor with a readonly RAI for a readonly blockfile.- Parameters:
rai- the RandomAccessInterface to use- Throws:
IOException- if an I/O error occurs
BlockFile
Create a BlockFile from a RandomAccessFile. RAF must be writable.- Parameters:
raf- the RandomAccessFile to use- Throws:
IOException- if an I/O error occurs
BlockFile
Create a BlockFile from a RandomAccessFile with optional initialization. RAF must be writable.- Parameters:
raf- the RandomAccessFile to useinit- if true, initialize the file with a new block structure- Throws:
IOException- if an I/O error occurs
BlockFile
Create a BlockFile from a File with optional initialization. File must be writable.- Parameters:
f- the File to useinit- if true, initialize the file with a new block structure- Throws:
IOException- if an I/O error occurs
BlockFile
Create a BlockFile from a RandomAccessInterface with optional initialization. Use this constructor with a readonly RAI and init = false for a readonly blockfile.- Parameters:
rai- the RandomAccessInterface to useinit- if true, initialize the file with a new block structure- Throws:
IOException- if an I/O error occurs
Method Details
mount
Reads the file header or writes a new one.- Throws:
IOException- if the header cannot be read
writeSuperBlock
Writes the file header block.- Throws:
IOException- if the header cannot be written
readSuperBlock
Reads and validates the file header block.- Throws:
IOException- if the header is missing, short, or from a newer version
main
Run an integrity check on the blockfile and all the skiplists in it. WARNING: This only works on skiplists usingUTF8StringBytesas a key serializer, unless the exception has been coded in bfck below. Will CORRUPT other skiplists.- Parameters:
args- command line arguments (file path)
writeMultiPageData
public int writeMultiPageData(byte[] data, int page, int[] curPageOff, int[] nextPage) throws IOException Write bytes to multiple pages. This will allocate additional continuation pages as necessary.- Parameters:
data- data to writepage- index of the page to start writing atcurPageOff- in (current) and out (new) parameter at index 0nextPage- in (current) and out (new) parameter at index 0- Returns:
- index of the page the write finished on
- Throws:
IOException- if an I/O error occurs
readMultiPageData
public int readMultiPageData(byte[] arr, int page, int[] curPageOff, int[] nextPage) throws IOException Read bytes from multiple pages.- Parameters:
arr- fill this array fully with datapage- index of the page to start reading atcurPageOff- in (current) and out (new) parameter at index 0nextPage- in (current) and out (new) parameter at index 0- Returns:
- index of the page the read finished on
- Throws:
IOException- if an I/O error occurs or not enough pages to read
skipMultiPageBytes
public int skipMultiPageBytes(int length, int page, int[] curPageOff, int[] nextPage) throws IOException Skip length bytes across multiple pages. The same asreadMultiPageData(byte[], int, int[], int[])without returning a result- Parameters:
length- number of bytes to skippage- index of the page the skip starts atcurPageOff- in (current) and out (new) parameter at index 0nextPage- in (current) and out (new) parameter at index 0- Returns:
- index of the page the skip finished on
- Throws:
IOException- if an I/O error occurs or not enough pages to skip
wasMounted
public boolean wasMounted()Check if the file was locked when opened.- Returns:
- true if the file was mounted
pageSeek
Go to any page but the superblock. Page 1 is the superblock, must use file.seek(0) to get there.- Parameters:
file- the RandomAccessInterface to seek inpage- the page number (>= 2)- Throws:
IOException- if page is invalid
allocPage
Allocate a new page from the free list or extend the file.- Returns:
- the page number of the newly allocated page
- Throws:
IOException- if an I/O error occurs
freePage
public void freePage(int page) Add the page to the free list. The file is never shrunk. Does not throw exceptions; logs on failure.- Parameters:
page- the page number to free
getIndex
public <K extends Comparable<? super K>, V>BSkipList<K,V> getIndex(String name, Serializer<K> key, Serializer<V> val) throws IOException Open a skiplist if it exists. Returns null if the skiplist does not exist. Empty skiplists are not preserved after close. If the file is writable, this runs an integrity check and repair on first open.- Type Parameters:
K- the type of keys in the skiplistV- the type of values in the skiplist- Parameters:
name- the skiplist's name within this blockfilekey- the Serializer for keysval- the Serializer for values- Returns:
- the BSkipList, or null if not found
- Throws:
IOException- if an I/O error occurs
makeIndex
public <K extends Comparable<? super K>, V>BSkipList<K,V> makeIndex(String name, Serializer<K> key, Serializer<V> val) throws IOException Create and open a new skiplist if it does not exist. Throws IOException if it already exists.- Type Parameters:
K- the type of keys in the skiplistV- the type of values in the skiplist- Parameters:
name- the skiplist's name within this blockfilekey- the Serializer for keysval- the Serializer for values- Returns:
- the newly created BSkipList
- Throws:
IOException- if already exists or other errors
delIndex
Delete a skiplist if it exists. Must be open. Throws IOException if exists but is closed. Broken before 0.9.26.- Parameters:
name- the skiplist's name within this blockfile- Throws:
IOException- if it is closed.
closeIndex
Close a skiplist if it is open.- Parameters:
name- the skiplist's name within this blockfile
reformatIndex
public <K extends Comparable<? super K>, V> void reformatIndex(String name, Serializer<K> oldKey, Serializer<V> oldVal, Serializer<K> newKey, Serializer<V> newVal) throws IOException Reformat a skiplist with new Serializers if it exists. The skiplist must be closed. Throws IOException if the skiplist is open. The skiplist will remain closed after completion.- Type Parameters:
K- the type of keys in the skiplistV- the type of values in the skiplist- Parameters:
name- the skiplist's name within this blockfileoldKey- the current Serializer for keysoldVal- the current Serializer for valuesnewKey- the new Serializer for keysnewVal- the new Serializer for values- Throws:
IOException- if it is open or on errors
close
Closes all open skiplists and then the blockfile itself. Note (I2P) Does NOT close the RAF / RAI.- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Throws:
IOException
bfck
public boolean bfck(boolean fix) Run an integrity check on the blockfile and all the skiplists in it.- Parameters:
fix- if true, attempt to fix any corruption found- Returns:
- true if the levels were modified.