Return-Path: X-Original-To: apmail-incubator-connectors-commits-archive@minotaur.apache.org Delivered-To: apmail-incubator-connectors-commits-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2CE999D1C for ; Sun, 18 Dec 2011 08:38:05 +0000 (UTC) Received: (qmail 56845 invoked by uid 500); 18 Dec 2011 08:38:04 -0000 Delivered-To: apmail-incubator-connectors-commits-archive@incubator.apache.org Received: (qmail 56693 invoked by uid 500); 18 Dec 2011 08:38:03 -0000 Mailing-List: contact connectors-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: connectors-dev@incubator.apache.org Delivered-To: mailing list connectors-commits@incubator.apache.org Received: (qmail 56678 invoked by uid 99); 18 Dec 2011 08:38:03 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Dec 2011 08:38:03 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Sun, 18 Dec 2011 08:37:49 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 4E78E2388AB8; Sun, 18 Dec 2011 08:37:02 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1220353 [6/11] - in /incubator/lcf/branches/CONNECTORS-286/warthog-reimport: ./ src/main/java/org/apache/warthog/api/ src/main/java/org/apache/warthog/bytekeyvalue/ src/main/java/org/apache/warthog/common/ src/main/java/org/apache/warthog/... Date: Sun, 18 Dec 2011 08:36:56 -0000 To: connectors-commits@incubator.apache.org From: kwright@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20111218083702.4E78E2388AB8@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Modified: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java?rev=1220353&r1=1220352&r2=1220353&view=diff ============================================================================== --- incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java (original) +++ incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java Sun Dec 18 08:36:52 2011 @@ -1,646 +1,646 @@ -/* $Id: Index.java 1209929 2011-12-03 15:06:22Z kwright $ */ - -/** -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.warthog.keyvaluetablestore; - -import org.apache.warthog.api.*; -import org.apache.warthog.transactionalkeyvaluestore.*; -import org.apache.warthog.common.*; - -import java.util.*; - -/** This is the standard implementation of WHIndex. -* -* The index structure has a one-to-one correspondence with the rows -* in the underlying table. Since there is such a correspondence, we make -* use of the rowID for each table row as a "nodeID". This reduces the number -* of keys/values we need to track for an index. -* -* The index has the following overall structure: -* (a) An (optional) root node reference, as decribed by a root key, which points to -* either nothing or the root node for the first index column; -* (b) A set of nodes for the first index column organized in a btree; -* (c) A reference from each node representing the first index column which -* functions as the root pointer for a btree based on the second index column, etc. -* -* Each btree node has a lesser child node reference, a greater child node reference, -* and an "equals" child node reference. All of these relationships refer to comparisons -* of the current column value for the row represented by the node. There are also rules -* for what is legal in any given context within each btree. Specifically, nodes that -* exist in the "equals" chain cannot have greater or lesser children, only "equals" -* children. -* -* For each node reference, there's also a back reference, which allows you to walk back -* up the tree. This is unique since every index node can have only one reference to it. -* -* In the future, a "maximum depth" value will also be associated with every node, so as -* to allow automatic rebalancing of each btree. -* -*/ -public class Index implements WHIndex -{ - protected TableStore ts; - protected Table table; - protected LongValue indexID; - protected long indexIDValue; - protected long[] columnIDs; - protected WHComparator[] comparators; - protected boolean unique; - - /** Constructor */ - public Index(TableStore ts, LongValue indexID, Table table, long[] columnIDs, String[] comparatorClasses, boolean unique) - throws WHException - { - if (columnIDs.length != comparatorClasses.length) - throw new WHException("Number of index column names must match number of comparator classes"); - this.ts = ts; - this.table = table; - this.indexID = indexID; - this.indexIDValue = indexID.getValue(); - this.columnIDs = columnIDs; - this.unique = unique; - this.comparators = new WHComparator[comparatorClasses.length]; - try - { - for (int i = 0 ; i < comparators.length ; i++) - { - this.comparators[i] = (WHComparator)Class.forName(comparatorClasses[i]).newInstance(); - } - } - catch (Exception e) - { - throw new WHException("Error instantiating comparator class for index '"+new Long(indexIDValue).toString()+"': "+e.getMessage(),e); - } - } - - /** Get the relationship the index applies to. - */ - public WHRelationship getRelationship() - throws WHException - { - return table; - } - - /** Get the underlying relationship column names. - */ - public String[] getColumnNames() - throws WHException - { - return table.getColumnNames(); - } - - /** Get a default accessor with default ordering and no filtering. - */ - public WHAccessor buildAccessor() - throws WHException - { - // Use null criteria - return buildAccessor(null,null); - } - - - /** Create an accessor based on this index which uses the provided criteria. The - * criteria must align with the index's columns. Null values are permitted where - * no criteria are present. - *@param criteria are the criteria that apply to each individual index column; null for no criteria at all. - *@param orderReversed is a boolean for each individual index column; true if the comparator order of that column - * should be reversed for the accessor. Null indicates no reversal for any column. - */ - public WHAccessor buildAccessor(IndexCriteria[] criteria, boolean[] orderReversed) - throws WHException - { - if (criteria != null && criteria.length != columnIDs.length) - throw new WHException("Criteria count must match index column count"); - if (orderReversed != null && orderReversed.length != columnIDs.length) - throw new WHException("Order reversal count must match index column count"); - return new IndexAccessor(this,criteria,orderReversed); - } - - // Below this line are methods that are not meant to be used for general purposes, - - /** Get the columns that are indexed - */ - protected long[] getIndexColumnIDs() - { - return columnIDs; - } - - /** Get the index id */ - protected LongValue getID() - { - return indexID; - } - - protected long getIDValue() - { - return indexIDValue; - } - - protected Table getTable() - { - return table; - } - - /** Get the comparators. - */ - protected WHComparator[] getComparators() - { - return comparators; - } - - /** Add a new row to the index. - * The row must already exist in the underlying table. - */ - protected void addNewRow(LongValue rowID) - throws WHException - { - // The algorithm here simply involves finding the right spot and adding a new node at that point. - // We should also rebalance the tree at that point, but that's going to be implemented in phase II. - - addNodeInto(rowID,new IndexRootKey(indexIDValue)); - } - - /** Method to add a given node into a subtree where we start only with a parent key. - */ - protected void addNodeInto(LongValue rowID, WHKey parentKey) - throws WHException - { - for (int columnIndex = 0 ; columnIndex < columnIDs.length ; columnIndex++ ) - { - // Place a node into a specific tree as indicated by the column number. - // This will either wind up in an equals chain (in which case, a link to the column child will already exist), - // or it will wind up as a new primary node (in which case, the link to the column child will need to be created). - - parentKey = placeIntoBtree(rowID,parentKey,columnIndex); - } - } - - /** Method to place a new node into a specific tree for a column. - */ - protected WHKey placeIntoBtree(LongValue rowID, WHKey parentKey, int columnIndex) - throws WHException - { - // Get the current column - long columnID = columnIDs[columnIndex]; - WHComparator comparator = comparators[columnIndex]; - // Read the value we're going to be inserting - WHValue insertValue = (WHValue)table.getTableColumnValue(rowID,columnID); - // Keep going until we've found the insertion point (or until it looks like we're looping, - // which means we've hit a concurrency problem) - //Set hitSoFar = new HashSet(); - while (true) - { - // Pick up the current node from the parent - LongValue currentRowID = readIndexParentChild(parentKey); - if (currentRowID == null) - { - // Set the node in place - setIndexParentChild(parentKey,columnID,rowID); - return new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); - } - - //if (hitSoFar.contains(currentRowID)) - // throw new WHConcurrencyException(); - //hitSoFar.add(currentRowID); - - // Read the value at this node - WHValue currentValue = (WHValue)table.getTableColumnValue(currentRowID,columnID); - - // Perform the comparison - int comparatorResult = comparator.compare(currentValue,insertValue); - - // Based on the result, decide which way to go - switch (comparatorResult) - { - case WHComparator.RESULT_LESS: - // Descend the lesser tree for this column. - parentKey = new IndexNodeLesserKey(indexIDValue,currentRowID.getValue(),columnID); - continue; - case WHComparator.RESULT_GREATER: - // Descend the greater tree for this column. - parentKey = new IndexNodeGreaterKey(indexIDValue,currentRowID.getValue(),columnID); - continue; - case WHComparator.RESULT_EQUALS: - // Insert here! into the chain if need be... - break; - default: - throw new WHException("Comparator returned illegal result"); - } - - if (unique && columnIndex +1 == columnIDs.length) - { - // Unique constraint violation - throw new WHUniqueConstraintViolationException("Row "+new Long(rowID.getValue()).toString()+" violates uniqueness constraint on index "+new Long(indexIDValue).toString()); - } - - // We keep a linked list of identical nodes. We can insert into that chain at any point. - // We insert the new node at the beginning of the chain so we don't have to scan it, obviously... - - // First, get the old ref, if there is one. - LongValue currentEqualsRowID = readIndexNodeEqualsNode(currentRowID,columnID); - - // Move the old pointer to the new position - if (currentEqualsRowID != null) - { - // Delete the old one - deleteIndexNodeEqualsNode(currentRowID,columnID); - // Move the pointer to the child of the node we just created - setIndexNodeEqualsNode(rowID,columnID,currentEqualsRowID); - } - - // Now, set the new ref. - setIndexNodeEqualsNode(currentRowID,columnID,rowID); - - return new IndexNodeColumnKey(indexIDValue,currentRowID.getValue(),columnID); - } - } - - /** Remove a row from the index. The row must currently exist. - */ - protected void deleteRow(LongValue rowID) - throws WHException - { - // The deletion algorithm must remove N keys, one per column. We start with the key for - // column N-1, and work back to column 0. - // - // Each remove basically occurs independently within its own btree. In each btree, if - // the node has an equals child, that child is promoted and takes on the greater and lesser children - // of the node that is going away. If there is no equals child, then we promote either the lesser or - // the greater child, and if there are none of those we just remove the node and do nothing else. - // - // As part of promoting the lesser or greater child, the other child (if it exists) will be inserted - // into the btree and will be carried to the bottom and linked in. - - for (int i = columnIDs.length ; i > 0 ; i--) - { - removeFromBtree(rowID,i-1); - } - } - - /** Remove a row for a specific column from the corresponding btree. - */ - protected void removeFromBtree(LongValue rowID, int columnIndex) - throws WHException - { - long columnID = columnIDs[columnIndex]; - - // Build the index node's parent key - WHKey parentKey = readIndexNodeParentKey(rowID,columnID); - - // Look for an 'equals' child - LongValue equalsChild = readIndexNodeEqualsNode(rowID,columnID); - if (equalsChild != null) - { - // Case (1) (as described above). Promote the child. We know the child has - // no greater/lesser children. - deleteIndexNodeEqualsNode(rowID,columnID); - deleteIndexParentChild(parentKey,columnID); - setIndexParentChild(parentKey,columnID,equalsChild); - // Now, transfer the delete node's lesser/greater children to the equalsChild. - LongValue lesserChild = readIndexNodeLesserNode(rowID,columnID); - if (lesserChild != null) - { - deleteIndexNodeLesserNode(rowID,columnID); - setIndexNodeLesserNode(equalsChild,columnID,lesserChild); - } - LongValue greaterChild = readIndexNodeGreaterNode(rowID,columnID); - if (greaterChild != null) - { - deleteIndexNodeGreaterNode(rowID,columnID); - setIndexNodeGreaterNode(equalsChild,columnID,greaterChild); - } - return; - } - - // No equals chain. Instead we look for a node to be promoted. - - // The column priority is fixed and will not change, but the priority of lesser vs. greater is - // arbitrary. Someday we'll choose to promote the deeper side perhaps... - - // First, unhook the whole tree from the parent. - deleteIndexParentChild(parentKey,columnID); - - // Now look for a promotion candidate to hook in in its place. - LongValue promotionCandidate = null; - if (promotionCandidate == null) - { - promotionCandidate = readIndexNodeLesserNode(rowID,columnID); - if (promotionCandidate != null) - // We found our promotion candidate! - deleteIndexNodeLesserNode(rowID,columnID); - } - if (promotionCandidate == null) - { - promotionCandidate = readIndexNodeGreaterNode(rowID,columnID); - if (promotionCandidate != null) - // Candidate found - deleteIndexNodeGreaterNode(rowID,columnID); - } - - if (promotionCandidate != null) - { - // Hook in the promotion candidate as child of the parent. - setIndexParentChild(parentKey,columnID,promotionCandidate); - // Transfer the remaining lesser/greater children into the promotionCandidate node - LongValue lesserChild = readIndexNodeLesserNode(rowID,columnID); - if (lesserChild != null) - { - // Peel it away from the deleteNodeID - deleteIndexNodeLesserNode(rowID,columnID); - // Now insert this node into promotionCandidate via parentKey - placeIntoBtree(lesserChild,parentKey,columnIndex); - } - LongValue greaterChild = readIndexNodeGreaterNode(rowID,columnID); - if (greaterChild != null) - { - // Delete the reference from the deletion node - deleteIndexNodeGreaterNode(rowID,columnID); - // Now insert this node into promotionCandidate via parentKey - placeIntoBtree(greaterChild,parentKey,columnIndex); - } - } - } - - /** Initialize an entire index. - * WARNING: This effectively requires the entire new index to fit in memory! - * Better create the index when the table is small, then... - */ - protected void initialize() - throws WHException - { - // Create an accessor for the table - WHAccessor tableAccessor = table.buildAccessor(); - while (true) - { - LongValue rowID = (LongValue)tableAccessor.getCurrentRowID(); - if (rowID == null) - break; - // Add this row to the index. - addNewRow(rowID); - tableAccessor.advance(); - } - } - - /** Remove an entire index. - * WARNING: This effectively requires the entire index to fit in memory! - * It's far better to remove a bit at a time, in separate transactions. - */ - protected void remove() - throws WHException - { - deleteBtree(new IndexRootKey(indexIDValue),0); - } - - /** Delete a single btree with specified column index. - */ - protected void deleteBtree(WHKey key, int indexColumn) - throws WHException - { - if (indexColumn == columnIDs.length) - return; - - // For this btree, start with the root - LongValue child = readIndexParentChild(key); - // If there's no root, we are done - if (child == null) - return; - - // Delete the child. - long columnID = columnIDs[indexColumn]; - // First, unlink from the parent. - deleteIndexParentChild(key,columnID); - // Recursively clean up all child links. - deleteBtree(new IndexNodeEqualsKey(indexIDValue,child.getValue(),columnID),indexColumn); - deleteBtree(new IndexNodeLesserKey(indexIDValue,child.getValue(),columnID),indexColumn); - deleteBtree(new IndexNodeGreaterKey(indexIDValue,child.getValue(),columnID),indexColumn); - // Move on to next column - deleteBtree(new IndexNodeColumnKey(indexIDValue,child.getValue(),columnID),indexColumn+1); - } - - // Protected methods - - /** Get next column's root node for an index node. - * This link is necessary in order to allow each tree to rebalance independently. - */ - protected LongValue readIndexNodeColumnNode(LongValue rowID, long columnID) - throws WHException - { - return (LongValue)ts.get(new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID)); - } - - /** Set next column's root node for an index node. - */ - protected void setIndexNodeColumnNode(LongValue rowID, long columnID, LongValue refRowID) - throws WHException - { - IndexNodeColumnKey key = new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); - ts.put(key,refRowID); - ts.put(parentKey,key); - } - - /** Delete the column root-node child reference for an index node. Presumes that the reference exists. - */ - protected void deleteIndexNodeColumnNode(LongValue rowID, long columnID) - throws WHException - { - IndexNodeColumnKey key = new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); - LongValue childReference = (LongValue)ts.get(key); - if (childReference == null) - throw new WHConcurrencyException(); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); - ts.put(key,null); - ts.put(parentKey,null); - } - - /** Get the lesser child reference for an index node. - */ - protected LongValue readIndexNodeLesserNode(LongValue rowID, long columnID) - throws WHException - { - return (LongValue)ts.get(new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID)); - } - - /** Set the lesser child reference for an index node. Presumes that no such reference already exists. - */ - protected void setIndexNodeLesserNode(LongValue rowID, long columnID, LongValue refRowID) - throws WHException - { - IndexNodeLesserKey key = new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); - ts.put(key,refRowID); - ts.put(parentKey,key); - } - - /** Delete the lesser child reference for an index node. Presumes that the reference exists. - */ - protected void deleteIndexNodeLesserNode(LongValue rowID, long columnID) - throws WHException - { - IndexNodeLesserKey key = new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID); - LongValue childReference = (LongValue)ts.get(key); - if (childReference == null) - throw new WHConcurrencyException(); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); - ts.put(key,null); - ts.put(parentKey,null); - } - - /** Get the greater child reference for an index node. - */ - protected LongValue readIndexNodeGreaterNode(LongValue rowID, long columnID) - throws WHException - { - return (LongValue)ts.get(new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID)); - } - - /** Set the greater child reference for an index node. Presumes that the reference is currently empty. - */ - protected void setIndexNodeGreaterNode(LongValue rowID, long columnID, LongValue refRowID) - throws WHException - { - IndexNodeGreaterKey key = new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); - ts.put(key,refRowID); - ts.put(parentKey,key); - } - - /** Delete the greater child reference for an index node. Presumes that the reference exists. - */ - protected void deleteIndexNodeGreaterNode(LongValue rowID, long columnID) - throws WHException - { - IndexNodeGreaterKey key = new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID); - LongValue childReference = (LongValue)ts.get(key); - if (childReference == null) - throw new WHConcurrencyException(); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); - ts.put(key,null); - ts.put(parentKey,null); - } - - /** Get the equals child reference for an index node. - */ - protected LongValue readIndexNodeEqualsNode(LongValue rowID, long columnID) - throws WHException - { - return (LongValue)ts.get(new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID)); - } - - /** Set the equals child reference for an index node. Presumes that a reference doesn't yet exist. - */ - protected void setIndexNodeEqualsNode(LongValue rowID, long columnID, LongValue refRowID) - throws WHException - { - IndexNodeEqualsKey key = new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); - ts.put(key,refRowID); - ts.put(parentKey,key); - } - - /** Delete the equals child reference for an index node. Presumes that the reference exists. - */ - protected void deleteIndexNodeEqualsNode(LongValue rowID, long columnID) - throws WHException - { - IndexNodeEqualsKey key = new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID); - LongValue childReference = (LongValue)ts.get(key); - if (childReference == null) - throw new WHConcurrencyException(); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); - ts.put(key,null); - ts.put(parentKey,null); - } - - /** Get the parent reference for an index node. - */ - protected WHKey readIndexNodeParentKey(LongValue rowID, long columnID) - throws WHException - { - WHKey rval = (WHKey)ts.get(new IndexNodeParentKey(indexIDValue,rowID.getValue(),columnID)); - if (rval == null) - throw new WHConcurrencyException(); - return rval; - } - - /** Read the child node of a specified parent node. - */ - protected LongValue readIndexParentChild(WHKey parentKey) - throws WHException - { - return (LongValue)ts.get(parentKey); - } - - /** Set an index parent's child node. Presumes this child is not set yet. - */ - protected void setIndexParentChild(WHKey parentKey, long columnID, LongValue rowID) - throws WHException - { - ts.put(parentKey,rowID); - ts.put(new IndexNodeParentKey(indexIDValue,rowID.getValue(),columnID),parentKey); - } - - /** Remove an index parent's child node reference. Presumes that this child exists. - */ - protected void deleteIndexParentChild(WHKey parentKey, long columnID) - throws WHException - { - // Get the existing child - LongValue childNodeRef = (LongValue)ts.get(parentKey); - if (childNodeRef == null) - throw new WHConcurrencyException(); - ts.put(parentKey,null); - ts.put(new IndexNodeParentKey(indexIDValue,childNodeRef.getValue(),columnID),null); - } - - /** Get the root pointer for an index. - */ - protected LongValue readIndexRootNode() - throws WHException - { - return (LongValue)ts.get(new IndexRootKey(indexIDValue)); - } - - /** Set the root pointer for an index. Presumes the root pointer does not currently exist. - */ - protected void setIndexRootNode(LongValue rootRowID, long columnID) - throws WHException - { - IndexRootKey key = new IndexRootKey(indexIDValue); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,rootRowID.getValue(),columnID); - ts.put(key,rootRowID); - ts.put(parentKey,key); - } - - /** Delete the root node reference for an index. Presumes that the reference exists. - */ - protected void deleteIndexRootNode(long columnID) - throws WHException - { - IndexRootKey key = new IndexRootKey(indexIDValue); - LongValue childReference = (LongValue)ts.get(key); - if (childReference == null) - throw new WHConcurrencyException(); - IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); - ts.put(key,null); - ts.put(parentKey,null); - } - - -} +/* $Id$ */ + +/** +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.warthog.keyvaluetablestore; + +import org.apache.warthog.api.*; +import org.apache.warthog.transactionalkeyvaluestore.*; +import org.apache.warthog.common.*; + +import java.util.*; + +/** This is the standard implementation of WHIndex. +* +* The index structure has a one-to-one correspondence with the rows +* in the underlying table. Since there is such a correspondence, we make +* use of the rowID for each table row as a "nodeID". This reduces the number +* of keys/values we need to track for an index. +* +* The index has the following overall structure: +* (a) An (optional) root node reference, as decribed by a root key, which points to +* either nothing or the root node for the first index column; +* (b) A set of nodes for the first index column organized in a btree; +* (c) A reference from each node representing the first index column which +* functions as the root pointer for a btree based on the second index column, etc. +* +* Each btree node has a lesser child node reference, a greater child node reference, +* and an "equals" child node reference. All of these relationships refer to comparisons +* of the current column value for the row represented by the node. There are also rules +* for what is legal in any given context within each btree. Specifically, nodes that +* exist in the "equals" chain cannot have greater or lesser children, only "equals" +* children. +* +* For each node reference, there's also a back reference, which allows you to walk back +* up the tree. This is unique since every index node can have only one reference to it. +* +* In the future, a "maximum depth" value will also be associated with every node, so as +* to allow automatic rebalancing of each btree. +* +*/ +public class Index implements WHIndex +{ + protected TableStore ts; + protected Table table; + protected LongValue indexID; + protected long indexIDValue; + protected long[] columnIDs; + protected WHComparator[] comparators; + protected boolean unique; + + /** Constructor */ + public Index(TableStore ts, LongValue indexID, Table table, long[] columnIDs, String[] comparatorClasses, boolean unique) + throws WHException + { + if (columnIDs.length != comparatorClasses.length) + throw new WHException("Number of index column names must match number of comparator classes"); + this.ts = ts; + this.table = table; + this.indexID = indexID; + this.indexIDValue = indexID.getValue(); + this.columnIDs = columnIDs; + this.unique = unique; + this.comparators = new WHComparator[comparatorClasses.length]; + try + { + for (int i = 0 ; i < comparators.length ; i++) + { + this.comparators[i] = (WHComparator)Class.forName(comparatorClasses[i]).newInstance(); + } + } + catch (Exception e) + { + throw new WHException("Error instantiating comparator class for index '"+new Long(indexIDValue).toString()+"': "+e.getMessage(),e); + } + } + + /** Get the relationship the index applies to. + */ + public WHRelationship getRelationship() + throws WHException + { + return table; + } + + /** Get the underlying relationship column names. + */ + public String[] getColumnNames() + throws WHException + { + return table.getColumnNames(); + } + + /** Get a default accessor with default ordering and no filtering. + */ + public WHAccessor buildAccessor() + throws WHException + { + // Use null criteria + return buildAccessor(null,null); + } + + + /** Create an accessor based on this index which uses the provided criteria. The + * criteria must align with the index's columns. Null values are permitted where + * no criteria are present. + *@param criteria are the criteria that apply to each individual index column; null for no criteria at all. + *@param orderReversed is a boolean for each individual index column; true if the comparator order of that column + * should be reversed for the accessor. Null indicates no reversal for any column. + */ + public WHAccessor buildAccessor(IndexCriteria[] criteria, boolean[] orderReversed) + throws WHException + { + if (criteria != null && criteria.length != columnIDs.length) + throw new WHException("Criteria count must match index column count"); + if (orderReversed != null && orderReversed.length != columnIDs.length) + throw new WHException("Order reversal count must match index column count"); + return new IndexAccessor(this,criteria,orderReversed); + } + + // Below this line are methods that are not meant to be used for general purposes, + + /** Get the columns that are indexed + */ + protected long[] getIndexColumnIDs() + { + return columnIDs; + } + + /** Get the index id */ + protected LongValue getID() + { + return indexID; + } + + protected long getIDValue() + { + return indexIDValue; + } + + protected Table getTable() + { + return table; + } + + /** Get the comparators. + */ + protected WHComparator[] getComparators() + { + return comparators; + } + + /** Add a new row to the index. + * The row must already exist in the underlying table. + */ + protected void addNewRow(LongValue rowID) + throws WHException + { + // The algorithm here simply involves finding the right spot and adding a new node at that point. + // We should also rebalance the tree at that point, but that's going to be implemented in phase II. + + addNodeInto(rowID,new IndexRootKey(indexIDValue)); + } + + /** Method to add a given node into a subtree where we start only with a parent key. + */ + protected void addNodeInto(LongValue rowID, WHKey parentKey) + throws WHException + { + for (int columnIndex = 0 ; columnIndex < columnIDs.length ; columnIndex++ ) + { + // Place a node into a specific tree as indicated by the column number. + // This will either wind up in an equals chain (in which case, a link to the column child will already exist), + // or it will wind up as a new primary node (in which case, the link to the column child will need to be created). + + parentKey = placeIntoBtree(rowID,parentKey,columnIndex); + } + } + + /** Method to place a new node into a specific tree for a column. + */ + protected WHKey placeIntoBtree(LongValue rowID, WHKey parentKey, int columnIndex) + throws WHException + { + // Get the current column + long columnID = columnIDs[columnIndex]; + WHComparator comparator = comparators[columnIndex]; + // Read the value we're going to be inserting + WHValue insertValue = (WHValue)table.getTableColumnValue(rowID,columnID); + // Keep going until we've found the insertion point (or until it looks like we're looping, + // which means we've hit a concurrency problem) + //Set hitSoFar = new HashSet(); + while (true) + { + // Pick up the current node from the parent + LongValue currentRowID = readIndexParentChild(parentKey); + if (currentRowID == null) + { + // Set the node in place + setIndexParentChild(parentKey,columnID,rowID); + return new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); + } + + //if (hitSoFar.contains(currentRowID)) + // throw new WHConcurrencyException(); + //hitSoFar.add(currentRowID); + + // Read the value at this node + WHValue currentValue = (WHValue)table.getTableColumnValue(currentRowID,columnID); + + // Perform the comparison + int comparatorResult = comparator.compare(currentValue,insertValue); + + // Based on the result, decide which way to go + switch (comparatorResult) + { + case WHComparator.RESULT_LESS: + // Descend the lesser tree for this column. + parentKey = new IndexNodeLesserKey(indexIDValue,currentRowID.getValue(),columnID); + continue; + case WHComparator.RESULT_GREATER: + // Descend the greater tree for this column. + parentKey = new IndexNodeGreaterKey(indexIDValue,currentRowID.getValue(),columnID); + continue; + case WHComparator.RESULT_EQUALS: + // Insert here! into the chain if need be... + break; + default: + throw new WHException("Comparator returned illegal result"); + } + + if (unique && columnIndex +1 == columnIDs.length) + { + // Unique constraint violation + throw new WHUniqueConstraintViolationException("Row "+new Long(rowID.getValue()).toString()+" violates uniqueness constraint on index "+new Long(indexIDValue).toString()); + } + + // We keep a linked list of identical nodes. We can insert into that chain at any point. + // We insert the new node at the beginning of the chain so we don't have to scan it, obviously... + + // First, get the old ref, if there is one. + LongValue currentEqualsRowID = readIndexNodeEqualsNode(currentRowID,columnID); + + // Move the old pointer to the new position + if (currentEqualsRowID != null) + { + // Delete the old one + deleteIndexNodeEqualsNode(currentRowID,columnID); + // Move the pointer to the child of the node we just created + setIndexNodeEqualsNode(rowID,columnID,currentEqualsRowID); + } + + // Now, set the new ref. + setIndexNodeEqualsNode(currentRowID,columnID,rowID); + + return new IndexNodeColumnKey(indexIDValue,currentRowID.getValue(),columnID); + } + } + + /** Remove a row from the index. The row must currently exist. + */ + protected void deleteRow(LongValue rowID) + throws WHException + { + // The deletion algorithm must remove N keys, one per column. We start with the key for + // column N-1, and work back to column 0. + // + // Each remove basically occurs independently within its own btree. In each btree, if + // the node has an equals child, that child is promoted and takes on the greater and lesser children + // of the node that is going away. If there is no equals child, then we promote either the lesser or + // the greater child, and if there are none of those we just remove the node and do nothing else. + // + // As part of promoting the lesser or greater child, the other child (if it exists) will be inserted + // into the btree and will be carried to the bottom and linked in. + + for (int i = columnIDs.length ; i > 0 ; i--) + { + removeFromBtree(rowID,i-1); + } + } + + /** Remove a row for a specific column from the corresponding btree. + */ + protected void removeFromBtree(LongValue rowID, int columnIndex) + throws WHException + { + long columnID = columnIDs[columnIndex]; + + // Build the index node's parent key + WHKey parentKey = readIndexNodeParentKey(rowID,columnID); + + // Look for an 'equals' child + LongValue equalsChild = readIndexNodeEqualsNode(rowID,columnID); + if (equalsChild != null) + { + // Case (1) (as described above). Promote the child. We know the child has + // no greater/lesser children. + deleteIndexNodeEqualsNode(rowID,columnID); + deleteIndexParentChild(parentKey,columnID); + setIndexParentChild(parentKey,columnID,equalsChild); + // Now, transfer the delete node's lesser/greater children to the equalsChild. + LongValue lesserChild = readIndexNodeLesserNode(rowID,columnID); + if (lesserChild != null) + { + deleteIndexNodeLesserNode(rowID,columnID); + setIndexNodeLesserNode(equalsChild,columnID,lesserChild); + } + LongValue greaterChild = readIndexNodeGreaterNode(rowID,columnID); + if (greaterChild != null) + { + deleteIndexNodeGreaterNode(rowID,columnID); + setIndexNodeGreaterNode(equalsChild,columnID,greaterChild); + } + return; + } + + // No equals chain. Instead we look for a node to be promoted. + + // The column priority is fixed and will not change, but the priority of lesser vs. greater is + // arbitrary. Someday we'll choose to promote the deeper side perhaps... + + // First, unhook the whole tree from the parent. + deleteIndexParentChild(parentKey,columnID); + + // Now look for a promotion candidate to hook in in its place. + LongValue promotionCandidate = null; + if (promotionCandidate == null) + { + promotionCandidate = readIndexNodeLesserNode(rowID,columnID); + if (promotionCandidate != null) + // We found our promotion candidate! + deleteIndexNodeLesserNode(rowID,columnID); + } + if (promotionCandidate == null) + { + promotionCandidate = readIndexNodeGreaterNode(rowID,columnID); + if (promotionCandidate != null) + // Candidate found + deleteIndexNodeGreaterNode(rowID,columnID); + } + + if (promotionCandidate != null) + { + // Hook in the promotion candidate as child of the parent. + setIndexParentChild(parentKey,columnID,promotionCandidate); + // Transfer the remaining lesser/greater children into the promotionCandidate node + LongValue lesserChild = readIndexNodeLesserNode(rowID,columnID); + if (lesserChild != null) + { + // Peel it away from the deleteNodeID + deleteIndexNodeLesserNode(rowID,columnID); + // Now insert this node into promotionCandidate via parentKey + placeIntoBtree(lesserChild,parentKey,columnIndex); + } + LongValue greaterChild = readIndexNodeGreaterNode(rowID,columnID); + if (greaterChild != null) + { + // Delete the reference from the deletion node + deleteIndexNodeGreaterNode(rowID,columnID); + // Now insert this node into promotionCandidate via parentKey + placeIntoBtree(greaterChild,parentKey,columnIndex); + } + } + } + + /** Initialize an entire index. + * WARNING: This effectively requires the entire new index to fit in memory! + * Better create the index when the table is small, then... + */ + protected void initialize() + throws WHException + { + // Create an accessor for the table + WHAccessor tableAccessor = table.buildAccessor(); + while (true) + { + LongValue rowID = (LongValue)tableAccessor.getCurrentRowID(); + if (rowID == null) + break; + // Add this row to the index. + addNewRow(rowID); + tableAccessor.advance(); + } + } + + /** Remove an entire index. + * WARNING: This effectively requires the entire index to fit in memory! + * It's far better to remove a bit at a time, in separate transactions. + */ + protected void remove() + throws WHException + { + deleteBtree(new IndexRootKey(indexIDValue),0); + } + + /** Delete a single btree with specified column index. + */ + protected void deleteBtree(WHKey key, int indexColumn) + throws WHException + { + if (indexColumn == columnIDs.length) + return; + + // For this btree, start with the root + LongValue child = readIndexParentChild(key); + // If there's no root, we are done + if (child == null) + return; + + // Delete the child. + long columnID = columnIDs[indexColumn]; + // First, unlink from the parent. + deleteIndexParentChild(key,columnID); + // Recursively clean up all child links. + deleteBtree(new IndexNodeEqualsKey(indexIDValue,child.getValue(),columnID),indexColumn); + deleteBtree(new IndexNodeLesserKey(indexIDValue,child.getValue(),columnID),indexColumn); + deleteBtree(new IndexNodeGreaterKey(indexIDValue,child.getValue(),columnID),indexColumn); + // Move on to next column + deleteBtree(new IndexNodeColumnKey(indexIDValue,child.getValue(),columnID),indexColumn+1); + } + + // Protected methods + + /** Get next column's root node for an index node. + * This link is necessary in order to allow each tree to rebalance independently. + */ + protected LongValue readIndexNodeColumnNode(LongValue rowID, long columnID) + throws WHException + { + return (LongValue)ts.get(new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID)); + } + + /** Set next column's root node for an index node. + */ + protected void setIndexNodeColumnNode(LongValue rowID, long columnID, LongValue refRowID) + throws WHException + { + IndexNodeColumnKey key = new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); + ts.put(key,refRowID); + ts.put(parentKey,key); + } + + /** Delete the column root-node child reference for an index node. Presumes that the reference exists. + */ + protected void deleteIndexNodeColumnNode(LongValue rowID, long columnID) + throws WHException + { + IndexNodeColumnKey key = new IndexNodeColumnKey(indexIDValue,rowID.getValue(),columnID); + LongValue childReference = (LongValue)ts.get(key); + if (childReference == null) + throw new WHConcurrencyException(); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); + ts.put(key,null); + ts.put(parentKey,null); + } + + /** Get the lesser child reference for an index node. + */ + protected LongValue readIndexNodeLesserNode(LongValue rowID, long columnID) + throws WHException + { + return (LongValue)ts.get(new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID)); + } + + /** Set the lesser child reference for an index node. Presumes that no such reference already exists. + */ + protected void setIndexNodeLesserNode(LongValue rowID, long columnID, LongValue refRowID) + throws WHException + { + IndexNodeLesserKey key = new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); + ts.put(key,refRowID); + ts.put(parentKey,key); + } + + /** Delete the lesser child reference for an index node. Presumes that the reference exists. + */ + protected void deleteIndexNodeLesserNode(LongValue rowID, long columnID) + throws WHException + { + IndexNodeLesserKey key = new IndexNodeLesserKey(indexIDValue,rowID.getValue(),columnID); + LongValue childReference = (LongValue)ts.get(key); + if (childReference == null) + throw new WHConcurrencyException(); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); + ts.put(key,null); + ts.put(parentKey,null); + } + + /** Get the greater child reference for an index node. + */ + protected LongValue readIndexNodeGreaterNode(LongValue rowID, long columnID) + throws WHException + { + return (LongValue)ts.get(new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID)); + } + + /** Set the greater child reference for an index node. Presumes that the reference is currently empty. + */ + protected void setIndexNodeGreaterNode(LongValue rowID, long columnID, LongValue refRowID) + throws WHException + { + IndexNodeGreaterKey key = new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); + ts.put(key,refRowID); + ts.put(parentKey,key); + } + + /** Delete the greater child reference for an index node. Presumes that the reference exists. + */ + protected void deleteIndexNodeGreaterNode(LongValue rowID, long columnID) + throws WHException + { + IndexNodeGreaterKey key = new IndexNodeGreaterKey(indexIDValue,rowID.getValue(),columnID); + LongValue childReference = (LongValue)ts.get(key); + if (childReference == null) + throw new WHConcurrencyException(); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); + ts.put(key,null); + ts.put(parentKey,null); + } + + /** Get the equals child reference for an index node. + */ + protected LongValue readIndexNodeEqualsNode(LongValue rowID, long columnID) + throws WHException + { + return (LongValue)ts.get(new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID)); + } + + /** Set the equals child reference for an index node. Presumes that a reference doesn't yet exist. + */ + protected void setIndexNodeEqualsNode(LongValue rowID, long columnID, LongValue refRowID) + throws WHException + { + IndexNodeEqualsKey key = new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,refRowID.getValue(),columnID); + ts.put(key,refRowID); + ts.put(parentKey,key); + } + + /** Delete the equals child reference for an index node. Presumes that the reference exists. + */ + protected void deleteIndexNodeEqualsNode(LongValue rowID, long columnID) + throws WHException + { + IndexNodeEqualsKey key = new IndexNodeEqualsKey(indexIDValue,rowID.getValue(),columnID); + LongValue childReference = (LongValue)ts.get(key); + if (childReference == null) + throw new WHConcurrencyException(); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); + ts.put(key,null); + ts.put(parentKey,null); + } + + /** Get the parent reference for an index node. + */ + protected WHKey readIndexNodeParentKey(LongValue rowID, long columnID) + throws WHException + { + WHKey rval = (WHKey)ts.get(new IndexNodeParentKey(indexIDValue,rowID.getValue(),columnID)); + if (rval == null) + throw new WHConcurrencyException(); + return rval; + } + + /** Read the child node of a specified parent node. + */ + protected LongValue readIndexParentChild(WHKey parentKey) + throws WHException + { + return (LongValue)ts.get(parentKey); + } + + /** Set an index parent's child node. Presumes this child is not set yet. + */ + protected void setIndexParentChild(WHKey parentKey, long columnID, LongValue rowID) + throws WHException + { + ts.put(parentKey,rowID); + ts.put(new IndexNodeParentKey(indexIDValue,rowID.getValue(),columnID),parentKey); + } + + /** Remove an index parent's child node reference. Presumes that this child exists. + */ + protected void deleteIndexParentChild(WHKey parentKey, long columnID) + throws WHException + { + // Get the existing child + LongValue childNodeRef = (LongValue)ts.get(parentKey); + if (childNodeRef == null) + throw new WHConcurrencyException(); + ts.put(parentKey,null); + ts.put(new IndexNodeParentKey(indexIDValue,childNodeRef.getValue(),columnID),null); + } + + /** Get the root pointer for an index. + */ + protected LongValue readIndexRootNode() + throws WHException + { + return (LongValue)ts.get(new IndexRootKey(indexIDValue)); + } + + /** Set the root pointer for an index. Presumes the root pointer does not currently exist. + */ + protected void setIndexRootNode(LongValue rootRowID, long columnID) + throws WHException + { + IndexRootKey key = new IndexRootKey(indexIDValue); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,rootRowID.getValue(),columnID); + ts.put(key,rootRowID); + ts.put(parentKey,key); + } + + /** Delete the root node reference for an index. Presumes that the reference exists. + */ + protected void deleteIndexRootNode(long columnID) + throws WHException + { + IndexRootKey key = new IndexRootKey(indexIDValue); + LongValue childReference = (LongValue)ts.get(key); + if (childReference == null) + throw new WHConcurrencyException(); + IndexNodeParentKey parentKey = new IndexNodeParentKey(indexIDValue,childReference.getValue(),columnID); + ts.put(key,null); + ts.put(parentKey,null); + } + + +} Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/Index.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java?rev=1220353&r1=1220352&r2=1220353&view=diff ============================================================================== --- incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java (original) +++ incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java Sun Dec 18 08:36:52 2011 @@ -1,306 +1,306 @@ -/* $Id: IndexAccessor.java 1209929 2011-12-03 15:06:22Z kwright $ */ - -/** -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.warthog.keyvaluetablestore; - -import org.apache.warthog.api.*; -import org.apache.warthog.transactionalkeyvaluestore.*; -import org.apache.warthog.common.*; -import java.util.*; - -/** Index accessor, with criteria. -* The problem with writing an index accessor is the requirement that you be allowed to remove the node you just returned without anything bad -* happening to the state. This restriction severely limits how we can store the 'current node'. Keeping state in a 'stack' won't work because -* the parent node may well be destroyed, and thus when it becomes time to "pop" up a level we'll have meaningless state to work with. -* The alternative - keeping a back pointer for each node - is better, since it allows us to keep the entire state using one node reference, but -* it too has problems. Specifically, all state is lost when descent into the child occurs, so upon returning to the parent, we don't know where -* we are or which branches we've already taken. -* -* Another alternative is to keep nodes that we've "discovered" in an in-memory ordered queue. Thus, when we visit a node, we assess immediately -* which branches we will be taking, and which we will be skipping, and push the "taking" node id's onto the queue in proper order before doing anything else. -* Since we pull nodes off the queue from the front, and since only that node can be deleted, by definition we cannot mess up the queue. This is the -* alternative this class uses. -*/ -public class IndexAccessor implements WHAccessor -{ - protected Index index; - protected Table table; - protected long[] indexColumnIDs; - protected WHComparator[] comparators; - protected IndexCriteria[] indexCriteria; - protected boolean[] orderReversed; - - /** This is the current node queue. Nodes on the queue are unevaluated!! */ - protected NodeQueue queue = new NodeQueue(); - - /** The current (matching) rowID, to be returned */ - protected LongValue currentRowID; - - /** Constructor */ - public IndexAccessor(Index index, IndexCriteria[] indexCriteria, boolean[] orderReversed) - throws WHException - { - this.index = index; - this.table = index.getTable(); - this.indexColumnIDs = index.getIndexColumnIDs(); - this.comparators = index.getComparators(); - this.indexCriteria = indexCriteria; - this.orderReversed = orderReversed; - LongValue rootRowID = index.readIndexRootNode(); - if (rootRowID != null) - queue.pushNeedsAnalysis(rootRowID,0); - goToNextLegalRow(); - } - - /** Advance to the next row. - */ - public void advance() - throws WHException - { - if (currentRowID != null) - { - goToNextLegalRow(); - } - } - - /** Read the current relationship row ID, Null will be returned if we are - * at the end of the sequence. - */ - public WHRowID getCurrentRowID() - throws WHException - { - return currentRowID; - } - - /** Get the data for the current row and specified column. - */ - public WHValue getValue(String columnName) - throws WHException - { - if (currentRowID != null) - return (WHValue)table.getTableColumnValue(currentRowID,table.getColumnID(columnName)); - throw new WHException("Can't read beyond end of accessor"); - } - - protected void goToNextLegalRow() - throws WHException - { - while (true) - { - // Find the next node, using the queue - Node node = queue.pop(); - if (node == null) - { - currentRowID = null; - return; - } - - if (node.getAction() == ACTION_DEREFERENCE) - { - currentRowID = node.getRowID(); - return; - } - - if (node.getAction() == ACTION_CHASE_EQUALS) - { - // We can skip all analysis, and just chase the equals chain. - LongValue chaseRowID = node.getRowID(); - // Push the rowID, then chase the equals chain. - queue.pushNeedsDereference(chaseRowID); - // Now find the next node in the equals chain. - LongValue nextEqualsNode = index.readIndexNodeEqualsNode(chaseRowID,indexColumnIDs[indexColumnIDs.length-1]); - if (nextEqualsNode != null) - { - // Because it's equals chain, we know that it is unnecessary to evaluate its fields, so note that when - // we queue it. - queue.pushChaseEquals(nextEqualsNode); - } - continue; - } - - // This node needs analysis. - int columnIndex = node.getColumnIndex(); - LongValue rowID = node.getRowID(); - - // Evaluate the node, pushing its descendents, and make a decision whether to - // use the row or not. - - // Look at the node and decide about whether to queue up all its pointers. - // We can only add at the beginning of the queue, so we must be careful to push - // nodes in backwards order!! - - // Evaluate this column - long currentColumnID = indexColumnIDs[columnIndex]; - // Get the column value - WHValue columnValue = (WHValue)index.getTable().getTableColumnValue(rowID,currentColumnID); - - // Do the assessment, if there are index criteria for this column - int criteria; - if (indexCriteria != null && indexCriteria[columnIndex] != null) - criteria = indexCriteria[columnIndex].evaluateValue(columnValue,comparators[columnIndex]); - else - criteria = IndexCriteria.SIGNAL_LESSER | IndexCriteria.SIGNAL_GREATER | IndexCriteria.SIGNAL_EQUALS; - - // Remember, we want to push greater values first, then lesser. Order reversal will swap that around. - if (orderReversed == null || orderReversed[columnIndex] == false) - { - if ((criteria & IndexCriteria.SIGNAL_GREATER) != 0) - { - // Dereference the greater child for this column and push that node for analysis - LongValue childRowID = index.readIndexNodeGreaterNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID != null) - queue.pushNeedsAnalysis(childRowID,columnIndex); - } - // Do the equals children next - if ((criteria & IndexCriteria.SIGNAL_EQUALS) != 0) - { - // We want to continue on to the next column, or if we're at the end, we take the - // row ID. - if (columnIndex + 1 == indexColumnIDs.length) - queue.pushChaseEquals(rowID); - else - { - LongValue childRowID = index.readIndexNodeColumnNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID == null) - throw new WHConcurrencyException(); - queue.pushNeedsAnalysis(childRowID,columnIndex+1); - } - } - if ((criteria & IndexCriteria.SIGNAL_LESSER) != 0) - { - // Dereference the lesser child for this column and push that node for analysis - LongValue childRowID = index.readIndexNodeLesserNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID != null) - queue.pushNeedsAnalysis(childRowID,columnIndex); - } - } - else - { - if ((criteria & IndexCriteria.SIGNAL_LESSER) != 0) - { - // Dereference the lesser child for this column and push that node for analysis - LongValue childRowID = index.readIndexNodeLesserNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID != null) - queue.pushNeedsAnalysis(childRowID,columnIndex); - } - // Do the equals children next - if ((criteria & IndexCriteria.SIGNAL_EQUALS) != 0) - { - // We want to continue on to the next column, or if we're at the end, we take the - // row ID. - if (columnIndex + 1 == indexColumnIDs.length) - queue.pushChaseEquals(rowID); - else - { - LongValue childRowID = index.readIndexNodeColumnNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID == null) - throw new WHConcurrencyException(); - queue.pushNeedsAnalysis(childRowID,columnIndex+1); - } - } - if ((criteria & IndexCriteria.SIGNAL_GREATER) != 0) - { - // Dereference the greater child for this column and push that node for analysis - LongValue childRowID = index.readIndexNodeGreaterNode(rowID,indexColumnIDs[columnIndex]); - if (childRowID != null) - queue.pushNeedsAnalysis(childRowID,columnIndex); - } - } - } - } - - // The types of actions we need the engine to understand, which must be signaled in the queue - /** Full analysis */ - protected static final int ACTION_FULL_ANALYSIS = 0; - /** Chase equals chain (no analysis needed) */ - protected static final int ACTION_CHASE_EQUALS = 1; - /** Just dereference to rowID */ - protected static final int ACTION_DEREFERENCE = 2; - - /** The node queue */ - protected static class NodeQueue - { - protected List nodeList = new ArrayList(); - - public NodeQueue() - { - } - - public void pushNeedsAnalysis(LongValue rowID, int columnIndex) - { - nodeList.add(new Node(rowID,columnIndex,ACTION_FULL_ANALYSIS)); - } - - public void pushChaseEquals(LongValue rowID) - { - nodeList.add(new Node(rowID,-1,ACTION_CHASE_EQUALS)); - } - - public void pushNeedsDereference(LongValue rowID) - { - nodeList.add(new Node(rowID,-1,ACTION_DEREFERENCE)); - } - - public Node pop() - { - if (nodeList.size() == 0) - return null; - return nodeList.remove(nodeList.size()-1); - } - } - - /** A node in the queue */ - protected static class Node - { - protected LongValue rowID; - protected int columnIndex; - protected int action; - - /** Constructor */ - public Node(LongValue rowID, int columnIndex, int action) - { - this.rowID = rowID; - this.columnIndex = columnIndex; - this.action = action; - } - - /** Get the node id. - */ - public LongValue getRowID() - { - return rowID; - } - - /** Get the column index. - */ - public int getColumnIndex() - { - return columnIndex; - } - - /** Get whether this node should be treated as needing dereference or needing analysis. - */ - public int getAction() - { - return action; - } - - } - -} +/* $Id$ */ + +/** +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.warthog.keyvaluetablestore; + +import org.apache.warthog.api.*; +import org.apache.warthog.transactionalkeyvaluestore.*; +import org.apache.warthog.common.*; +import java.util.*; + +/** Index accessor, with criteria. +* The problem with writing an index accessor is the requirement that you be allowed to remove the node you just returned without anything bad +* happening to the state. This restriction severely limits how we can store the 'current node'. Keeping state in a 'stack' won't work because +* the parent node may well be destroyed, and thus when it becomes time to "pop" up a level we'll have meaningless state to work with. +* The alternative - keeping a back pointer for each node - is better, since it allows us to keep the entire state using one node reference, but +* it too has problems. Specifically, all state is lost when descent into the child occurs, so upon returning to the parent, we don't know where +* we are or which branches we've already taken. +* +* Another alternative is to keep nodes that we've "discovered" in an in-memory ordered queue. Thus, when we visit a node, we assess immediately +* which branches we will be taking, and which we will be skipping, and push the "taking" node id's onto the queue in proper order before doing anything else. +* Since we pull nodes off the queue from the front, and since only that node can be deleted, by definition we cannot mess up the queue. This is the +* alternative this class uses. +*/ +public class IndexAccessor implements WHAccessor +{ + protected Index index; + protected Table table; + protected long[] indexColumnIDs; + protected WHComparator[] comparators; + protected IndexCriteria[] indexCriteria; + protected boolean[] orderReversed; + + /** This is the current node queue. Nodes on the queue are unevaluated!! */ + protected NodeQueue queue = new NodeQueue(); + + /** The current (matching) rowID, to be returned */ + protected LongValue currentRowID; + + /** Constructor */ + public IndexAccessor(Index index, IndexCriteria[] indexCriteria, boolean[] orderReversed) + throws WHException + { + this.index = index; + this.table = index.getTable(); + this.indexColumnIDs = index.getIndexColumnIDs(); + this.comparators = index.getComparators(); + this.indexCriteria = indexCriteria; + this.orderReversed = orderReversed; + LongValue rootRowID = index.readIndexRootNode(); + if (rootRowID != null) + queue.pushNeedsAnalysis(rootRowID,0); + goToNextLegalRow(); + } + + /** Advance to the next row. + */ + public void advance() + throws WHException + { + if (currentRowID != null) + { + goToNextLegalRow(); + } + } + + /** Read the current relationship row ID, Null will be returned if we are + * at the end of the sequence. + */ + public WHRowID getCurrentRowID() + throws WHException + { + return currentRowID; + } + + /** Get the data for the current row and specified column. + */ + public WHValue getValue(String columnName) + throws WHException + { + if (currentRowID != null) + return (WHValue)table.getTableColumnValue(currentRowID,table.getColumnID(columnName)); + throw new WHException("Can't read beyond end of accessor"); + } + + protected void goToNextLegalRow() + throws WHException + { + while (true) + { + // Find the next node, using the queue + Node node = queue.pop(); + if (node == null) + { + currentRowID = null; + return; + } + + if (node.getAction() == ACTION_DEREFERENCE) + { + currentRowID = node.getRowID(); + return; + } + + if (node.getAction() == ACTION_CHASE_EQUALS) + { + // We can skip all analysis, and just chase the equals chain. + LongValue chaseRowID = node.getRowID(); + // Push the rowID, then chase the equals chain. + queue.pushNeedsDereference(chaseRowID); + // Now find the next node in the equals chain. + LongValue nextEqualsNode = index.readIndexNodeEqualsNode(chaseRowID,indexColumnIDs[indexColumnIDs.length-1]); + if (nextEqualsNode != null) + { + // Because it's equals chain, we know that it is unnecessary to evaluate its fields, so note that when + // we queue it. + queue.pushChaseEquals(nextEqualsNode); + } + continue; + } + + // This node needs analysis. + int columnIndex = node.getColumnIndex(); + LongValue rowID = node.getRowID(); + + // Evaluate the node, pushing its descendents, and make a decision whether to + // use the row or not. + + // Look at the node and decide about whether to queue up all its pointers. + // We can only add at the beginning of the queue, so we must be careful to push + // nodes in backwards order!! + + // Evaluate this column + long currentColumnID = indexColumnIDs[columnIndex]; + // Get the column value + WHValue columnValue = (WHValue)index.getTable().getTableColumnValue(rowID,currentColumnID); + + // Do the assessment, if there are index criteria for this column + int criteria; + if (indexCriteria != null && indexCriteria[columnIndex] != null) + criteria = indexCriteria[columnIndex].evaluateValue(columnValue,comparators[columnIndex]); + else + criteria = IndexCriteria.SIGNAL_LESSER | IndexCriteria.SIGNAL_GREATER | IndexCriteria.SIGNAL_EQUALS; + + // Remember, we want to push greater values first, then lesser. Order reversal will swap that around. + if (orderReversed == null || orderReversed[columnIndex] == false) + { + if ((criteria & IndexCriteria.SIGNAL_GREATER) != 0) + { + // Dereference the greater child for this column and push that node for analysis + LongValue childRowID = index.readIndexNodeGreaterNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID != null) + queue.pushNeedsAnalysis(childRowID,columnIndex); + } + // Do the equals children next + if ((criteria & IndexCriteria.SIGNAL_EQUALS) != 0) + { + // We want to continue on to the next column, or if we're at the end, we take the + // row ID. + if (columnIndex + 1 == indexColumnIDs.length) + queue.pushChaseEquals(rowID); + else + { + LongValue childRowID = index.readIndexNodeColumnNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID == null) + throw new WHConcurrencyException(); + queue.pushNeedsAnalysis(childRowID,columnIndex+1); + } + } + if ((criteria & IndexCriteria.SIGNAL_LESSER) != 0) + { + // Dereference the lesser child for this column and push that node for analysis + LongValue childRowID = index.readIndexNodeLesserNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID != null) + queue.pushNeedsAnalysis(childRowID,columnIndex); + } + } + else + { + if ((criteria & IndexCriteria.SIGNAL_LESSER) != 0) + { + // Dereference the lesser child for this column and push that node for analysis + LongValue childRowID = index.readIndexNodeLesserNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID != null) + queue.pushNeedsAnalysis(childRowID,columnIndex); + } + // Do the equals children next + if ((criteria & IndexCriteria.SIGNAL_EQUALS) != 0) + { + // We want to continue on to the next column, or if we're at the end, we take the + // row ID. + if (columnIndex + 1 == indexColumnIDs.length) + queue.pushChaseEquals(rowID); + else + { + LongValue childRowID = index.readIndexNodeColumnNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID == null) + throw new WHConcurrencyException(); + queue.pushNeedsAnalysis(childRowID,columnIndex+1); + } + } + if ((criteria & IndexCriteria.SIGNAL_GREATER) != 0) + { + // Dereference the greater child for this column and push that node for analysis + LongValue childRowID = index.readIndexNodeGreaterNode(rowID,indexColumnIDs[columnIndex]); + if (childRowID != null) + queue.pushNeedsAnalysis(childRowID,columnIndex); + } + } + } + } + + // The types of actions we need the engine to understand, which must be signaled in the queue + /** Full analysis */ + protected static final int ACTION_FULL_ANALYSIS = 0; + /** Chase equals chain (no analysis needed) */ + protected static final int ACTION_CHASE_EQUALS = 1; + /** Just dereference to rowID */ + protected static final int ACTION_DEREFERENCE = 2; + + /** The node queue */ + protected static class NodeQueue + { + protected List nodeList = new ArrayList(); + + public NodeQueue() + { + } + + public void pushNeedsAnalysis(LongValue rowID, int columnIndex) + { + nodeList.add(new Node(rowID,columnIndex,ACTION_FULL_ANALYSIS)); + } + + public void pushChaseEquals(LongValue rowID) + { + nodeList.add(new Node(rowID,-1,ACTION_CHASE_EQUALS)); + } + + public void pushNeedsDereference(LongValue rowID) + { + nodeList.add(new Node(rowID,-1,ACTION_DEREFERENCE)); + } + + public Node pop() + { + if (nodeList.size() == 0) + return null; + return nodeList.remove(nodeList.size()-1); + } + } + + /** A node in the queue */ + protected static class Node + { + protected LongValue rowID; + protected int columnIndex; + protected int action; + + /** Constructor */ + public Node(LongValue rowID, int columnIndex, int action) + { + this.rowID = rowID; + this.columnIndex = columnIndex; + this.action = action; + } + + /** Get the node id. + */ + public LongValue getRowID() + { + return rowID; + } + + /** Get the column index. + */ + public int getColumnIndex() + { + return columnIndex; + } + + /** Get whether this node should be treated as needing dereference or needing analysis. + */ + public int getAction() + { + return action; + } + + } + +} Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexAccessor.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java?rev=1220353&r1=1220352&r2=1220353&view=diff ============================================================================== --- incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java (original) +++ incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java Sun Dec 18 08:36:52 2011 @@ -1,39 +1,39 @@ -/* $Id: IndexKey.java 1207727 2011-11-29 01:12:13Z kwright $ */ - -/** -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.warthog.keyvaluetablestore; - -import org.apache.warthog.api.*; -import org.apache.warthog.transactionalkeyvaluestore.*; -import org.apache.warthog.common.*; - -/** Key for accessing an index definition */ -public class IndexKey extends LongKey -{ - /** Constructor */ - public IndexKey(long indexID) - { - super(indexID); - } - - public IndexKey(byte[] data) - { - super(data); - } -} +/* $Id$ */ + +/** +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.warthog.keyvaluetablestore; + +import org.apache.warthog.api.*; +import org.apache.warthog.transactionalkeyvaluestore.*; +import org.apache.warthog.common.*; + +/** Key for accessing an index definition */ +public class IndexKey extends LongKey +{ + /** Constructor */ + public IndexKey(long indexID) + { + super(indexID); + } + + public IndexKey(byte[] data) + { + super(data); + } +} Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexKey.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java?rev=1220353&r1=1220352&r2=1220353&view=diff ============================================================================== --- incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java (original) +++ incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java Sun Dec 18 08:36:52 2011 @@ -1,39 +1,39 @@ -/* $Id: IndexLookupKey.java 1207727 2011-11-29 01:12:13Z kwright $ */ - -/** -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.warthog.keyvaluetablestore; - -import org.apache.warthog.api.*; -import org.apache.warthog.transactionalkeyvaluestore.*; -import org.apache.warthog.common.*; - -/** Key for accessing an index identifier */ -public class IndexLookupKey extends StringKey -{ - /** Constructor */ - public IndexLookupKey(String name) - { - super(name); - } - - public IndexLookupKey(byte[] data) - { - super(data); - } -} +/* $Id$ */ + +/** +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.warthog.keyvaluetablestore; + +import org.apache.warthog.api.*; +import org.apache.warthog.transactionalkeyvaluestore.*; +import org.apache.warthog.common.*; + +/** Key for accessing an index identifier */ +public class IndexLookupKey extends StringKey +{ + /** Constructor */ + public IndexLookupKey(String name) + { + super(name); + } + + public IndexLookupKey(byte[] data) + { + super(data); + } +} Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexLookupKey.java ------------------------------------------------------------------------------ svn:keywords = Id Modified: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java URL: http://svn.apache.org/viewvc/incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java?rev=1220353&r1=1220352&r2=1220353&view=diff ============================================================================== --- incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java (original) +++ incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java Sun Dec 18 08:36:52 2011 @@ -1,39 +1,39 @@ -/* $Id: IndexNameKey.java 1207727 2011-11-29 01:12:13Z kwright $ */ - -/** -* Licensed to the Apache Software Foundation (ASF) under one or more -* contributor license agreements. See the NOTICE file distributed with -* this work for additional information regarding copyright ownership. -* The ASF licenses this file to You under the Apache License, Version 2.0 -* (the "License"); you may not use this file except in compliance with -* the License. You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package org.apache.warthog.keyvaluetablestore; - -import org.apache.warthog.api.*; -import org.apache.warthog.transactionalkeyvaluestore.*; -import org.apache.warthog.common.*; - -/** Key class for accessing index name given ID */ -public class IndexNameKey extends LongKey -{ - /** Constructor */ - public IndexNameKey(long indexID) - { - super(indexID); - } - - public IndexNameKey(byte[] data) - { - super(data); - } -} +/* $Id$ */ + +/** +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You under the Apache License, Version 2.0 +* (the "License"); you may not use this file except in compliance with +* the License. You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package org.apache.warthog.keyvaluetablestore; + +import org.apache.warthog.api.*; +import org.apache.warthog.transactionalkeyvaluestore.*; +import org.apache.warthog.common.*; + +/** Key class for accessing index name given ID */ +public class IndexNameKey extends LongKey +{ + /** Constructor */ + public IndexNameKey(long indexID) + { + super(indexID); + } + + public IndexNameKey(byte[] data) + { + super(data); + } +} Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: incubator/lcf/branches/CONNECTORS-286/warthog-reimport/src/main/java/org/apache/warthog/keyvaluetablestore/IndexNameKey.java ------------------------------------------------------------------------------ svn:keywords = Id