提交 0b219336 authored 作者: Thomas Mueller's avatar Thomas Mueller

Formatting, javadocs

上级 58bea228
......@@ -24,7 +24,14 @@ import org.h2.store.fs.FilePathNio;
*/
public class FileStore {
/**
* The number of read operations.
*/
protected long readCount;
/**
* The number of write operations.
*/
protected long writeCount;
/**
......@@ -33,12 +40,34 @@ public class FileStore {
*/
protected final FreeSpaceBitSet freeSpace = new FreeSpaceBitSet(2, MVStore.BLOCK_SIZE);
/**
* The file name.
*/
protected String fileName;
/**
* Whether this store is read-only.
*/
protected boolean readOnly;
/**
* The file size (cached).
*/
protected long fileSize;
/**
* The file.
*/
protected FileChannel file;
/**
* The encrypted file (if encryption is used).
*/
protected FileChannel encryptedFile;
/**
* The file lock.
*/
protected FileLock fileLock;
@Override
......@@ -46,6 +75,13 @@ public class FileStore {
return fileName;
}
/**
* Read from the file.
*
* @param pos the write position
* @param len the number of bytes to read
* @return the byte buffer
*/
public ByteBuffer readFully(long pos, int len) {
readCount++;
ByteBuffer dst = ByteBuffer.allocate(len);
......@@ -53,12 +89,27 @@ public class FileStore {
return dst;
}
/**
* Write to the file.
*
* @param pos the write position
* @param src the source buffer
*/
public void writeFully(long pos, ByteBuffer src) {
writeCount++;
fileSize = Math.max(fileSize, pos + src.remaining());
DataUtils.writeFully(file, pos, src);
}
/**
* Try to open the file.
*
* @param fileName the file name
* @param readOnly whether the file should only be opened in read-only mode,
* even if the file is writable
* @param encryptionKey the encryption key, or null if encryption is not
* used
*/
public void open(String fileName, boolean readOnly, char[] encryptionKey) {
if (fileName != null && fileName.indexOf(':') < 0) {
// NIO is used, unless a different file system is specified
......@@ -80,6 +131,7 @@ public class FileStore {
file = f.open(readOnly ? "r" : "rw");
if (encryptionKey != null) {
byte[] password = FilePathCrypt.getPasswordBytes(encryptionKey);
encryptedFile = file;
file = new FilePathCrypt.FileCrypt(fileName, password, file);
}
file = FilePathCache.wrap(file);
......@@ -105,6 +157,9 @@ public class FileStore {
}
}
/**
* Close this store.
*/
public void close() {
try {
if (fileLock != null) {
......@@ -122,6 +177,9 @@ public class FileStore {
}
}
/**
* Flush all changes.
*/
public void sync() {
try {
file.force(true);
......@@ -132,10 +190,20 @@ public class FileStore {
}
}
/**
* Get the file size.
*
* @return the file size
*/
public long size() {
return fileSize;
}
/**
* Truncate the file.
*
* @param size the new file size
*/
public void truncate(long size) {
try {
writeCount++;
......@@ -150,8 +218,10 @@ public class FileStore {
}
/**
* Get the file instance in use. The application may read from the file (for
* example for online backup), but not write to it or truncate it.
* Get the file instance in use.
* <p>
* The application may read from the file (for example for online backup),
* but not write to it or truncate it.
*
* @return the file
*/
......@@ -159,6 +229,18 @@ public class FileStore {
return file;
}
/**
* Get the encrypted file instance, if encryption is used.
* <p>
* The application may read from the file (for example for online backup),
* but not write to it or truncate it.
*
* @return the encrypted file, or null if encryption is not used
*/
public FileChannel getEncryptedFile() {
return encryptedFile;
}
/**
* Get the number of write operations since this store was opened.
* For file based stores, this is the number of file write operations.
......@@ -183,14 +265,31 @@ public class FileStore {
return readOnly;
}
/**
* Get the default retention time for this store in milliseconds.
*
* @return the retention time
*/
public int getDefaultRetentionTime() {
return 45000;
}
public void markUsed(long start, int len) {
freeSpace.markUsed(start, len);
/**
* Mark the space as in use.
*
* @param pos the position in bytes
* @param length the number of bytes
*/
public void markUsed(long pos, int length) {
freeSpace.markUsed(pos, length);
}
/**
* Allocate a number of blocks and mark them as used.
*
* @param length the number of bytes to allocate
* @return the start position in bytes
*/
public long allocate(int length) {
return freeSpace.allocate(length);
}
......@@ -213,6 +312,9 @@ public class FileStore {
return freeSpace.getFirstFree();
}
/**
* Mark the file as empty.
*/
public void clear() {
freeSpace.clear();
}
......
......@@ -62,46 +62,32 @@ MVStore:
- defragment (re-creating maps, specially those with small pages)
- chunk header: store changed chunk data as row; maybe after the root
- chunk checksum (header, last page, 2 bytes per page?)
- on insert, if the child page is already full, don't load and modify it
split directly (specially for leaves with one large entry)
- maybe let a chunk point to a list of potential next chunks
(so no fixed location header is needed), similar to a skip list
- triggers (can be implemented with a custom map);
maybe implement database indexing with triggers
- store number of write operations per page (maybe defragment
if much different than count)
- r-tree: nearest neighbor search
- support maps without values (just existence of the key)
- support maps without keys (counted b-tree features)
- use a small object value cache (StringCache), test on Android
for default serialization
- MVStoreTool.dump: dump values (using a callback)
- map split / merge (fast if no overlap)
(use case: partitioning)
- StreamStore optimization: avoid copying bytes in memory
- Feature shrink a store (create, copy, rename, delete)
and for MVStore on Windows, auto-detect renamed file
- ensure data is overwritten eventually if the system doesn't have a
real-time clock (Raspberry Pi) and if there are few writes per startup
- SSD-friendly write (always in blocks of 4 MB / 1 second?)
- close the file on out of memory or disk write error (out of disk space or so)
- implement a sharded map (in one store, multiple stores)
to support concurrent updates and writes, and very large maps
- maybe support for writing to branches
- maybe add an optional finalizer and exit hook
to store committed changes
- to save space when persisting very small transactions,
use a transaction log where only the deltas are stored
- serialization for lists, sets, sets, sorted sets, maps, sorted maps
- maybe rename 'rollback' to 'revert' to distinguish from transactions
- support other compression algorithms (deflate, LZ4,...)
- only retain the last version, unless explicitly set (setRetainVersion)
- support opening (existing) maps by id
- more consistent null handling (keys/values sometimes may be null)
- autocommit (to avoid having to call commit,
as it could be called too often or it is easily forgotten)
- remove features that are not really needed; simplify the code
possibly using a separate layer or tools
(retainVersion?)
- rename "store" to "save", as "store" is used in "storeVersion"
- MVStoreTool.dump should dump the data if possible;
possibly using a callback for serialization
......@@ -245,6 +231,7 @@ public class MVStore {
/**
* Create and open the store.
*
* @param config the configuration to use
* @throws IllegalStateException if the file is corrupt, or an exception
* occurred while opening
* @throws IllegalArgumentException if the directory does not exist
......@@ -682,12 +669,14 @@ public class MVStore {
if (shrinkIfPossible) {
shrinkFileIfPossible(0);
}
// release memory early - this is important when called
// because of out of memory
cache.clear();
for (MVMap<?, ?> m : New.arrayList(maps.values())) {
m.close();
}
meta = null;
chunks.clear();
cache.clear();
maps.clear();
try {
fileStore.close();
......@@ -1884,9 +1873,9 @@ public class MVStore {
*
* @param mb the cache size in MB.
*/
public void setCacheSize(long mb) {
public void setCacheSize(int mb) {
if (cache != null) {
cache.setMaxMemory(mb * 1024 * 1024);
cache.setMaxMemory((long) mb * 1024 * 1024);
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论