int linkNode(int index, int lastLookup) {

        // get the first reclaimed slot
        int lookup = reclaimedNodePointer;

        // A VoltDB extension to diagnose ArrayOutOfBounds.
        boolean voltDBreclaimed = (reclaimedNodePointer != -1);
        // Keep a history of events, wrapping to the start of the buffer when capacity runs out
        // so the most recent events are never lost.
        voltDBhistory[voltDBhistoryDepth++ % voltDBhistoryCapacity] = index;
        // End of VoltDB extension
        if (lookup == -1) {
            lookup = newNodePointer++;
        } else {

            // reset the first reclaimed slot
            reclaimedNodePointer = linkTable[lookup];
        }

        // link the node
        if (lastLookup == -1) {
            hashTable[index] = lookup;
        } else {
            linkTable[lastLookup] = lookup;
        }

        // A VoltDB extension to diagnose ArrayOutOfBounds.
        if (lookup >= linkTable.length) {
            StringBuilder report = new StringBuilder();
            report.append("linkTable size is ").append(linkTable.length);
            report.append(voltDBreclaimed ? " reclaimed" : " new").append(" index is ").append(lookup);
            report.append(" linkTable content is [");
            for (int link : linkTable) {
                report.append(link).append(", ");
            }
            report.append("]\n");
            report.append(" hashTable content is [");
            for (int look : hashTable) {
                report.append(look).append(", ");
            }
            report.append("]\n");
            report.append(" history is [");
            int depth = 0;
            for (int look : voltDBhistory) {
                ++depth;
                if (depth == (voltDBhistoryDepth % voltDBhistoryCapacity)) {
                    report.append(" /* <- history ends here and/or starts here -> */ ");
                }
                if (look < 0) {
                    report.append(-(look+1)).append(" unlnkd, ");
                } else if (look > 1000000) {
                    report.append(look-1000000).append(" rmdlkp, ");
                } else {
                    report.append(look).append(" linked, ");
                }
            }
            report.append("]\n");
            report.append(" lost history length is ").append(voltDBhistoryDepth / voltDBhistoryCapacity * voltDBhistoryCapacity);
            report.append("next reclaimedPointer is ").append(reclaimedNodePointer);
            report.append(" next newNodePointer is ").append(newNodePointer);
            report.append(" last reset was #").append(voltDBresetCount).append(" after event ").append(voltDBlastResetEvent);
            report.append(" from ").append(voltDBresetCapacity);
            report.append(" last clear was #").append(voltDBclearCount).append(" after event ").append(voltDBlastClearEvent);
            report.append(" from ").append(voltDBclearCapacity);
            throw new ArrayIndexOutOfBoundsException(report.toString());
        }
        // End of VoltDB extension
        linkTable[lookup] = -1;

        elementCount++;

        modified = true;

        return lookup;
    }
int linkNode ( int index , int lastLookup ) { int lookup = reclaimedNodePointer ; boolean voltDBreclaimed = ( reclaimedNodePointer != - 1 ) ; voltDBhistory [ voltDBhistoryDepth ++ % voltDBhistoryCapacity ] = index ; if ( lookup == - 1 ) { lookup = newNodePointer ++ ; } else { reclaimedNodePointer = linkTable [ lookup ] ; } if ( lastLookup == - 1 ) { hashTable [ index ] = lookup ; } else { linkTable [ lastLookup ] = lookup ; } if ( lookup >= linkTable . length ) { StringBuilder report = new StringBuilder ( ) ; report . append ( "linkTable size is " ) . append ( linkTable . length ) ; report . append ( voltDBreclaimed ? " reclaimed" : " new" ) . append ( " index is " ) . append ( lookup ) ; report . append ( " linkTable content is [" ) ; for ( int link : linkTable ) { report . append ( link ) . append ( ", " ) ; } report . append ( "]\n" ) ; report . append ( " hashTable content is [" ) ; for ( int look : hashTable ) { report . append ( look ) . append ( ", " ) ; } report . append ( "]\n" ) ; report . append ( " history is [" ) ; int depth = 0 ; for ( int look : voltDBhistory ) { ++ depth ; if ( depth == ( voltDBhistoryDepth % voltDBhistoryCapacity ) ) { report . append ( " /* <- history ends here and/or starts here -> */ " ) ; } if ( look < 0 ) { report . append ( - ( look + 1 ) ) . append ( " unlnkd, " ) ; } else if ( look > 1000000 ) { report . append ( look - 1000000 ) . append ( " rmdlkp, " ) ; } else { report . append ( look ) . append ( " linked, " ) ; } } report . append ( "]\n" ) ; report . append ( " lost history length is " ) . append ( voltDBhistoryDepth / voltDBhistoryCapacity * voltDBhistoryCapacity ) ; report . append ( "next reclaimedPointer is " ) . append ( reclaimedNodePointer ) ; report . append ( " next newNodePointer is " ) . append ( newNodePointer ) ; report . append ( " last reset was #" ) . append ( voltDBresetCount ) . append ( " after event " ) . append ( voltDBlastResetEvent ) ; report . append ( " from " ) . append ( voltDBresetCapacity ) ; report . append ( " last clear was #" ) . append ( voltDBclearCount ) . append ( " after event " ) . append ( voltDBlastClearEvent ) ; report . append ( " from " ) . append ( voltDBclearCapacity ) ; throw new ArrayIndexOutOfBoundsException ( report . toString ( ) ) ; } linkTable [ lookup ] = - 1 ; elementCount ++ ; modified = true ; return lookup ; }
Link a new node to the end of the linked for a hash index.

@param index an index into hashTable
@param lastLookup either -1 or the node to which the new node will be linked
@return the new node