mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Preliminary pass at reverse index table iteration
This commit is contained in:
parent
c4bbff8195
commit
9d08754877
10 changed files with 521 additions and 467 deletions
|
@ -1,6 +1,5 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -22,15 +21,13 @@ import java.util.NoSuchElementException;
|
|||
|
||||
public class FieldIndexTable extends IndexTable {
|
||||
|
||||
private static final Class<?>[] fieldClasses = {
|
||||
};
|
||||
|
||||
private static final String[] fieldNames = {
|
||||
};
|
||||
|
||||
private static final Class<?>[] fieldClasses = {};
|
||||
|
||||
private static final String[] fieldNames = {};
|
||||
|
||||
private final Schema indexSchema;
|
||||
private final int indexColumn;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new secondary index which is based upon a specific field within the
|
||||
* primary table specified by name.
|
||||
|
@ -40,14 +37,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException
|
||||
*/
|
||||
FieldIndexTable(Table primaryTable, int colIndex) throws IOException {
|
||||
this(primaryTable,
|
||||
primaryTable.getDBHandle().getMasterTable().createTableRecord(
|
||||
primaryTable.getName(),
|
||||
getIndexTableSchema(primaryTable, colIndex),
|
||||
colIndex)
|
||||
);
|
||||
this(primaryTable, primaryTable.getDBHandle().getMasterTable().createTableRecord(
|
||||
primaryTable.getName(), getIndexTableSchema(primaryTable, colIndex), colIndex));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a new or existing secondary index. An existing index must have
|
||||
* its' root ID specified within the tableRecord.
|
||||
|
@ -60,23 +53,23 @@ public class FieldIndexTable extends IndexTable {
|
|||
this.indexSchema = indexTable.getSchema();
|
||||
this.indexColumn = indexTableRecord.getIndexedColumn();
|
||||
}
|
||||
|
||||
|
||||
private static Schema getIndexTableSchema(Table primaryTable, int colIndex) {
|
||||
byte fieldType = primaryTable.getSchema().getField(colIndex).getFieldType();
|
||||
IndexField indexKeyField = IndexField.getIndexField(fieldType);
|
||||
return new Schema(0, indexKeyField.getClass(), "IndexKey", fieldClasses, fieldNames);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @see ghidra.framework.store.db.IndexTable#findPrimaryKeys(ghidra.framework.store.db.Field)
|
||||
*/
|
||||
@Override
|
||||
long[] findPrimaryKeys(Field indexValue) throws IOException {
|
||||
long[] findPrimaryKeys(Field indexValue) throws IOException {
|
||||
IndexField indexField = IndexField.getIndexField(indexValue, Long.MIN_VALUE);
|
||||
DBFieldIterator iter = indexTable.fieldKeyIterator(indexField);
|
||||
ArrayList<IndexField> list = new ArrayList<IndexField>(20);
|
||||
ArrayList<IndexField> list = new ArrayList<>(20);
|
||||
while (iter.hasNext()) {
|
||||
IndexField f = (IndexField)iter.next();
|
||||
IndexField f = (IndexField) iter.next();
|
||||
if (!f.hasSameIndex(indexField)) {
|
||||
break;
|
||||
}
|
||||
|
@ -102,7 +95,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#getKeyCount(ghidra.framework.store.db.Field)
|
||||
*/
|
||||
@Override
|
||||
int getKeyCount(Field indexValue) throws IOException {
|
||||
int getKeyCount(Field indexValue) throws IOException {
|
||||
return findPrimaryKeys(indexValue).length;
|
||||
}
|
||||
|
||||
|
@ -110,7 +103,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#addEntry(ghidra.framework.store.db.Record)
|
||||
*/
|
||||
@Override
|
||||
void addEntry(Record record) throws IOException {
|
||||
void addEntry(Record record) throws IOException {
|
||||
Field indexedField = record.getField(colIndex);
|
||||
IndexField f = IndexField.getIndexField(indexedField, record.getKey());
|
||||
Record rec = indexSchema.createRecord(f);
|
||||
|
@ -121,7 +114,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#deleteEntry(ghidra.framework.store.db.Record)
|
||||
*/
|
||||
@Override
|
||||
void deleteEntry(Record record) throws IOException {
|
||||
void deleteEntry(Record record) throws IOException {
|
||||
Field indexedField = record.getField(colIndex);
|
||||
IndexField f = IndexField.getIndexField(indexedField, record.getKey());
|
||||
indexTable.deleteRecord(f);
|
||||
|
@ -131,7 +124,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#indexIterator()
|
||||
*/
|
||||
@Override
|
||||
DBFieldIterator indexIterator() throws IOException {
|
||||
DBFieldIterator indexIterator() throws IOException {
|
||||
return new IndexFieldIterator();
|
||||
}
|
||||
|
||||
|
@ -139,25 +132,26 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#indexIterator(ghidra.framework.store.db.Field, ghidra.framework.store.db.Field, boolean)
|
||||
*/
|
||||
@Override
|
||||
DBFieldIterator indexIterator(Field minField, Field maxField, boolean atMin)
|
||||
throws IOException {
|
||||
return new IndexFieldIterator(minField, maxField, atMin);
|
||||
DBFieldIterator indexIterator(Field minField, Field maxField, boolean before)
|
||||
throws IOException {
|
||||
return new IndexFieldIterator(minField, maxField, before);
|
||||
}
|
||||
|
||||
/*
|
||||
* @see db.IndexTable#indexIterator(db.Field, db.Field, db.Field, boolean)
|
||||
*/
|
||||
@Override
|
||||
DBFieldIterator indexIterator(Field minField, Field maxField, Field startField, boolean before) throws IOException {
|
||||
DBFieldIterator indexIterator(Field minField, Field maxField, Field startField, boolean before)
|
||||
throws IOException {
|
||||
return new IndexFieldIterator(minField, maxField, startField, before);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterates over index field values within a specified range.
|
||||
* NOTE: Index fields which have been truncated may be returned out of order.
|
||||
*/
|
||||
class IndexFieldIterator implements DBFieldIterator {
|
||||
|
||||
|
||||
private IndexField min;
|
||||
private IndexField max;
|
||||
private IndexField lastKey;
|
||||
|
@ -165,52 +159,56 @@ public class FieldIndexTable extends IndexTable {
|
|||
private DBFieldIterator indexIterator;
|
||||
private boolean hasNext = false;
|
||||
private boolean hasPrev = false;
|
||||
|
||||
|
||||
/**
|
||||
* Construct an index field iterator starting with the minimum index value.
|
||||
*/
|
||||
IndexFieldIterator() throws IOException {
|
||||
this(null, null, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct an index field iterator. The iterator is positioned at index
|
||||
* value identified by startValue.
|
||||
* @param minValue minimum index value or null if no minimum
|
||||
* @param maxValue maximum index value or null if no maximum
|
||||
* @param atMin if true initial position is before minValue, else position
|
||||
* @param before if true initial position is before minValue, else position
|
||||
* after maxValue
|
||||
* @throws IOException
|
||||
*/
|
||||
IndexFieldIterator(Field minValue, Field maxValue, boolean atMin) throws IOException {
|
||||
|
||||
IndexFieldIterator(Field minValue, Field maxValue, boolean before) throws IOException {
|
||||
|
||||
if (primaryTable.getSchema().getField(indexColumn).isVariableLength()) {
|
||||
throw new UnsupportedOperationException("Due to potential truncation issues, operation not permitted on variable length fields");
|
||||
throw new UnsupportedOperationException(
|
||||
"Due to potential truncation issues, operation not permitted on variable length fields");
|
||||
}
|
||||
|
||||
min = minValue != null ?
|
||||
IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ?
|
||||
IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
|
||||
|
||||
min = minValue != null ? IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ? IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
|
||||
IndexField start = null;
|
||||
if (atMin && minValue != null) {
|
||||
if (before && minValue != null) {
|
||||
start = min;
|
||||
}
|
||||
else if (!atMin && maxValue != null){
|
||||
else if (!before && maxValue != null) {
|
||||
start = max;
|
||||
}
|
||||
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max, start);
|
||||
|
||||
|
||||
if (start != null) {
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max, start);
|
||||
}
|
||||
else {
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max, before);
|
||||
}
|
||||
|
||||
if (indexIterator.hasNext()) {
|
||||
indexIterator.next();
|
||||
if (atMin) {
|
||||
if (before) {
|
||||
indexIterator.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param minField
|
||||
* @param maxField
|
||||
|
@ -218,32 +216,34 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @param before
|
||||
* @throws IOException
|
||||
*/
|
||||
public IndexFieldIterator(Field minValue, Field maxValue, Field startValue, boolean before) throws IOException {
|
||||
|
||||
public IndexFieldIterator(Field minValue, Field maxValue, Field startValue, boolean before)
|
||||
throws IOException {
|
||||
|
||||
if (primaryTable.getSchema().getField(indexColumn).isVariableLength()) {
|
||||
throw new UnsupportedOperationException("Due to potential truncation issues, operation not permitted on variable length fields");
|
||||
throw new UnsupportedOperationException(
|
||||
"Due to potential truncation issues, operation not permitted on variable length fields");
|
||||
}
|
||||
|
||||
|
||||
if (startValue == null) {
|
||||
throw new IllegalArgumentException("starting index value required");
|
||||
}
|
||||
min = minValue != null ?
|
||||
IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ?
|
||||
IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
|
||||
IndexField start = IndexField.getIndexField(startValue, before ? Long.MIN_VALUE : Long.MAX_VALUE);
|
||||
min = minValue != null ? IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ? IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
|
||||
IndexField start =
|
||||
IndexField.getIndexField(startValue, before ? Long.MIN_VALUE : Long.MAX_VALUE);
|
||||
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max, start);
|
||||
|
||||
|
||||
if (indexIterator.hasNext()) {
|
||||
IndexField f = (IndexField)indexIterator.next();
|
||||
IndexField f = (IndexField) indexIterator.next();
|
||||
if (before || !f.getIndexField().equals(startValue)) {
|
||||
indexIterator.previous();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNext() throws IOException {
|
||||
if (hasNext)
|
||||
return true;
|
||||
|
@ -253,7 +253,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
while (indexKey != null && indexKey.hasSameIndex(lastKey)) {
|
||||
if (++skipCnt > 10) {
|
||||
// Reinit iterator to skip large number of same index value
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max,
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max,
|
||||
IndexField.getIndexField(indexKey.getIndexField(), Long.MAX_VALUE));
|
||||
skipCnt = 0;
|
||||
}
|
||||
|
@ -267,6 +267,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPrevious() throws IOException {
|
||||
if (hasPrev)
|
||||
return true;
|
||||
|
@ -276,7 +277,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
while (indexKey != null && indexKey.hasSameIndex(lastKey)) {
|
||||
if (++skipCnt > 10) {
|
||||
// Reinit iterator to skip large number of same index value
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max,
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max,
|
||||
IndexField.getIndexField(indexKey.getIndexField(), Long.MIN_VALUE));
|
||||
skipCnt = 0;
|
||||
}
|
||||
|
@ -290,6 +291,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Field next() throws IOException {
|
||||
if (hasNext || hasNext()) {
|
||||
hasNext = false;
|
||||
|
@ -300,7 +302,8 @@ public class FieldIndexTable extends IndexTable {
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Field previous() throws IOException {
|
||||
if (hasPrev || hasPrevious()) {
|
||||
hasNext = true;
|
||||
|
@ -317,6 +320,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* index value (lastKey).
|
||||
* @see db.DBFieldIterator#delete()
|
||||
*/
|
||||
@Override
|
||||
public boolean delete() throws IOException {
|
||||
if (lastKey == null)
|
||||
return false;
|
||||
|
@ -335,7 +339,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @see ghidra.framework.store.db.IndexTable#hasRecord(ghidra.framework.store.db.Field)
|
||||
*/
|
||||
@Override
|
||||
boolean hasRecord(Field field) throws IOException {
|
||||
boolean hasRecord(Field field) throws IOException {
|
||||
IndexField indexField = IndexField.getIndexField(field, Long.MIN_VALUE);
|
||||
DBFieldIterator iter = indexTable.fieldKeyIterator(indexField);
|
||||
while (iter.hasNext()) {
|
||||
|
@ -362,10 +366,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIterator() throws IOException {
|
||||
return new PrimaryKeyIterator();
|
||||
DBLongIterator keyIterator() throws IOException {
|
||||
return new PrimaryKeyIterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all primary keys sorted based upon the associated index key.
|
||||
* The iterator is initially positioned before the first index buffer whose index key
|
||||
|
@ -375,10 +379,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIteratorBefore(Field startField) throws IOException {
|
||||
return new PrimaryKeyIterator(startField, false);
|
||||
DBLongIterator keyIteratorBefore(Field startField) throws IOException {
|
||||
return new PrimaryKeyIterator(startField, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all primary keys sorted based upon the associated index key.
|
||||
* The iterator is initially positioned after the index buffer whose index key
|
||||
|
@ -389,10 +393,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIteratorAfter(Field startField) throws IOException {
|
||||
return new PrimaryKeyIterator(startField, true);
|
||||
DBLongIterator keyIteratorAfter(Field startField) throws IOException {
|
||||
return new PrimaryKeyIterator(startField, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all primary keys sorted based upon the associated index key.
|
||||
* The iterator is initially positioned before the primaryKey within the index buffer
|
||||
|
@ -404,10 +408,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIteratorBefore(Field startField, long primaryKey) throws IOException {
|
||||
return new PrimaryKeyIterator(null, null, startField, primaryKey, false);
|
||||
DBLongIterator keyIteratorBefore(Field startField, long primaryKey) throws IOException {
|
||||
return new PrimaryKeyIterator(null, null, startField, primaryKey, false);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all primary keys sorted based upon the associated index key.
|
||||
* The iterator is initially positioned after the primaryKey within the index buffer
|
||||
|
@ -419,10 +423,10 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIteratorAfter(Field startField, long primaryKey) throws IOException {
|
||||
return new PrimaryKeyIterator(null, null, startField, primaryKey, true);
|
||||
DBLongIterator keyIteratorAfter(Field startField, long primaryKey) throws IOException {
|
||||
return new PrimaryKeyIterator(null, null, startField, primaryKey, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterate over all primary keys sorted based upon the associated index key.
|
||||
* The iterator is limited to range of index keys of startField through endField, inclusive.
|
||||
|
@ -438,20 +442,22 @@ public class FieldIndexTable extends IndexTable {
|
|||
* @throws IOException thrown if IO error occurs
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIterator(Field startField, Field endField, boolean atStart) throws IOException {
|
||||
return new PrimaryKeyIterator(startField, endField, atStart ? startField : endField,
|
||||
atStart ? Long.MIN_VALUE : Long.MAX_VALUE, !atStart);
|
||||
DBLongIterator keyIterator(Field startField, Field endField, boolean atStart)
|
||||
throws IOException {
|
||||
return new PrimaryKeyIterator(startField, endField, atStart ? startField : endField,
|
||||
atStart ? Long.MIN_VALUE : Long.MAX_VALUE, !atStart);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see db.IndexTable#keyIterator(db.Field, db.Field, db.Field, boolean)
|
||||
*/
|
||||
@Override
|
||||
DBLongIterator keyIterator(Field minField, Field maxField, Field startField, boolean before) throws IOException {
|
||||
return new PrimaryKeyIterator(minField, maxField, startField,
|
||||
before ? Long.MIN_VALUE : Long.MAX_VALUE, !before);
|
||||
DBLongIterator keyIterator(Field minField, Field maxField, Field startField, boolean before)
|
||||
throws IOException {
|
||||
return new PrimaryKeyIterator(minField, maxField, startField,
|
||||
before ? Long.MIN_VALUE : Long.MAX_VALUE, !before);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iterates over primary keys which correspond to index field values within a specified range.
|
||||
* NOTE: Primary keys corresponding to index fields which have been truncated may be returned out of order.
|
||||
|
@ -461,19 +467,19 @@ public class FieldIndexTable extends IndexTable {
|
|||
private IndexField min;
|
||||
private IndexField max;
|
||||
private DBFieldIterator indexIterator;
|
||||
|
||||
|
||||
private boolean hasNext = false;
|
||||
private boolean hasPrev = false;
|
||||
private IndexField key;
|
||||
private IndexField lastKey;
|
||||
|
||||
|
||||
/**
|
||||
* Construct a key iterator starting with the minimum secondary key.
|
||||
*/
|
||||
PrimaryKeyIterator() throws IOException {
|
||||
indexIterator = indexTable.fieldKeyIterator();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a key iterator. The iterator is positioned immediately before
|
||||
* the key associated with the first occurance of the startValue.
|
||||
|
@ -484,7 +490,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
PrimaryKeyIterator(Field startValue, boolean after) throws IOException {
|
||||
this(null, null, startValue, after ? Long.MAX_VALUE : Long.MIN_VALUE, after);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Construct a key iterator. The iterator is positioned immediately before
|
||||
* or after the key associated with the specified startValue/primaryKey.
|
||||
|
@ -497,18 +503,15 @@ public class FieldIndexTable extends IndexTable {
|
|||
* otherwise immediately before.
|
||||
* @throws IOException
|
||||
*/
|
||||
PrimaryKeyIterator(Field minValue, Field maxValue, Field startValue,
|
||||
long primaryKey, boolean after) throws IOException
|
||||
{
|
||||
min = minValue != null ?
|
||||
IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ?
|
||||
IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
IndexField start = startValue != null ?
|
||||
IndexField.getIndexField(startValue, primaryKey) : null;
|
||||
|
||||
PrimaryKeyIterator(Field minValue, Field maxValue, Field startValue, long primaryKey,
|
||||
boolean after) throws IOException {
|
||||
min = minValue != null ? IndexField.getIndexField(minValue, Long.MIN_VALUE) : null;
|
||||
max = maxValue != null ? IndexField.getIndexField(maxValue, Long.MAX_VALUE) : null;
|
||||
IndexField start =
|
||||
startValue != null ? IndexField.getIndexField(startValue, primaryKey) : null;
|
||||
|
||||
indexIterator = indexTable.fieldKeyIterator(min, max, start);
|
||||
|
||||
|
||||
if (indexIterator.hasNext()) {
|
||||
Field f = indexIterator.next();
|
||||
if (!after || !f.equals(start)) {
|
||||
|
@ -516,7 +519,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If min or max index values was truncated, a comparison of the actual
|
||||
* indexed field value (i.e., primary table value) is done with the min and/or max values.
|
||||
|
@ -550,6 +553,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.store.db.DBLongIterator#hasNext()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasNext() throws IOException {
|
||||
if (hasNext) {
|
||||
return true;
|
||||
|
@ -568,6 +572,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.store.db.DBLongIterator#hasPrevious()
|
||||
*/
|
||||
@Override
|
||||
public boolean hasPrevious() throws IOException {
|
||||
if (hasPrev) {
|
||||
return true;
|
||||
|
@ -586,6 +591,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.store.db.DBLongIterator#next()
|
||||
*/
|
||||
@Override
|
||||
public long next() throws IOException {
|
||||
if (hasNext()) {
|
||||
lastKey = key;
|
||||
|
@ -598,6 +604,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.store.db.DBLongIterator#previous()
|
||||
*/
|
||||
@Override
|
||||
public long previous() throws IOException {
|
||||
if (hasPrevious()) {
|
||||
lastKey = key;
|
||||
|
@ -610,6 +617,7 @@ public class FieldIndexTable extends IndexTable {
|
|||
/* (non-Javadoc)
|
||||
* @see ghidra.framework.store.db.DBLongIterator#delete()
|
||||
*/
|
||||
@Override
|
||||
public boolean delete() throws IOException {
|
||||
if (lastKey != null) {
|
||||
long primaryKey = lastKey.getPrimaryKey();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue