@Test public void getSliceRespectsAllBoundsInclusionArguments() throws Exception { // Test case where endColumn=startColumn+1 ByteBuffer key = KeyColumnValueStoreUtil.longToByteBuffer(0); ByteBuffer columnBeforeStart = KeyColumnValueStoreUtil.longToByteBuffer(776); ByteBuffer columnStart = KeyColumnValueStoreUtil.longToByteBuffer(777); ByteBuffer columnEnd = KeyColumnValueStoreUtil.longToByteBuffer(778); ByteBuffer columnAfterEnd = KeyColumnValueStoreUtil.longToByteBuffer(779); // First insert four test Entries TransactionHandle txn = manager.beginTransaction(); List<Entry> entries = Arrays.asList( new Entry(columnBeforeStart, columnBeforeStart), new Entry(columnStart, columnStart), new Entry(columnEnd, columnEnd), new Entry(columnAfterEnd, columnAfterEnd)); store.mutate(key, entries, null, txn); txn.commit(); // getSlice() with only start inclusive txn = manager.beginTransaction(); List<Entry> result = store.getSlice(key, columnStart, columnEnd, txn); assertEquals(1, result.size()); assertEquals(777, result.get(0).getColumn().getLong()); txn.commit(); }
// Inherit interface docs. @Override public void closeTable(TableInfo tableInfo) throws IOException { // Remove this table from the cache since it's about to be closed. openTables.remove(tableInfo.getTableName()); DBFile dbFile = tableInfo.getTupleFile().getDBFile(); // Flush all open pages for the table. storageManager.getBufferManager().flushDBFile(dbFile); storageManager.getFileManager().closeDBFile(dbFile); }
@Test public void containsKeyColumnReturnsTrueOnExtantInput() throws Exception { TransactionHandle txn = manager.beginTransaction(); KeyColumnValueStoreUtil.insert(store, txn, 1, "c", "v"); txn.commit(); txn = manager.beginTransaction(); ByteBuffer key1 = KeyColumnValueStoreUtil.longToByteBuffer(1); ByteBuffer c = KeyColumnValueStoreUtil.stringToByteBuffer("c"); assertTrue(store.containsKeyColumn(key1.duplicate(), c.duplicate(), txn)); txn.commit(); }
@Test public void containsKeyReturnsFalseOnNonexistentKey() throws Exception { TransactionHandle txn = manager.beginTransaction(); ByteBuffer key1 = KeyColumnValueStoreUtil.longToByteBuffer(1); assertFalse(store.containsKey(key1.duplicate(), txn)); txn.commit(); }
// Inherit interface docs. @Override public boolean tableExists(String tableName) throws IOException { String tblFileName = getTableFileName(tableName); FileManager fileManager = storageManager.getFileManager(); return fileManager.fileExists(tblFileName); }
@Test public void getNonExistentKeyReturnsNull() throws Exception { TransactionHandle txn = manager.beginTransaction(); assertEquals(null, KeyColumnValueStoreUtil.get(store, txn, 0, "col0")); assertEquals(null, KeyColumnValueStoreUtil.get(store, txn, 0, "col1")); txn.commit(); }
@Override public InternalTitanTransaction startTransaction(TransactionConfig configuration) { try { return new StandardPersistTitanTx(this, etManager, configuration, storage.beginTransaction()); } catch (StorageException e) { throw new TitanException("Could not start new transaction", e); } }
@Test public void insertingGettingAndDeletingSimpleDataWorks() throws Exception { TransactionHandle txn = manager.beginTransaction(); KeyColumnValueStoreUtil.insert(store, txn, 0, "col0", "val0"); KeyColumnValueStoreUtil.insert(store, txn, 0, "col1", "val1"); txn.commit(); txn = manager.beginTransaction(); assertEquals("val0", KeyColumnValueStoreUtil.get(store, txn, 0, "col0")); assertEquals("val1", KeyColumnValueStoreUtil.get(store, txn, 0, "col1")); KeyColumnValueStoreUtil.delete(store, txn, 0, "col0"); KeyColumnValueStoreUtil.delete(store, txn, 0, "col1"); txn.commit(); txn = manager.beginTransaction(); assertEquals(null, KeyColumnValueStoreUtil.get(store, txn, 0, "col0")); assertEquals(null, KeyColumnValueStoreUtil.get(store, txn, 0, "col1")); txn.commit(); }
@Test public void getSliceRespectsColumnLimit() throws Exception { TransactionHandle txn = manager.beginTransaction(); ByteBuffer key = KeyColumnValueStoreUtil.longToByteBuffer(0); final int cols = 1024; List<Entry> entries = new LinkedList<Entry>(); for (int i = 0; i < cols; i++) { ByteBuffer col = KeyColumnValueStoreUtil.longToByteBuffer(i); entries.add(new Entry(col, col)); } store.mutate(key, entries, null, txn); txn.commit(); txn = manager.beginTransaction(); ByteBuffer columnStart = KeyColumnValueStoreUtil.longToByteBuffer(0); ByteBuffer columnEnd = KeyColumnValueStoreUtil.longToByteBuffer(cols); /* * When limit is greater than or equal to the matching column count, * all matching columns must be returned. */ List<Entry> result = store.getSlice(key, columnStart, columnEnd, cols, txn); assertEquals(cols, result.size()); assertEquals(entries, result); result = store.getSlice(key, columnStart, columnEnd, cols + 10, txn); assertEquals(cols, result.size()); assertEquals(entries, result); /* * When limit is less the matching column count, the columns up to the * limit (ordered bytewise) must be returned. */ result = store.getSlice(key, columnStart, columnEnd, cols - 1, txn); assertEquals(cols - 1, result.size()); entries.remove(entries.size() - 1); assertEquals(entries, result); result = store.getSlice(key, columnStart, columnEnd, 1, txn); assertEquals(1, result.size()); List<Entry> firstEntrySingleton = Arrays.asList(entries.get(0)); assertEquals(firstEntrySingleton, result); txn.commit(); }
// Inherit interface docs. @Override public void dropTable(String tableName) throws IOException { TableInfo tableInfo = openTable(tableName); if (StorageManager.ENABLE_INDEXES) dropTableIndexes(tableInfo); // Close the table. This will purge out all dirty pages for the table // as well. closeTable(tableInfo); String tblFileName = getTableFileName(tableName); storageManager.getFileManager().deleteDBFile(tblFileName); }
@Override public synchronized void shutdown() throws TitanException { if (!isOpen) return; super.shutdown(); etManager.close(); idAssigner.close(); try { edgeStore.close(); propertyIndex.close(); storage.close(); } catch (StorageException e) { throw new TitanException("Could not close storage backend", e); } isOpen = false; }
// Inherit interface docs. @Override public TableInfo openTable(String tableName) throws IOException { TableInfo tableInfo; // If the table is already open, just return the cached information. tableInfo = openTables.get(tableName); if (tableInfo != null) return tableInfo; // Open the data file for the table; read out its type and page-size. String tblFileName = getTableFileName(tableName); TupleFile tupleFile = storageManager.openTupleFile(tblFileName); tableInfo = new TableInfo(tableName, tupleFile); // Cache this table since it's now considered "open". openTables.put(tableName, tableInfo); return tableInfo; }
// Inherit interface docs. @Override public TableInfo createTable(String tableName, TableSchema schema, CommandProperties properties) throws IOException { int pageSize = StorageManager.getCurrentPageSize(); String storageType = "heap"; ArrayList<Integer> hashColumns = new ArrayList<Integer>(); if (properties != null) { logger.info("Using command properties " + properties); pageSize = properties.getInt("pagesize", pageSize); storageType = properties.getString("storage", storageType); String hashString = properties.getString("hashkey", null); if (hashString != null) { List<String> hashList = Arrays.asList(hashString.split("\\s*,\\s*")); for (String s : hashList) { hashColumns.add(Integer.valueOf(s)); } } HashSet<String> names = new HashSet<String>(properties.getNames()); names.remove("pagesize"); names.remove("storage"); names.remove("hashkey"); if (!names.isEmpty()) { throw new IllegalArgumentException( "Unrecognized property " + "name(s) specified: " + names); } } String tblFileName = getTableFileName(tableName); DBFileType type; if ("heap".equals(storageType)) { type = DBFileType.HEAP_TUPLE_FILE; } else if ("btree".equals(storageType)) { type = DBFileType.BTREE_TUPLE_FILE; } else if ("lin-hash".equals(storageType)) { type = DBFileType.LINEAR_HASH_FILE; if (hashColumns.isEmpty()) { throw new IllegalArgumentException("Hash storage must specify a key!"); } } else { throw new IllegalArgumentException("Unrecognized table file " + "type: " + storageType); } TupleFileManager tupleFileManager = storageManager.getTupleFileManager(type); // First, create a new DBFile that the tuple file will go into. FileManager fileManager = storageManager.getFileManager(); DBFile dbFile = fileManager.createDBFile(tblFileName, type, pageSize); logger.debug("Created new DBFile for table " + tableName + " at path " + dbFile.getDataFile()); // Now, initialize it to be a tuple file with the specified type and // schema. TupleFile tupleFile; if (type == DBFileType.LINEAR_HASH_FILE) { DBFile overflow = fileManager.createDBFile("ovflw_" + tblFileName, DBFileType.OVERFLOW_FILE, pageSize); HashTupleFileManager hashManager = (HashTupleFileManager) tupleFileManager; tupleFile = hashManager.createTupleFile(dbFile, schema, hashColumns, overflow); } else { tupleFile = tupleFileManager.createTupleFile(dbFile, schema); } // Cache this table since it's now considered "open". TableInfo tableInfo = new TableInfo(tableName, tupleFile); openTables.put(tableName, tableInfo); return tableInfo; }
public void open() { manager = openStorageManager(); tx = manager.beginTransaction(); store = manager.openDatabase(storeName); }
private void dropTableIndexes(TableInfo tableInfo) throws IOException { String tableName = tableInfo.getTableName(); // We need to open the table so that we can drop all related objects, // such as indexes on the table, etc. TableSchema schema = tableInfo.getTupleFile().getSchema(); // Check whether this table is referenced by any other tables via // foreign keys. Need to check the primary key and candidate keys. KeyColumnRefs pk = schema.getPrimaryKey(); if (pk != null && !pk.getReferencingIndexes().isEmpty()) { throw new IOException( "Drop table failed due to the table" + " having foreign key dependencies: " + tableName); } List<KeyColumnRefs> candKeyList = schema.getCandidateKeys(); for (KeyColumnRefs candKey : candKeyList) { if (!candKey.getReferencingIndexes().isEmpty()) { throw new IOException( "Drop table failed due to the table" + " having foreign key dependencies: " + tableName); } } // If we got here, the table being dropped is not a referenced table. // Start cleaning up various schema objects for the table. List<KeyColumnRefs> parentCandKeyList; TableInfo parentTableInfo; // Now drop the foreign key constraint fields that this table // may have on other parent tables. Scan through this table's // Foreign key indexes to see which tables need maintenance List<ForeignKeyColumnRefs> forKeyList = schema.getForeignKeys(); for (ForeignKeyColumnRefs forKey : forKeyList) { // Open the parent table, and iterate through all of its primary // and candidate keys, dropping any foreign key constraints that // refer to the child table with tableName String parentTableName = forKey.getRefTable(); try { parentTableInfo = openTable(parentTableName); } catch (Exception e) { throw new IOException( "The referenced table, " + parentTableName + ", which is referenced by " + tableName + ", does not exist."); } TableSchema parentSchema = parentTableInfo.getTupleFile().getSchema(); KeyColumnRefs parentPK = parentSchema.getPrimaryKey(); if (parentPK != null) { parentPK.dropRefToTable(tableName); } parentCandKeyList = parentSchema.getCandidateKeys(); for (KeyColumnRefs parentCandKey : parentCandKeyList) { parentCandKey.dropRefToTable(tableName); } // Persist the changes we made to the schema saveTableInfo(parentTableInfo); } // Then drop the indexes since we've checked the constraints IndexManager indexManager = storageManager.getIndexManager(); for (String indexName : schema.getIndexes().keySet()) indexManager.dropIndex(tableInfo, indexName); }
public void close() { if (tx != null) tx.commit(); store.close(); manager.close(); }
@Override public Features getFeatures() { return TitanFeatures.getFeatures(getConfiguration(), storage.getFeatures()); }