- Description
- Field Summary
- Method Summary
- Field Details
- EMPTY_STAMPED_LOCKS
- METRICS_REGISTRY
- MAGIC_STRING
- VERSION
- DEFAULT_BLOB_COUNT
- DEFAULT_SEGMENT_SIZE
- DEFAULT_COMPRESSION_LEVEL
- MAGIC_LENGTH
- MAGIC_OFFSET
- VERSION_OFFSET
- BLOB_COUNT_OFFSET
- SEGMENT_SIZE_OFFSET
- HEADER_LENGTH
- SRC_LENGTH_OFFSET
- COMPRESSED_LENGTH_OFFSET
- BLOB_HEADER_LENGTH
- INDEX_SIZE
- UNASSIGNED_INDEX
- FIRST_SEGMENT_INDEX
- NO_ATTRIBUTES
- Method Details
- open(Path, OpenOption...)
- open(Path, Set, FileAttribute...)
- open(Path, int, int, OpenOption...)
- open(Path, int, int, Set, FileAttribute...)
- getPath()
- getBlobCount()
- getSegmentSize()
- getCompressionLevel()
- getUsedBlobCount()
- setFlushOnWrite(boolean)
- setCompressionLevel(int)
- size()
- segmentSize()
- segmentCount()
- keys()
- readBlobLength(int)
- readBlobCompressedLength(int)
- readBlob(int)
- readBlob(int, ByteBuffer)
- writeBlob(int, ByteBuffer)
- removeBlob(int)
- lock()
- force(boolean)
- close()
- toString()
Class IndexedStorageFile
- All Implemented Interfaces:
Closeable, AutoCloseable
setCompressionLevel(int) method.
File Structure
Name | bytes | type | notes --------------------------------------------------------------------------------- Magic | 20 | ASCII |MAGIC_STRINGVersion | 4 | int |VERSIONBlob Count | 4 | int |DEFAULT_BLOB_COUNTSegment Size | 4 | int |DEFAULT_SEGMENT_SIZEBlob Indexes | BlobCount * 4 | int[Blob Count] |UNASSIGNED_INDEXSegments | ... | Segment[...]
Segment
Name | bytes | notes ------------------------------------------------- Blob Data | ...
Blob
Name | bytes ----------------------------- Blob Length | 4 Compressed Length | 4 Compressed Data | ...
The IndexedStorageFile provides best effort safety and recovery if the application crashes at any point. This is achieved by ensuring
the order of operations do not cause the file to ever be in an invalid state, however, if the underlying FileChannel manages to do a partial write
for some specific values it is still possible for the file to become corrupted.
Known Issue: There is two operations that currently break the above guarantee and is labeled with @Corruption.
TODO: Future Work: It is possible to provide stronger guarantees of writes if we use some kind of signature validation for indexes.
The IndexedStorageFile is safe for use by multiple concurrent threads as long as only a single IndexedStorageFile object is used so that internal locking correctly operates.
TODO: Future Work: This could be improved by sharing the locks between IndexedStorageFile objects based on the target file's Path.
Could use reference counting along with a Cleaner.
- Since:
- 2020/02/20
- Version:
- 1.0
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intstatic final intstatic final intstatic final intstatic final intstatic final intstatic final StampedLock[]static final intstatic final intstatic final intstatic final intstatic final intstatic final StringMagic bytes used to identify the file.static final MetricsRegistry<IndexedStorageFile> static final FileAttribute<?>[]static final intstatic final intstatic final intSegment indexes start at 1 with an index of 0 meaning unassigned.static final intstatic final int -
Method Summary
Modifier and TypeMethodDescriptionvoidclose()voidforce(boolean metaData) intThe maximum number of blobs that can be stored in this IndexedStorageFileintgetPath()intThe size of segments inside of this file, the value of this changes the performance characteristics and should be benchmarked based on the blob sizes.intThe number of blobs currently stored in this IndexedStorageFileit.unimi.dsi.fastutil.ints.IntListkeys()Returns a list of all the blobs that exist in this filelock()static IndexedStorageFileopen(Path path, int blobCount, int segmentSize, OpenOption... options) Creates an IndexedStorageFile from a path with a specified blob count and segment size.static IndexedStorageFileopen(Path path, int blobCount, int segmentSize, Set<? extends OpenOption> options, FileAttribute<?>... attrs) Creates an IndexedStorageFile from a path with a specified blob count and segment size.static IndexedStorageFileopen(Path path, OpenOption... options) static IndexedStorageFileopen(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) readBlob(int blobIndex) Reads a blob at a given index into a buffer.voidreadBlob(int blobIndex, ByteBuffer dest) Reads a blob at a given index into a buffer.intreadBlobCompressedLength(int blobIndex) Reads the length of a blobintreadBlobLength(int blobIndex) Reads the length of a blobvoidremoveBlob(int blobIndex) Removes a blob at a given index.intCounts the number of segments that are currently usedintGet the total number of segments in the filevoidsetCompressionLevel(int compressionLevel) Sets the compression level passed to Zstd for compression.voidsetFlushOnWrite(boolean flushOnWrite) Sets ifwriteBlob(int, ByteBuffer)andremoveBlob(int)should flush changes to disk.longsize()toString()voidwriteBlob(int blobIndex, ByteBuffer src) Writes a blob at a given index from a buffer.
-
Field Details
-
EMPTY_STAMPED_LOCKS
-
METRICS_REGISTRY
-
MAGIC_STRING
-
VERSION
public static final int VERSION- See Also:
-
DEFAULT_BLOB_COUNT
public static final int DEFAULT_BLOB_COUNT- See Also:
-
DEFAULT_SEGMENT_SIZE
public static final int DEFAULT_SEGMENT_SIZE- See Also:
-
DEFAULT_COMPRESSION_LEVEL
public static final int DEFAULT_COMPRESSION_LEVEL- See Also:
-
MAGIC_LENGTH
public static final int MAGIC_LENGTH- See Also:
-
MAGIC_OFFSET
public static final int MAGIC_OFFSET -
VERSION_OFFSET
public static final int VERSION_OFFSET -
BLOB_COUNT_OFFSET
public static final int BLOB_COUNT_OFFSET -
SEGMENT_SIZE_OFFSET
public static final int SEGMENT_SIZE_OFFSET -
HEADER_LENGTH
public static final int HEADER_LENGTH -
SRC_LENGTH_OFFSET
public static final int SRC_LENGTH_OFFSET -
COMPRESSED_LENGTH_OFFSET
public static final int COMPRESSED_LENGTH_OFFSET -
BLOB_HEADER_LENGTH
public static final int BLOB_HEADER_LENGTH -
INDEX_SIZE
public static final int INDEX_SIZE- See Also:
-
UNASSIGNED_INDEX
public static final int UNASSIGNED_INDEXSegment indexes start at 1 with an index of 0 meaning unassigned. This is so that a newly created file will have all blob indexes already set to unassigned and when the file length is increased all newly created segments have a next segment index of 0 which denotes that the segment is unclaimed.- See Also:
-
FIRST_SEGMENT_INDEX
public static final int FIRST_SEGMENT_INDEX- See Also:
-
NO_ATTRIBUTES
-
-
Method Details
-
open
@Nonnull public static IndexedStorageFile open(@Nonnull Path path, OpenOption... options) throws IOException - Parameters:
path- the path to the fileoptions- SeeOpenOptionandFileChannel.open(Path, Set, FileAttribute[])- Returns:
- An IndexedStorageFile for the path provided.
- Throws:
IOException- If the file is unable to be created, written to or some other IO error occurs- See Also:
-
open
@Nonnull public static IndexedStorageFile open(@Nonnull Path path, @Nonnull Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException - Parameters:
path- the path to the fileoptions- SeeOpenOptionandFileChannel.open(Path, Set, FileAttribute[])attrs- SeeFileAttributeandFileChannel.open(Path, Set, FileAttribute[])- Returns:
- An IndexedStorageFile for the path provided.
- Throws:
IOException- If the file is unable to be created, written to or some other IO error occurs- See Also:
-
open
@Nonnull public static IndexedStorageFile open(@Nonnull Path path, int blobCount, int segmentSize, OpenOption... options) throws IOException Creates an IndexedStorageFile from a path with a specified blob count and segment size.- Parameters:
path- the path to the fileblobCount- the maximum number of blobs that can be stored in this IndexedStorageFilesegmentSize- the size of segments inside of this file, the value of this changes the performance characteristics and should be benchmarked based on the blob sizes.options- SeeOpenOptionandFileChannel.open(Path, Set, FileAttribute[])- Returns:
- An IndexedStorageFile for the path provided.
- Throws:
IOException- If the file is unable to be created, written to or some other IO error occurs- See Also:
-
open
@Nonnull public static IndexedStorageFile open(@Nonnull Path path, int blobCount, int segmentSize, @Nonnull Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException Creates an IndexedStorageFile from a path with a specified blob count and segment size.- Parameters:
path- the path to the fileblobCount- the maximum number of blobs that can be stored in this IndexedStorageFilesegmentSize- the size of segments inside of this file, the value of this changes the performance characteristics and should be benchmarked based on the blob sizes.options- SeeOpenOptionandFileChannel.open(Path, Set, FileAttribute[])attrs- SeeFileAttributeandFileChannel.open(Path, Set, FileAttribute[])- Returns:
- An IndexedStorageFile for the path provided.
- Throws:
IOException- If the file is unable to be created, written to or some other IO error occurs
-
getPath
-
getBlobCount
public int getBlobCount()The maximum number of blobs that can be stored in this IndexedStorageFile- Returns:
- the blob count
-
getSegmentSize
public int getSegmentSize()The size of segments inside of this file, the value of this changes the performance characteristics and should be benchmarked based on the blob sizes.- Returns:
- the segment size
-
getCompressionLevel
public int getCompressionLevel() -
getUsedBlobCount
public int getUsedBlobCount()The number of blobs currently stored in this IndexedStorageFile- Returns:
- the used blob count
-
setFlushOnWrite
public void setFlushOnWrite(boolean flushOnWrite) Sets ifwriteBlob(int, ByteBuffer)andremoveBlob(int)should flush changes to disk.- Parameters:
flushOnWrite- If data is flushed to disk on write.
-
setCompressionLevel
public void setCompressionLevel(int compressionLevel) Sets the compression level passed to Zstd for compression. The higher the value the longer compression takes but the smaller the compressed blob should be, however this has diminishing returns.Default value is
DEFAULT_COMPRESSION_LEVEL- Parameters:
compressionLevel- the compression level.
-
size
- Throws:
IOException- See Also:
-
segmentSize
public int segmentSize()Get the total number of segments in the file- Returns:
- the number of segments
-
segmentCount
public int segmentCount()Counts the number of segments that are currently used- Returns:
- the number of used segments
-
keys
Returns a list of all the blobs that exist in this file- Returns:
- the blobs that exist in this file
- Throws:
IOException
-
readBlobLength
Reads the length of a blob- Parameters:
blobIndex- the index of the blob- Returns:
- the length of the blob
- Throws:
IOException- if an IO error occurs
-
readBlobCompressedLength
Reads the length of a blob- Parameters:
blobIndex- the index of the blob- Returns:
- the length of the blob
- Throws:
IOException- if an IO error occurs
-
readBlob
Reads a blob at a given index into a buffer.- Parameters:
blobIndex- the index of the blob to read.- Throws:
IOException- if an IO error occurs
-
readBlob
Reads a blob at a given index into a buffer.- Parameters:
blobIndex- the index of the blob to read.dest- the buffer to read the blob into- Throws:
IOException- if an IO error occurs
-
writeBlob
Writes a blob at a given index from a buffer.- Parameters:
blobIndex- the index of the blob to write.src- the buffer to read the blob from- Throws:
IOException- if an IO error occurs
-
removeBlob
Removes a blob at a given index.- Parameters:
blobIndex- the index of the blob to remove.- Throws:
IOException- if an IO error occurs
-
lock
- Throws:
IOException- See Also:
-
force
- Throws:
IOException- See Also:
-
close
- Specified by:
closein interfaceAutoCloseable- Specified by:
closein interfaceCloseable- Throws:
IOException
-
toString
-