Corrected ConcurrentModificationException caused by recent DBObjectCache

change
This commit is contained in:
ghidra1 2020-05-20 10:18:35 -04:00
parent 3dc789863e
commit 2ec2a991fb

View file

@ -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();