📄 idfile.java
字号:
/* Sesame - Storage and Querying architecture for RDF and RDF Schema * Copyright (C) 2001-2005 Aduna * * Contact: * Aduna * Prinses Julianaplein 14 b * 3817 CS Amersfoort * The Netherlands * tel. +33 (0)33 465 99 87 * fax. +33 (0)33 465 99 87 * * http://aduna.biz/ * http://www.openrdf.org/ * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package org.openrdf.sesame.sailimpl.nativerdf.datastore;import java.io.File;import java.io.IOException;import java.io.RandomAccessFile;import java.nio.ByteBuffer;import java.nio.channels.FileChannel;/** * Class supplying access to an ID file. * * @author Arjohn Kampman * @version $Revision: 1.11 $ **/public class IDFile {/*-------------+| Constants |+-------------*/ private static final long HEADER_LENGTH = 8L; private static final long ITEM_SIZE = 8L;/*-------------+| Variables |+-------------*/ private File _file; private RandomAccessFile _raf; private FileChannel _fileChannel; private File _txnFile; private RandomAccessFile _txnRaf; private FileChannel _txnChannel; private ByteBuffer _txnBuffer = ByteBuffer.allocate(8); /** Flag indicating whether the current transaction is/should be an isolated one. **/ private boolean _isolatedTransaction; private boolean _dataCleared;/*-------------+| Constructors |+-------------*/ public IDFile(File file) throws IOException { _file = file; // Make sure the file exists _file.createNewFile(); // Open a read/write channel to the file _raf = new RandomAccessFile(_file, "rw"); _fileChannel = _raf.getChannel(); if (_fileChannel.size() == 0L) { // Empty file, insert 8 dummy bytes at the start of the file _fileChannel.write( ByteBuffer.wrap(new byte[] {0, 0, 0, 0, 0, 0, 0, 0}) ); } }/*----------+| Methods |+----------*/ public void startTransaction(boolean isolateTransaction) throws IOException { _isolatedTransaction = isolateTransaction; if (isolateTransaction) { // Make sure the transaction file exists and that it is empty _txnFile = new File(_file.getParentFile(), "txn_" + _file.getName()); if (!_txnFile.exists()) { _txnFile.createNewFile(); } _txnRaf = new RandomAccessFile(_txnFile, "rw"); _txnChannel = _txnRaf.getChannel(); if (_txnChannel.size() > 0L) { _txnChannel.truncate(0L); } _dataCleared = false; } } public void commitTransaction() throws IOException { if (_isolatedTransaction) { if (_dataCleared) { // Discard existing data _fileChannel.truncate(HEADER_LENGTH); } // Append the txn file to the data file _txnChannel.position(0L); TransferUtil.transferFrom(_txnChannel, _fileChannel.size(), _txnChannel.size(), _fileChannel); _txnRaf.close(); _txnRaf = null; _txnChannel = null; // Delete the txn file _txnFile.delete(); _txnFile = null; } } public void rollbackTransaction() throws IOException { if (_isolatedTransaction) { // Close and discard the txn channel _txnRaf.close(); _txnRaf = null; _txnChannel = null; // Delete the txn file _txnFile.delete(); _txnFile = null; } else { throw new IOException("Unisolated transactions cannot be rolled back"); } } /** * Gets a new and unused ID that can be assign to new data. **/ public int getNewID() throws IOException { if (_isolatedTransaction) { // Txn file will be appended to data file on commit, // combine both file size to calculate the next ID if (_dataCleared) { return (int)((_txnChannel.size() + HEADER_LENGTH) / ITEM_SIZE); } else { return (int)((_txnChannel.size() + _fileChannel.size()) / ITEM_SIZE); } } else { return (int)(_fileChannel.size() / ITEM_SIZE); } } public int getMaxID() throws IOException { return (int)(_fileChannel.size() / ITEM_SIZE) - 1; } /** * Stores the offset of a new data entry with the specified ID. **/ public void storeOffset(int id, long offset) throws IOException { // Create and fill ByteBuffer _txnBuffer.clear(); _txnBuffer.putLong(0, offset); // Insert the offset at 8*id long txnOffset = ITEM_SIZE*id; FileChannel channel = _fileChannel; if (_isolatedTransaction) { channel = _txnChannel; txnOffset -= _dataCleared ? HEADER_LENGTH : _fileChannel.size(); } channel.write(_txnBuffer, txnOffset); } /** * Gets the offset of the data entry with the specified ID. **/ public long getOffset(int id, boolean dirtyReads) throws IOException { long offset = ITEM_SIZE * id; FileChannel channel = null; if (dirtyReads && _isolatedTransaction && (_dataCleared || offset >= _fileChannel.size())) { // Check txn file channel = _txnChannel; offset -= _dataCleared ? HEADER_LENGTH : _fileChannel.size(); } else { // Check data file channel = _fileChannel; } ByteBuffer buf = ByteBuffer.allocate(8); channel.read(buf, offset); return buf.getLong(0); } public void clear() throws IOException { if (_isolatedTransaction) { _txnChannel.truncate(0L); // Existing data is deleted on commit _dataCleared = true; } else { _fileChannel.truncate(HEADER_LENGTH); } } public void close() throws IOException { if (_txnChannel != null) { rollbackTransaction(); } _raf.close(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -