⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datafile.java

📁 这是外国一个开源推理机
💻 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;import java.util.NoSuchElementException;/** * Class supplying access to a data file. A data file stores data sequentially. * Each entry starts with the entry's length (4 bytes), followed by the data * itself. File offsets are used to identify entries. * * @author Arjohn Kampman * @version $Revision: 1.11 $ **/public class DataFile {/*-------------+| Constants    |+-------------*/	private static final long HEADER_LENGTH = 4L;/*-------------+| Variables    |+-------------*/	private File _file;	private RandomAccessFile _raf;	private FileChannel _fileChannel;	private File _txnFile;	private RandomAccessFile _txnRaf;	private FileChannel _txnChannel;	/** Flag indicating whether the current transaction is/should be an isolated one. **/	private boolean _isolatedTransaction;	private boolean _dataCleared;/*-------------+| Constructors |+-------------*/	public DataFile(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 4 dummy bytes at the start of the file			_fileChannel.write( ByteBuffer.wrap(new byte[] {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());			_txnFile.createNewFile();			_txnRaf = new RandomAccessFile(_txnFile, "rw");			_txnChannel = _txnRaf.getChannel();			_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");		}	}	/**	 * Stores the specified data and returns the byte-offset at which it has	 * been stored.	 **/	public long storeData(byte[] data)		throws IOException	{		if (_isolatedTransaction) {			// Append the data to the txn file			long offset = _txnChannel.size();			_writeData(_txnChannel, offset, data);			// Txn file will be appended to data file on commit,			// add size of data file to the offset			if (_dataCleared) {				// data file will be truncated to 4 bytes on commit				return HEADER_LENGTH + offset;			}			else {				return _fileChannel.size() + offset;			}		}		else {			long offset = _fileChannel.size();			_writeData(_fileChannel, offset, data);			return offset;		}	}	/**	 * Updates (replaces) the data at the specified offset with the supplied data.	 **/	public void updateData(long offset, byte[] data)		throws IOException	{		FileChannel channel = _fileChannel;		if (_isolatedTransaction && (_dataCleared || offset >= _fileChannel.size())) {			// Write the data to the txn file			channel = _txnChannel;			offset -= _dataCleared ? HEADER_LENGTH : _fileChannel.size();		}		_writeData(channel, offset, data);	}	private void _writeData(FileChannel channel, long offset, byte[] data)		throws IOException	{		ByteBuffer buf = ByteBuffer.allocate(data.length + 4);		buf.putInt(data.length);		buf.put(data);		buf.rewind();		channel.write(buf, offset);	}	/**	 * Gets the data that is stored at the specified offset.	 *	 * @param offset An offset in the data file.	 * @param dirtyReads Flag indicating whether data that hasn't been committed	 * yet should be searched too.	 * @return The data that was found on the specified offset.	 * @exception IOException If an I/O error occurred.	 **/	public byte[] getData(long offset, boolean dirtyReads)		throws IOException	{		FileChannel channel = _fileChannel;		if (dirtyReads && _isolatedTransaction && (_dataCleared || offset >= _fileChannel.size())) {			// Check txn file			channel = _txnChannel;			offset -= _dataCleared ? HEADER_LENGTH : _fileChannel.size();		}		// FIXME: maybe get more data in one go is more efficient?		ByteBuffer buf = ByteBuffer.allocate(4);		channel.read(buf, offset);		int dataLength = buf.getInt(0);		byte[] data = new byte[dataLength];		buf = ByteBuffer.wrap(data);		channel.read(buf, offset + 4L);		return data;	}	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();	}	public DataIterator iterator() {		return new DataIterator();	}	public class DataIterator {		private long _position = HEADER_LENGTH;		public boolean hasNext()			throws IOException		{			return _position < _fileChannel.size();		}		public byte[] next()			throws IOException		{			if (!hasNext()) {				throw new NoSuchElementException();			}			byte[] data = getData(_position, false);			_position += (4 + data.length);			return data;		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -