Top Description Inners Fields Constructors Methods
org.apache.derby.iapi.store.access

public Class BackingStoreHashtable

extends Object
Class Inheritance
Known Direct Subclasses
org.apache.derby.impl.store.access.BackingStoreHashTableFromScan
Imports
org.apache.derby.shared.common.error.StandardException, org.apache.derby.iapi.types.DataValueDescriptor, .LocatedRow, .RowLocation, org.apache.derby.iapi.services.cache.ClassSize, org.apache.derby.shared.common.sanity.SanityManager, java.util.ArrayList, .Collections, .Enumeration, .HashMap, .Iterator, .List, .Properties, .NoSuchElementException

A BackingStoreHashtable is a utility class which will store a set of rows into an in memory hash table, or overflow the hash table to a tempory on disk structure.

All rows must contain the same number of columns, and the column at position N of all the rows must have the same format id. If the BackingStoreHashtable needs to be overflowed to disk, then an arbitrary row will be chosen and used as a template for creating the underlying overflow container.

The hash table will be built logically as follows (actual implementation may differ). The important points are that the hash value is the standard java hash value on the row[key_column_numbers[0], if key_column_numbers.length is 1, or row[key_column_numbers[0, 1, ...]] if key_column_numbers.length > 1, and that duplicate detection is done by the standard java duplicate detection provided by java.util.Hashtable.

import java.util.Hashtable;

hash_table = new Hashtable();

Object row; // is a DataValueDescriptor[] or a LocatedRow

boolean  needsToClone = rowSource.needsToClone();

while((row = rowSource.getNextRowFromRowSource()) != null)
{
    if (needsToClone)
        row = clone_row_from_row(row);

    Object key = KeyHasher.buildHashKey(row, key_column_numbers);

    if ((duplicate_value = 
        hash_table.put(key, row)) != null)
    {
        Vector row_vec;

        // inserted a duplicate
        if ((duplicate_value instanceof vector))
        {
            row_vec = (Vector) duplicate_value;
        }
        else
        {
            // allocate vector to hold duplicates
            row_vec = new Vector(2);

            // insert original row into vector
            row_vec.addElement(duplicate_value);

            // put the vector as the data rather than the row
            hash_table.put(key, row_vec);
        }

        // insert new row into vector
        row_vec.addElement(row);
    }
}

What actually goes into the hash table is a little complicated. That is because the row may either be an array of column values (i.e. DataValueDescriptor[]) or a LocatedRow (i.e., a structure holding the columns plus a RowLocation). In addition, the hash value itself may either be one of these rows or (in the case of multiple rows which hash to the same value) a bucket (List) of rows. To sum this up, the values in a hash table which does not spill to disk may be the following:

If rows spill to disk, then they just become arrays of columns. In this case, a LocatedRow becomes a DataValueDescriptor[], where the last cell contains the RowLocation.

Nested and Inner Type Summary

Modifier and TypeClass and Description
private class
private static class
BackingStoreHashtable.RowList

List of DataValueDescriptor[] instances that represent rows.

Field Summary

Modifier and TypeField and Description
private static final int
ARRAY_LIST_SIZE

The estimated number of bytes used by ArrayList(0)

private Properties
private DiskHashtable
private HashMap<Object, Object>
private long
private boolean
private int[]
private long
private long
private boolean
private RowSource
private boolean
private TransactionController
tc

Fields of the class

Constructor Summary

AccessConstructor and Description
private
BackingStoreHashtable()

Constructors for This class:

public
BackingStoreHashtable(TransactionController
An open TransactionController to be used if the hash table needs to overflow to disk.
tc
,
RowSource
RowSource to read rows from.
row_source
,
int[]
The column numbers of the columns in the scan result row to be the key to the HashMap. "0" is the first column in the scan result row (which may be different than the first row in the table of the scan).
key_column_numbers
,
boolean
Should the HashMap automatically remove duplicates, or should it create the list of duplicates?
remove_duplicates
,
long
The estimated number of rows in the hash table. Pass in -1 if there is no estimate.
estimated_rowcnt
,
long
The maximum number of rows to insert into the inmemory Hash table before overflowing to disk. Pass in -1 if there is no maximum.
max_inmemory_rowcnt
,
int
If not "-1" used to initialize the java HashMap
initialCapacity
,
float
If not "-1" used to initialize the java HashMap
loadFactor
,
boolean
Skip rows with a null key column, if true.
skipNullKeyColumns
,
boolean
If true the hash table is kept after a commit, if false the hash table is dropped on the next commit.
keepAfterCommit
)

Create the BackingStoreHashtable from a row source.

Method Summary

Modifier and TypeMethod and Description
private void
add_row_to_hash_table(DataValueDescriptor[]
Row to add to the hash table.
columnValues
,
RowLocation
Location of row in conglomerate; could be null.
rowLocation
,
boolean
If the row needs to be cloned
needsToClone
)

Do the work to add one row to the hash table.

private static DataValueDescriptor[]

Returns:

The cloned row row to use.
cloneRow
(DataValueDescriptor[] old_row)

Return a cloned copy of the row.

public void
close()

Close the BackingStoreHashtable.

private void
doSpaceAccounting(Object hashValue, boolean firstDuplicate)

public Enumeration<Object>

Returns:

The Enumeration.
elements
()

Return an Enumeration that can be used to scan the entire table.

public Object

Returns:

The value to which the key is mapped in this hashtable; null if the key is not mapped to any value in this hashtable.
get
(Object
The key to hash on.
key
)

Get data associated with given key.

public void
getAllRuntimeStats(Properties
The set of properties to append to.
prop
)

Return runtime stats to caller by adding them to prop.

private long

Returns:

A guess as to how much memory the current hash value will use.
getEstimatedMemUsage
(Object
The object for which we want to know the memory usage.
hashValue
)

Take a value which will go into the hash table and return an estimate of how much memory that value will consume.

private DataValueDescriptor[]
getNextRowFromRowSource()

Call method to either get next row or next row with non-null key columns.

public boolean
includeRowLocations()

Return true if we should include RowLocations with the rows stored in this hash table.

private DataValueDescriptor[]
makeDiskRow(Object raw)

Make a full set of columns from an object which is either already an array of column or otherwise a LocatedRow.

private DataValueDescriptor[]
makeDiskRow(DataValueDescriptor[] columnValues, RowLocation rowLocation)

Construct a full set of columns, which may need to end with the row location.The full set of columns is what's stored on disk when we spill to disk.

private Object
makeInMemoryRow(DataValueDescriptor[] diskRow)

Make an in-memory row from an on-disk row.

private List<E>
makeInMemoryRows(List<E> diskRows)

Turn a list of disk rows into a list of in-memory rows.

public boolean

Returns:

true if row was inserted into the hash table. Returns false if the BackingStoreHashtable is eliminating duplicates, and the row being inserted is a duplicate, or if we are skipping rows with 1 or more null key columns and we find a null key column.
putRow
(boolean
does this routine have to make a copy of the row, in order to keep a reference to it after return?
needsToClone
,
DataValueDescriptor[]
The row to insert into the table.
row
,
RowLocation
Location of row in conglomerate; could be null.
rowLocation
)

Put a row into the hash table.

public Object
remove(Object
The key of the row to remove.
key
)

remove a row from the hash table.

public void
setAuxillaryRuntimeStats(Properties
The set of properties to append from.
prop
)

Set the auxillary runtime stats.

pack-priv static DataValueDescriptor[]

Returns:

The cloned row row to use.
shallowCloneRow
(DataValueDescriptor[] old_row)

Return a shallow cloned row

public int

Returns:

The number of unique rows in the hash table.
size
()

Return number of unique rows in the hash table.

private boolean

Returns:

true if the row was spilled to disk, false if not
spillToDisk
(DataValueDescriptor[]
Actual columns from source row.
columnValues
,
RowLocation
Optional row location.
rowLocation
)

Determine whether a new row should be spilled to disk and, if so, do it.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

ARRAY_LIST_SIZEback to summary
private static final int ARRAY_LIST_SIZE

The estimated number of bytes used by ArrayList(0)

auxillary_runtimestatsback to summary
private Properties auxillary_runtimestats
diskHashtableback to summary
private DiskHashtable diskHashtable
hash_tableback to summary
private HashMap<Object, Object> hash_table
inmemory_rowcntback to summary
private long inmemory_rowcnt
keepAfterCommitback to summary
private boolean keepAfterCommit
key_column_numbersback to summary
private int[] key_column_numbers
max_inmemory_rowcntback to summary
private long max_inmemory_rowcnt
max_inmemory_sizeback to summary
private long max_inmemory_size
remove_duplicatesback to summary
private boolean remove_duplicates
row_sourceback to summary
private RowSource row_source
skipNullKeyColumnsback to summary
private boolean skipNullKeyColumns
tcback to summary
private TransactionController tc

Fields of the class

Constructor Detail

BackingStoreHashtableback to summary
private BackingStoreHashtable()

Constructors for This class:

BackingStoreHashtableback to summary
public BackingStoreHashtable(TransactionController tc, RowSource row_source, int[] key_column_numbers, boolean remove_duplicates, long estimated_rowcnt, long max_inmemory_rowcnt, int initialCapacity, float loadFactor, boolean skipNullKeyColumns, boolean keepAfterCommit) throws StandardException

Create the BackingStoreHashtable from a row source.

This routine drains the RowSource. The performance characteristics depends on the number of rows inserted and the parameters to the constructor. RowLocations are supported iff row_source is null. RowLocations in a non-null row_source can be added later if there is a use-case that stresses this behavior.

If the number of rows is <= "max_inmemory_rowcnt", then the rows are inserted into a java.util.HashMap. In this case no TransactionController is necessary, a "null" tc is valid.

If the number of rows is > "max_inmemory_rowcnt", then the rows will be all placed in some sort of Access temporary file on disk. This case requires a valid TransactionController.

Parameters
tc:TransactionController

An open TransactionController to be used if the hash table needs to overflow to disk.

row_source:RowSource

RowSource to read rows from.

key_column_numbers:int[]

The column numbers of the columns in the scan result row to be the key to the HashMap. "0" is the first column in the scan result row (which may be different than the first row in the table of the scan).

remove_duplicates:boolean

Should the HashMap automatically remove duplicates, or should it create the list of duplicates?

estimated_rowcnt:long

The estimated number of rows in the hash table. Pass in -1 if there is no estimate.

max_inmemory_rowcnt:long

The maximum number of rows to insert into the inmemory Hash table before overflowing to disk. Pass in -1 if there is no maximum.

initialCapacity:int

If not "-1" used to initialize the java HashMap

loadFactor:float

If not "-1" used to initialize the java HashMap

skipNullKeyColumns:boolean

Skip rows with a null key column, if true.

keepAfterCommit:boolean

If true the hash table is kept after a commit, if false the hash table is dropped on the next commit.

Exceptions
StandardException:
Standard exception policy.

Method Detail

add_row_to_hash_tableback to summary
private void add_row_to_hash_table(DataValueDescriptor[] columnValues, RowLocation rowLocation, boolean needsToClone) throws StandardException

Do the work to add one row to the hash table.

Parameters
columnValues:DataValueDescriptor[]

Row to add to the hash table.

rowLocation:RowLocation

Location of row in conglomerate; could be null.

needsToClone:boolean

If the row needs to be cloned

Exceptions
StandardException:
Standard exception policy.
cloneRowback to summary
private static DataValueDescriptor[] cloneRow(DataValueDescriptor[] old_row) throws StandardException

Return a cloned copy of the row.

Returns:DataValueDescriptor[]

The cloned row row to use.

Exceptions
StandardException:
Standard exception policy.
closeback to summary
public void close() throws StandardException

Close the BackingStoreHashtable.

Perform any necessary cleanup after finishing with the hashtable. Will deallocate/dereference objects as necessary. If the table has gone to disk this will drop any on disk files used to support the hash table.

Exceptions
StandardException:
Standard exception policy.
doSpaceAccountingback to summary
private void doSpaceAccounting(Object hashValue, boolean firstDuplicate)
elementsback to summary
public Enumeration<Object> elements() throws StandardException

Return an Enumeration that can be used to scan the entire table. The objects in the Enumeration can be either of the following:

  • a row - This is a single row with a unique hash key.
  • or a bucket of rows - This is a list of rows which all have the same hash key.

The situation is a little more complicated because the row representation is different depending on whether the row includes a RowLocation. If includeRowLocations()== true, then the row is a LocatedRow. Otherwise, the row is an array of DataValueDescriptor. Putting all of this together, if the row contains a RowLocation, then the objects in the Enumeration returned by this method can be either of the following:

  • a LocatedRow
  • or a List<LocatedRow>

But if the row does not contain a RowLocation, then the objects in the Enumeration returned by this method can be either of the following:

  • a DataValueDescriptor[]
  • or a List<DataValueDescriptor[]>

RESOLVE - is it worth it to support this routine when we have a disk overflow hash table?

Returns:Enumeration<Object>

The Enumeration.

Exceptions
StandardException:
Standard exception policy.
getback to summary
public Object get(Object key) throws StandardException

Get data associated with given key.

There are 2 different types of objects returned from this routine.

In both cases, the key value is either the object stored in row[key_column_numbers[0]], if key_column_numbers.length is 1, otherwise it is a KeyHasher containing the objects stored in row[key_column_numbers[0, 1, ...]]. For every qualifying unique row value an entry is placed into the hash table.

For row values with duplicates, the value of the data is a list of rows.

The situation is a little more complicated because the row representation is different depending on whether the row includes a RowLocation. If includeRowLocations() == true, then the row is a LocatedRow. Otherwise, the row is an array of DataValueDescriptor. Putting all of this together, if the row contains a RowLocation, then the objects returned by this method can be either of the following:

  • a LocatedRow
  • or a List<LocatedRow>

But if the row does not contain a RowLocation, then the objects returned by this method can be either of the following:

  • a DataValueDescriptor[]
  • or a List<DataValueDescriptor[]>

The caller will have to call "instanceof" on the data value object if duplicates are expected, to determine if the data value of the hash table entry is a row or is a list of rows.

See the javadoc for elements() for more information on the objects returned by this method.

The BackingStoreHashtable "owns" the objects returned from the get() routine. They remain valid until the next access to the BackingStoreHashtable. If the client needs to keep references to these objects, it should clone copies of the objects. A valid BackingStoreHashtable can place all rows into a disk based conglomerate, declare a row buffer and then reuse that row buffer for every get() call.

Parameters
key:Object

The key to hash on.

Returns:Object

The value to which the key is mapped in this hashtable; null if the key is not mapped to any value in this hashtable.

Exceptions
StandardException:
Standard exception policy.
getAllRuntimeStatsback to summary
public void getAllRuntimeStats(Properties prop) throws StandardException

Return runtime stats to caller by adding them to prop.

Parameters
prop:Properties

The set of properties to append to.

Exceptions
StandardException:
Standard exception policy.
getEstimatedMemUsageback to summary
private long getEstimatedMemUsage(Object hashValue)

Take a value which will go into the hash table and return an estimate of how much memory that value will consume. The hash value could be either an array of columns or a LocatedRow.

Parameters
hashValue:Object

The object for which we want to know the memory usage.

Returns:long

A guess as to how much memory the current hash value will use.

getNextRowFromRowSourceback to summary
private DataValueDescriptor[] getNextRowFromRowSource() throws StandardException

Call method to either get next row or next row with non-null key columns. Currently, RowLocation information is not included in rows siphoned out of a RowSource. That functionality is only supported if the rows come from the scan of a base table.

Exceptions
StandardException:
Standard exception policy.
includeRowLocationsback to summary
public boolean includeRowLocations()

Return true if we should include RowLocations with the rows stored in this hash table.

makeDiskRowback to summary
private DataValueDescriptor[] makeDiskRow(Object raw)

Make a full set of columns from an object which is either already an array of column or otherwise a LocatedRow. The full set of columns is what's stored on disk when we spill to disk. This is the inverse of makeInMemoryRow().

makeDiskRowback to summary
private DataValueDescriptor[] makeDiskRow(DataValueDescriptor[] columnValues, RowLocation rowLocation)

Construct a full set of columns, which may need to end with the row location.The full set of columns is what's stored on disk when we spill to disk.

makeInMemoryRowback to summary
private Object makeInMemoryRow(DataValueDescriptor[] diskRow)

Make an in-memory row from an on-disk row. This is the inverse of makeDiskRow().

makeInMemoryRowsback to summary
private List<E> makeInMemoryRows(List<E> diskRows)

Turn a list of disk rows into a list of in-memory rows. The on disk rows are always of type DataValueDescriptor[]. But the in-memory rows could be of type LocatedRow.

putRowback to summary
public boolean putRow(boolean needsToClone, DataValueDescriptor[] row, RowLocation rowLocation) throws StandardException

Put a row into the hash table.

The in memory hash table will need to keep a reference to the row after the put call has returned. If "needsToClone" is true then the hash table will make a copy of the row and put that, else if "needsToClone" is false then the hash table will keep a reference to the row passed in and no copy will be made.

If routine returns false, then no reference is kept to the duplicate row which was rejected (thus allowing caller to reuse the object).

Parameters
needsToClone:boolean

does this routine have to make a copy of the row, in order to keep a reference to it after return?

row:DataValueDescriptor[]

The row to insert into the table.

rowLocation:RowLocation

Location of row in conglomerate; could be null.

Returns:boolean

true if row was inserted into the hash table. Returns false if the BackingStoreHashtable is eliminating duplicates, and the row being inserted is a duplicate, or if we are skipping rows with 1 or more null key columns and we find a null key column.

Exceptions
StandardException:
Standard exception policy.
removeback to summary
public Object remove(Object key) throws StandardException

remove a row from the hash table.

a remove of a duplicate removes the entire duplicate list.

Parameters
key:Object

The key of the row to remove.

Exceptions
StandardException:
Standard exception policy.
setAuxillaryRuntimeStatsback to summary
public void setAuxillaryRuntimeStats(Properties prop) throws StandardException

Set the auxillary runtime stats.

getRuntimeStats() will return both the auxillary stats and any BackingStoreHashtable() specific stats. Note that each call to setAuxillaryRuntimeStats() overwrites the Property set that was set previously.

Parameters
prop:Properties

The set of properties to append from.

Exceptions
StandardException:
Standard exception policy.
shallowCloneRowback to summary
pack-priv static DataValueDescriptor[] shallowCloneRow(DataValueDescriptor[] old_row) throws StandardException

Return a shallow cloned row

Returns:DataValueDescriptor[]

The cloned row row to use.

Exceptions
StandardException:
Standard exception policy.
sizeback to summary
public int size() throws StandardException

Return number of unique rows in the hash table.

Returns:int

The number of unique rows in the hash table.

Exceptions
StandardException:
Standard exception policy.
spillToDiskback to summary
private boolean spillToDisk(DataValueDescriptor[] columnValues, RowLocation rowLocation) throws StandardException

Determine whether a new row should be spilled to disk and, if so, do it.

Parameters
columnValues:DataValueDescriptor[]

Actual columns from source row.

rowLocation:RowLocation

Optional row location.

Returns:boolean

true if the row was spilled to disk, false if not

Exceptions
StandardException:
Standard exception policy.
org.apache.derby.iapi.store.access back to summary

private Class BackingStoreHashtable.BackingStoreHashtableEnumeration

extends Object
implements Enumeration<Object>
Class Inheritance
  • java.lang.Object
  • org.apache.derby.iapi.store.access.BackingStoreHashtable.BackingStoreHashtableEnumeration
All Implemented Interfaces
java.util.Enumeration

Field Summary

Modifier and TypeField and Description
private Enumeration<Object>
private Iterator<Object>

Constructor Summary

AccessConstructor and Description
pack-priv

Method Summary

Modifier and TypeMethod and Description
public boolean
hasMoreElements()

Implements java.util.Enumeration.hasMoreElements.

Tests if this enumeration contains more elements.

public Object
nextElement()

Implements java.util.Enumeration.nextElement.

Returns the next element of this enumeration if this enumeration object has at least one more element to provide.

Inherited from java.lang.Object:
cloneequalsfinalizegetClasshashCodenotifynotifyAlltoStringwaitwaitwait

Field Detail

diskEnumerationback to summary
private Enumeration<Object> diskEnumeration
memoryIteratorback to summary
private Iterator<Object> memoryIterator

Constructor Detail

BackingStoreHashtableEnumerationback to summary
pack-priv BackingStoreHashtableEnumeration()

Method Detail

hasMoreElementsback to summary
public boolean hasMoreElements()

Implements java.util.Enumeration.hasMoreElements.

Doc from java.util.Enumeration.hasMoreElements.

Tests if this enumeration contains more elements.

Returns:boolean

true if and only if this enumeration object contains at least one more element to provide; false otherwise.

nextElementback to summary
public Object nextElement() throws NoSuchElementException

Implements java.util.Enumeration.nextElement.

Doc from java.util.Enumeration.nextElement.

Returns the next element of this enumeration if this enumeration object has at least one more element to provide.

Returns:Object

the next element of this enumeration.

Exceptions
NoSuchElementException:
if no more elements exist.
org.apache.derby.iapi.store.access back to summary

private Class BackingStoreHashtable.RowList

extends ArrayList<Object>
Class Inheritance

List of DataValueDescriptor[] instances that represent rows. This class is used when the hash table contains multiple rows for the same hash key.

Constructor Summary

AccessConstructor and Description
private
RowList(int initialCapacity)

Method Summary

Inherited from java.util.ArrayList:
addaddaddAlladdAlladdFirstaddLastclearclonecontainsensureCapacityequalsforEachgetgetFirstgetLasthashCodeindexOfisEmptyiteratorlastIndexOflistIteratorlistIteratorremoveremoveremoveAllremoveFirstremoveIfremoveLastremoveRangereplaceAllretainAllsetsizesortspliteratorsubListtoArraytoArraytrimToSize

Constructor Detail

RowListback to summary
private RowList(int initialCapacity)