Merge remote-tracking branch 'origin/GP-6071_ghidra1_VTMatchSet'

This commit is contained in:
ghidra1
2025-11-05 14:17:01 -05:00
5 changed files with 95 additions and 67 deletions

View File

@@ -4,9 +4,9 @@
* Licensed 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.
@@ -301,11 +301,6 @@ public class VTMatchSetDB extends DatabaseObject implements VTMatchSet {
return true;
}
@Override
public boolean isInvalid() {
return session.getMatchSetRecord(key) == null;
}
private VTMatch getMatchForRecord(DBRecord matchRecord) {
try {
lock.acquire();
@@ -346,14 +341,8 @@ public class VTMatchSetDB extends DatabaseObject implements VTMatchSet {
return matchTableAdapter;
}
public void invalidateCache() {
lock.acquire();
try {
matchCache.invalidate();
}
finally {
lock.release();
}
void invalidateCache() {
matchCache.invalidate();
}
@Override

View File

@@ -4,9 +4,9 @@
* Licensed 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.
@@ -80,7 +80,7 @@ public abstract class VTMatchTableDBAdapter {
static VTMatchTableDBAdapter getAdapter(DBHandle dbHandle, long tableID, OpenMode openMode,
TaskMonitor monitor) throws VersionException {
return new VTMatchTableDBAdapterV0(dbHandle, tableID, openMode, monitor);
return new VTMatchTableDBAdapterV0(dbHandle, tableID, openMode);
}
public abstract DBRecord insertMatchRecord(VTMatchInfo info, VTMatchSetDB matchSet,

View File

@@ -4,9 +4,9 @@
* Licensed 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.
@@ -16,30 +16,25 @@
package ghidra.feature.vt.api.db;
import static ghidra.feature.vt.api.db.VTMatchTableDBAdapter.ColumnDescription.*;
import ghidra.feature.vt.api.main.VTMatchInfo;
import ghidra.framework.data.OpenMode;
import ghidra.util.exception.VersionException;
import ghidra.util.task.TaskMonitor;
import java.io.IOException;
import db.*;
import ghidra.feature.vt.api.main.VTMatchInfo;
import ghidra.framework.data.OpenMode;
import ghidra.util.exception.VersionException;
public class VTMatchTableDBAdapterV0 extends VTMatchTableDBAdapter {
private Table table;
private final DBHandle dbHandle;
public VTMatchTableDBAdapterV0(DBHandle dbHandle, long tableID) throws IOException {
this.dbHandle = dbHandle;
table =
dbHandle.createTable(TABLE_NAME + tableID, TABLE_SCHEMA,
new int[] { ASSOCIATION_COL.column() });
table = dbHandle.createTable(TABLE_NAME + tableID, TABLE_SCHEMA,
new int[] { ASSOCIATION_COL.column() });
}
public VTMatchTableDBAdapterV0(DBHandle dbHandle, long tableID, OpenMode openMode,
TaskMonitor monitor) throws VersionException {
this.dbHandle = dbHandle;
public VTMatchTableDBAdapterV0(DBHandle dbHandle, long tableID, OpenMode openMode)
throws VersionException {
table = dbHandle.getTable(TABLE_NAME + tableID);
if (table == null) {
throw new VersionException("Missing Table: " + TABLE_NAME);
@@ -57,8 +52,10 @@ public class VTMatchTableDBAdapterV0 extends VTMatchTableDBAdapter {
DBRecord record = TABLE_SCHEMA.createRecord(table.getKey());
record.setLongValue(TAG_KEY_COL.column(), (tag == null) ? -1 : tag.getKey());
record.setString(SIMILARITY_SCORE_COL.column(), info.getSimilarityScore().toStorageString());
record.setString(CONFIDENCE_SCORE_COL.column(), info.getConfidenceScore().toStorageString());
record.setString(SIMILARITY_SCORE_COL.column(),
info.getSimilarityScore().toStorageString());
record.setString(CONFIDENCE_SCORE_COL.column(),
info.getConfidenceScore().toStorageString());
record.setLongValue(ASSOCIATION_COL.column(), association.getKey());
record.setIntValue(SOURCE_LENGTH_COL.column(), info.getSourceLength());
record.setIntValue(DESTINATION_LENGTH_COL.column(), info.getDestinationLength());

View File

@@ -17,7 +17,6 @@ package ghidra.feature.vt.api.db;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import db.*;
import ghidra.app.util.task.OpenProgramRequest;
@@ -93,7 +92,7 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
private Program sourceProgram;
private Program destinationProgram;
private List<VTMatchSetDB> matchSets = new CopyOnWriteArrayList<>();
private Map<Long, VTMatchSetDB> matchSetMap = new HashMap<>();
private VTMatchSet manualMatchSet;
private VTMatchSet impliedMatchSet;
@@ -140,10 +139,12 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
initializePrograms(sourceProgram, destinationProgram, true);
createMatchSet(new ManualMatchProgramCorrelator(sourceProgram, destinationProgram),
MANUAL_MATCH_SET_ID);
createMatchSet(new ImpliedMatchProgramCorrelator(sourceProgram, destinationProgram),
IMPLIED_MATCH_SET_ID);
manualMatchSet =
createMatchSet(new ManualMatchProgramCorrelator(sourceProgram, destinationProgram),
MANUAL_MATCH_SET_ID);
impliedMatchSet =
createMatchSet(new ImpliedMatchProgramCorrelator(sourceProgram, destinationProgram),
IMPLIED_MATCH_SET_ID);
updateVersion();
}
@@ -439,17 +440,7 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
super.clearCache(all);
associationManager.invalidateCache();
tagCache.invalidate();
List<VTMatchSetDB> temp = new ArrayList<>();
for (VTMatchSetDB matchSet : matchSets) {
if (!matchSet.isInvalid()) {
matchSet.invalidateCache();
temp.add(matchSet);
}
}
matchSets.retainAll(temp);
reconcileCachedMatchSets();
}
finally {
lock.release();
@@ -471,11 +462,44 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
RecordIterator recordIterator = matchSetTableAdapter.getRecords();
while (recordIterator.hasNext()) {
DBRecord record = recordIterator.next();
matchSets.add(
matchSetMap.put(record.getKey(),
VTMatchSetDB.getMatchSetDB(record, this, getDBHandle(), openMode, monitor, lock));
}
}
private void reconcileCachedMatchSets() {
try {
Set<Long> cachedKeySet = new HashSet<>(matchSetMap.keySet());
RecordIterator recordIterator = matchSetTableAdapter.getRecords();
while (recordIterator.hasNext()) {
DBRecord record = recordIterator.next();
long key = record.getKey();
if (cachedKeySet.remove(key)) {
// Invalidate cached MatchSet
matchSetMap.get(key).invalidateCache();
}
else {
// Add missing MatchSet to cache
matchSetMap.put(key, VTMatchSetDB.getMatchSetDB(record, this, getDBHandle(),
OpenMode.UPDATE, TaskMonitor.DUMMY, lock));
}
}
// Remove obsolete/invalid MatchSets whose record was not found
for (long key : cachedKeySet) {
matchSetMap.remove(key);
}
}
catch (VersionException e) {
throw new RuntimeException("Unexpected exception", e);
}
catch (IOException e) {
dbError(e);
}
}
@Override
public Program getSourceProgram() {
return sourceProgram;
@@ -503,7 +527,7 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
DBRecord record = matchSetTableAdapter.createMatchSetRecord(id, correlator);
VTMatchSetDB matchSet =
VTMatchSetDB.createMatchSetDB(record, this, getDBHandle(), lock);
matchSets.add(matchSet);
matchSetMap.put(matchSet.getKey(), matchSet);
changeSetsModified = true; // signal endTransaction to clear undo stack
setObjectChanged(VTEvent.MATCH_SET_ADDED, matchSet, null, matchSet);
@@ -564,7 +588,7 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
@Override
public List<VTMatchSet> getMatchSets() {
return new ArrayList<>(matchSets);
return new ArrayList<>(matchSetMap.values());
}
AddressSet getSourceAddressSet(DBRecord record) throws IOException {
@@ -625,11 +649,17 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
@Override
public List<VTMatch> getMatches(VTAssociation association) {
List<VTMatch> matches = new ArrayList<>();
for (VTMatchSet matchSet : matchSets) {
matches.addAll(matchSet.getMatches(association));
try {
lock.acquire();
List<VTMatch> matches = new ArrayList<>();
for (VTMatchSet matchSet : matchSetMap.values()) {
matches.addAll(matchSet.getMatches(association));
}
return matches;
}
finally {
lock.release();
}
return matches;
}
/**
@@ -649,22 +679,34 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
@Override
public VTMatchSet getManualMatchSet() {
if (manualMatchSet == null) {
manualMatchSet = findMatchSet(ManualMatchProgramCorrelator.class.getName());
try {
lock.acquire();
if (manualMatchSet == null) {
manualMatchSet = findMatchSet(ManualMatchProgramCorrelator.class.getName());
}
return manualMatchSet;
}
finally {
lock.release();
}
return manualMatchSet;
}
@Override
public VTMatchSet getImpliedMatchSet() {
if (impliedMatchSet == null) {
impliedMatchSet = findMatchSet(ImpliedMatchProgramCorrelator.class.getName());
try {
lock.acquire();
if (impliedMatchSet == null) {
impliedMatchSet = findMatchSet(ImpliedMatchProgramCorrelator.class.getName());
}
return impliedMatchSet;
}
finally {
lock.release();
}
return impliedMatchSet;
}
private VTMatchSet findMatchSet(String correlatorClassName) {
for (VTMatchSet matchSet : matchSets) {
for (VTMatchSet matchSet : matchSetMap.values()) {
VTProgramCorrelatorInfo info = matchSet.getProgramCorrelatorInfo();
String matchSetCorrelatorClassName = info.getCorrelatorClassName();
if (correlatorClassName.equals(matchSetCorrelatorClassName)) {
@@ -771,8 +813,8 @@ public class VTSessionDB extends DomainObjectAdapterDB implements VTSession {
}
public VTMatchTag getMatchTag(long key) {
lock.acquire();
try {
lock.acquire();
VTMatchTagDB matchTagDB = tagCache.get(key);
if (matchTagDB != null) {
return matchTagDB;

View File

@@ -102,7 +102,7 @@ public abstract class DatabaseObject {
* @return true if this object is invalid and must be re-validated, else false if object state
* is currently valid which may include a deleted state.
*/
protected boolean isInvalid() {
protected final boolean isInvalid() {
return !deleted && invalidateCount != getCurrentValidationCount();
}