📄 triplestore.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;import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.InputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.ArrayList;import java.util.HashSet;import java.util.Iterator;import java.util.Properties;import java.util.Set;import java.util.StringTokenizer;import org.openrdf.util.ByteArrayUtil;import org.openrdf.util.log.ThreadLog;import org.openrdf.sesame.sail.SailInitializationException;import org.openrdf.sesame.sailimpl.nativerdf.btree.BTree;import org.openrdf.sesame.sailimpl.nativerdf.btree.BTreeIterator;import org.openrdf.sesame.sailimpl.nativerdf.btree.BTreeValueComparator;/** **/public class TripleStore {/*-------------+| Constants |+-------------*/ private static final String PROPERTIES_FILE = "triples.prop"; private static final String VERSION_KEY = "version"; private static final String INDEXES_KEY = "triple-indexes"; private static final int SCHEME_VERSION = 1; private static final String OLD_IDX_FILE = "triples.dat"; /* 13 bytes are used to represent a triple: * byte 0-3 : subject * byte 4-7 : predicate * byte 8-11: object * byte 12 : additional flag(s) */ static final int RECORD_LENGTH = 13; static final int SUBJ_IDX = 0; static final int PRED_IDX = 4; static final int OBJ_IDX = 8; static final int FLAG_IDX = 12; static final byte EXPLICIT_FLAG = (byte)0x1; // 0000 0001/*-------------+| Variables |+-------------*/ /** * The directory that is used to store the index files. */ private File _dir; /** * Object containing meta-data for the triple store. This includes */ private Properties _properties; /** * The array of triple indexes that are used to store and retrieve triples. **/ private TripleIndex[] _indexes;/*-------------+| Constructors |+-------------*/ public TripleStore(File dir, String indexSpecStr) throws IOException, SailInitializationException { _dir = dir; _properties = new Properties(); // Read triple properties file, upgrade if not present, restore indexes, reindex File propFile = new File(dir, PROPERTIES_FILE); if (propFile.exists()) { _loadProperties(propFile); } else { // Check for presence of old index file and rename it if necessary File oldIndexFile = new File(dir, OLD_IDX_FILE); if (oldIndexFile.exists()) { // Old index file contains an spo index File spoFile = _getIndexFile("spo"); if (!spoFile.exists()) { ThreadLog.log("Updating old triple indexing scheme..."); oldIndexFile.renameTo(spoFile); } _properties.setProperty(VERSION_KEY, String.valueOf(SCHEME_VERSION)); _properties.setProperty(INDEXES_KEY, "spo"); } } Set indexSpecs = _parseIndexSpecList(indexSpecStr); if (indexSpecs.isEmpty()) { // Create default spo index ThreadLog.log("No indexes specified, defaulting to single spo index"); indexSpecs.add("spo"); indexSpecStr = "spo"; } // Initialize added indexes and delete removed ones: _reindex(indexSpecs); // Store up-to-date properties _properties.setProperty(VERSION_KEY, String.valueOf(SCHEME_VERSION)); _properties.setProperty(INDEXES_KEY, indexSpecStr); _storeProperties(propFile); // Create specified indexes _indexes = new TripleIndex[indexSpecs.size()]; int i = 0; Iterator iter = indexSpecs.iterator(); while (iter.hasNext()) { String fieldSeq = (String)iter.next(); ThreadLog.trace("Activating index '" + fieldSeq + "'..."); _indexes[i++] = new TripleIndex(fieldSeq); } }/*----------+| Methods |+----------*/ /** * Parses a comma/whitespace-separated list of index specifications. Index * specifications are required to consists of 3 characters: 's', 'p' and 'o'. * * @param indexSpecStr A string like "spo, pos, osp". * @return A Set containing the parsed index specifications. */ private Set _parseIndexSpecList(String indexSpecStr) throws SailInitializationException { Set indexes = new HashSet(); if (indexSpecStr != null) { StringTokenizer tok = new StringTokenizer(indexSpecStr, ", \t"); while (tok.hasMoreTokens()) { String index = tok.nextToken().toLowerCase(); // sanity checks if (index.length() != 3 || index.indexOf('s') == -1 || index.indexOf('p') == -1 || index.indexOf('o') == -1) { throw new SailInitializationException( "invalid value '" + index + "' in index specification: " + indexSpecStr); } indexes.add(index); } } return indexes; } private void _reindex(Set newIndexSpecs) throws IOException, SailInitializationException { // Check if the index specification has changed and update indexes if necessary String currentIndexSpecStr = _properties.getProperty(INDEXES_KEY); if (currentIndexSpecStr == null) { return; } Set currentIndexSpecs = _parseIndexSpecList(currentIndexSpecStr); if (currentIndexSpecs.isEmpty()) { throw new SailInitializationException("Invalid index specification found in index properties"); } // Determine the set of newly added indexes Set addedIndexSpecs = new HashSet(newIndexSpecs); addedIndexSpecs.removeAll(currentIndexSpecs); if (!addedIndexSpecs.isEmpty()) { // Initialize new indexes using an existing index as source String sourceIndexSpec = (String)currentIndexSpecs.iterator().next(); TripleIndex sourceIndex = new TripleIndex(sourceIndexSpec); try { Iterator fieldSeqIter = addedIndexSpecs.iterator(); while (fieldSeqIter.hasNext()) { String fieldSeq = (String)fieldSeqIter.next(); ThreadLog.trace("Initializing new index '" + fieldSeq + "'..."); TripleIndex addedIndex = new TripleIndex(fieldSeq); BTree addedBTree = addedIndex.getBTree(); addedBTree.startTransaction(); BTreeIterator sourceIter = sourceIndex.getBTree().iterateAll(); try { byte[] value = null; while ( (value = sourceIter.next()) != null) { addedBTree.insert(value); } } finally { sourceIter.close(); } addedBTree.commitTransaction(); addedBTree.close(); } ThreadLog.trace("New index(es) initialized"); } finally { sourceIndex.getBTree().close(); } } // Determine the set of removed indexes Set removedIndexSpecs = new HashSet(currentIndexSpecs); removedIndexSpecs.removeAll(newIndexSpecs); // Delete files for removed indexes Iterator iter = removedIndexSpecs.iterator(); while (iter.hasNext()) { String fieldSeq = (String)iter.next(); boolean deleted = _getIndexFile(fieldSeq).delete(); if (deleted) { ThreadLog.trace("Deleted file for removed " + fieldSeq + " index"); } else { ThreadLog.warning("Unable to delete file for removed " + fieldSeq + " index"); } } } public void close() throws IOException { for (int i = 0; i < _indexes.length; i++) { _indexes[i].getBTree().close(); } _indexes = null; } public BTreeIterator getTriples(int subj, int pred, int obj) throws IOException {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -