mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 18:29:37 +02:00
Corrected ConcurrentModificationException caused by recent DBObjectCache
change
This commit is contained in:
parent
3dc789863e
commit
2ec2a991fb
1 changed files with 20 additions and 10 deletions
|
@ -21,6 +21,7 @@ package ghidra.program.database;
|
||||||
import java.lang.ref.ReferenceQueue;
|
import java.lang.ref.ReferenceQueue;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import db.Record;
|
import db.Record;
|
||||||
import ghidra.program.model.address.KeyRange;
|
import ghidra.program.model.address.KeyRange;
|
||||||
|
@ -198,16 +199,19 @@ public class DBObjectCache<T extends DatabaseObject> {
|
||||||
* @param keyRanges key ranges to delete
|
* @param keyRanges key ranges to delete
|
||||||
*/
|
*/
|
||||||
private void deleteLargeKeyRanges(List<KeyRange> keyRanges) {
|
private void deleteLargeKeyRanges(List<KeyRange> keyRanges) {
|
||||||
for (Long key : map.keySet()) {
|
//@formatter:off
|
||||||
if (keyRangesContain(keyRanges, key)) {
|
map.keySet().stream()
|
||||||
|
.filter(key -> keyRangesContain(keyRanges, key))
|
||||||
|
.collect(Collectors.toList())
|
||||||
|
.forEach(key -> {
|
||||||
KeyedSoftReference ref = map.remove(key);
|
KeyedSoftReference ref = map.remove(key);
|
||||||
DatabaseObject obj = ref.get();
|
DatabaseObject obj = ref.get();
|
||||||
if (obj != null) {
|
if (obj != null) {
|
||||||
obj.setDeleted();
|
obj.setDeleted();
|
||||||
ref.clear();
|
ref.clear();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
//@formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -270,17 +274,19 @@ public class DBObjectCache<T extends DatabaseObject> {
|
||||||
* @param endKey the last key in the range to invalidate.
|
* @param endKey the last key in the range to invalidate.
|
||||||
*/
|
*/
|
||||||
public synchronized void invalidate(long startKey, long endKey) {
|
public synchronized void invalidate(long startKey, long endKey) {
|
||||||
|
processQueue();
|
||||||
if (endKey - startKey < map.size()) {
|
if (endKey - startKey < map.size()) {
|
||||||
for (long i = startKey; i <= endKey; i++) {
|
for (long i = startKey; i <= endKey; i++) {
|
||||||
invalidate(i);
|
doInvalidate(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (long key : map.keySet()) {
|
//@formatter:off
|
||||||
if (key >= startKey && key <= endKey) {
|
map.keySet().stream()
|
||||||
invalidate(key);
|
.filter(key -> (key >= startKey && key <= endKey))
|
||||||
}
|
.collect(Collectors.toList())
|
||||||
}
|
.forEach(key -> doInvalidate(key));
|
||||||
|
//@formatter:on
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,6 +313,10 @@ public class DBObjectCache<T extends DatabaseObject> {
|
||||||
*/
|
*/
|
||||||
public synchronized void invalidate(long key) {
|
public synchronized void invalidate(long key) {
|
||||||
processQueue();
|
processQueue();
|
||||||
|
doInvalidate(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doInvalidate(long key) {
|
||||||
KeyedSoftReference ref = map.get(key);
|
KeyedSoftReference ref = map.get(key);
|
||||||
if (ref != null) {
|
if (ref != null) {
|
||||||
T obj = ref.get();
|
T obj = ref.get();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue