mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GT-3294 Added support for DB FixedField with improved indexing.
This commit is contained in:
@@ -44,11 +44,11 @@ public class FunctionsTable {
|
||||
static final int CACHE_SIZE = 10000;
|
||||
|
||||
// @formatter:off
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "Function ID", new Class[] {
|
||||
ShortField.class, LongField.class,
|
||||
ByteField.class, LongField.class, LongField.class,
|
||||
LongField.class, LongField.class, LongField.class,
|
||||
ByteField.class
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "Function ID", new Field[] {
|
||||
ShortField.INSTANCE, LongField.INSTANCE,
|
||||
ByteField.INSTANCE, LongField.INSTANCE, LongField.INSTANCE,
|
||||
LongField.INSTANCE, LongField.INSTANCE, LongField.INSTANCE,
|
||||
ByteField.INSTANCE
|
||||
}, new String[] {
|
||||
"Code Unit Size", "Full Hash",
|
||||
"Specific Hash Additional Size", "Specific Hash", "Library ID",
|
||||
@@ -133,14 +133,15 @@ public class FunctionsTable {
|
||||
*/
|
||||
public List<FunctionRecord> getFunctionRecordsByFullHash(long hash) throws IOException {
|
||||
LongField hashField = new LongField(hash);
|
||||
DBLongIterator iterator = table.indexKeyIterator(FULL_HASH_COL, hashField, hashField, true);
|
||||
DBFieldIterator iterator =
|
||||
table.indexKeyIterator(FULL_HASH_COL, hashField, hashField, true);
|
||||
if (!iterator.hasNext()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<FunctionRecord> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
long key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key);
|
||||
Field key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key.getLongValue());
|
||||
if (functionRecord == null) {
|
||||
Record record = table.getRecord(key);
|
||||
functionRecord = new FunctionRecord(fidDb, functionCache, record);
|
||||
@@ -216,15 +217,15 @@ public class FunctionsTable {
|
||||
*/
|
||||
public List<FunctionRecord> getFunctionRecordsByNameSubstring(String nameSearch)
|
||||
throws IOException {
|
||||
DBLongIterator iterator = table.indexKeyIterator(NAME_ID_COL);
|
||||
DBFieldIterator iterator = table.indexKeyIterator(NAME_ID_COL);
|
||||
|
||||
if (!iterator.hasNext()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<FunctionRecord> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
long key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key);
|
||||
Field key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key.getLongValue());
|
||||
if (functionRecord == null) {
|
||||
Record record = table.getRecord(key);
|
||||
long nameID = record.getLongValue(NAME_ID_COL);
|
||||
@@ -255,15 +256,15 @@ public class FunctionsTable {
|
||||
*/
|
||||
public List<FunctionRecord> getFunctionRecordsByNameRegex(String regex) throws IOException {
|
||||
Matcher matcher = Pattern.compile(regex).matcher("");
|
||||
DBLongIterator iterator = table.indexKeyIterator(NAME_ID_COL);
|
||||
DBFieldIterator iterator = table.indexKeyIterator(NAME_ID_COL);
|
||||
|
||||
if (!iterator.hasNext()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<FunctionRecord> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
long key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key);
|
||||
Field key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key.getLongValue());
|
||||
if (functionRecord == null) {
|
||||
Record record = table.getRecord(key);
|
||||
long nameID = record.getLongValue(NAME_ID_COL);
|
||||
@@ -347,15 +348,15 @@ public class FunctionsTable {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
LongField field = new LongField(stringID);
|
||||
DBLongIterator iterator = table.indexKeyIterator(NAME_ID_COL, field, field, true);
|
||||
DBFieldIterator iterator = table.indexKeyIterator(NAME_ID_COL, field, field, true);
|
||||
if (!iterator.hasNext()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
final long libraryKey = library.getLibraryID();
|
||||
List<FunctionRecord> list = new ArrayList<>();
|
||||
while (iterator.hasNext()) {
|
||||
long key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key);
|
||||
Field key = iterator.next();
|
||||
FunctionRecord functionRecord = functionCache.get(key.getLongValue());
|
||||
if (functionRecord == null) {
|
||||
Record record = table.getRecord(key);
|
||||
if (record.getLongValue(LIBRARY_ID_COL) == libraryKey) {
|
||||
|
||||
@@ -49,10 +49,10 @@ public class LibrariesTable {
|
||||
static final int GHIDRA_COMPILER_SPEC_ID_COL = 7;
|
||||
|
||||
// @formatter:off
|
||||
static final Schema SCHEMA = new Schema(VERSION, "Library ID", new Class[] {
|
||||
StringField.class, StringField.class, StringField.class,
|
||||
StringField.class, StringField.class, IntField.class, IntField.class,
|
||||
StringField.class
|
||||
static final Schema SCHEMA = new Schema(VERSION, "Library ID", new Field[] {
|
||||
StringField.INSTANCE, StringField.INSTANCE, StringField.INSTANCE,
|
||||
StringField.INSTANCE, StringField.INSTANCE, IntField.INSTANCE, IntField.INSTANCE,
|
||||
StringField.INSTANCE
|
||||
}, new String[] {
|
||||
"Library Family Name", "Library Version", "Library Variant",
|
||||
"Ghidra Version", "Ghidra Language ID", "Ghidra Language Version", "Ghidra Language Minor Version",
|
||||
@@ -90,8 +90,9 @@ public class LibrariesTable {
|
||||
if (libraryVersion != VERSION) {
|
||||
String msg = "Expected version " + VERSION + " for table " + LIBRARIES_TABLE +
|
||||
" but got " + table.getSchema().getVersion();
|
||||
throw new VersionException(msg, libraryVersion < VERSION
|
||||
? VersionException.OLDER_VERSION : VersionException.NEWER_VERSION,
|
||||
throw new VersionException(msg,
|
||||
libraryVersion < VERSION ? VersionException.OLDER_VERSION
|
||||
: VersionException.NEWER_VERSION,
|
||||
false);
|
||||
}
|
||||
}
|
||||
@@ -155,14 +156,14 @@ public class LibrariesTable {
|
||||
public List<LibraryRecord> getLibrariesByName(String name, String version, String variant)
|
||||
throws IOException {
|
||||
StringField hashField = new StringField(name);
|
||||
DBLongIterator iterator =
|
||||
DBFieldIterator iterator =
|
||||
table.indexKeyIterator(LIBRARY_FAMILY_NAME_COL, hashField, hashField, true);
|
||||
if (!iterator.hasNext()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<LibraryRecord> list = new ArrayList<LibraryRecord>();
|
||||
while (iterator.hasNext()) {
|
||||
long key = iterator.next();
|
||||
Field key = iterator.next();
|
||||
Record record = table.getRecord(key);
|
||||
LibraryRecord libraryRecord = new LibraryRecord(record);
|
||||
if (version != null) {
|
||||
|
||||
@@ -27,8 +27,8 @@ public class RelationsTable {
|
||||
// static final int CACHE_SIZE = 10000;
|
||||
|
||||
// @formatter:off
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "Relation Smash", new Class[] {
|
||||
}, new String[] {
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "Relation Smash",
|
||||
new Field[] { }, new String[] {
|
||||
});
|
||||
// @formatter:on
|
||||
|
||||
|
||||
@@ -35,11 +35,9 @@ public class StringsTable {
|
||||
static final int CACHE_SIZE = 10000;
|
||||
|
||||
// @formatter:off
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "String ID", new Class[] {
|
||||
StringField.class
|
||||
}, new String[] {
|
||||
"String Value"
|
||||
});
|
||||
static final Schema SCHEMA = new Schema(LibrariesTable.VERSION, "String ID",
|
||||
new Field[] { StringField.INSTANCE },
|
||||
new String[] { "String Value" });
|
||||
// @formatter:on
|
||||
|
||||
static int[] INDEXED_COLUMNS = new int[] { STRING_VALUE_COL };
|
||||
@@ -69,29 +67,30 @@ public class StringsTable {
|
||||
* @throws IOException if the database has a problem
|
||||
*/
|
||||
long obtainStringID(String value) throws IOException {
|
||||
long[] records = table.findRecords(new StringField(value), STRING_VALUE_COL);
|
||||
Field[] records = table.findRecords(new StringField(value), STRING_VALUE_COL);
|
||||
if (records == null || records.length == 0) {
|
||||
// create
|
||||
Record record = SCHEMA.createRecord(UniversalIdGenerator.nextID().getValue());
|
||||
long key = UniversalIdGenerator.nextID().getValue();
|
||||
Record record = SCHEMA.createRecord(key);
|
||||
record.setString(STRING_VALUE_COL, value);
|
||||
table.putRecord(record);
|
||||
return record.getKey();
|
||||
return key;
|
||||
}
|
||||
return records[0];
|
||||
return records[0].getLongValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup existing ID or return null for String value.
|
||||
* @param value the string value
|
||||
* @return the existing interned string primary key, or null if nonexistent
|
||||
* @return the existing interned string primary key as LongField, or null if nonexistent
|
||||
* @throws IOException if the database has a problem
|
||||
*/
|
||||
Long lookupStringID(String value) throws IOException {
|
||||
long[] records = table.findRecords(new StringField(value), STRING_VALUE_COL);
|
||||
Field[] records = table.findRecords(new StringField(value), STRING_VALUE_COL);
|
||||
if (records == null || records.length == 0) {
|
||||
return null;
|
||||
}
|
||||
return records[0];
|
||||
return records[0].getLongValue();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user