GP-5620 - Fixed a bug that introduced duplicate data when renaming

functions with a filter
This commit is contained in:
dragonmacher 2025-04-25 15:34:48 -04:00
parent 71e7f65d3f
commit 8d2c94e28d
4 changed files with 171 additions and 34 deletions

View file

@ -4,22 +4,23 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.widgets.table;
package docking.widgets.table.threaded;
import static docking.widgets.table.AddRemoveListItem.Type.*;
import java.util.*;
import docking.widgets.table.threaded.*;
import docking.widgets.table.AddRemoveListItem;
import docking.widgets.table.TableSortingContext;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
@ -76,6 +77,10 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
public void process(List<AddRemoveListItem<T>> addRemoveList, TableData<T> tableData,
TaskMonitor monitor) throws CancelledException {
if (addRemoveList.isEmpty()) {
return;
}
Set<AddRemoveListItem<T>> items = coalesceAddRemoveItems(addRemoveList);
//
@ -85,11 +90,7 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
// existing item still has the data used to sort it. If the sort data has changed, then
// even this step will not allow the TableData to find the item in a search.
//
Map<T, T> hashed = new HashMap<>();
for (T t : tableData) {
hashed.put(t, t);
}
Map<T, T> hashed = hashAllTableData(tableData, monitor);
Set<T> failedToRemove = new HashSet<>();
int n = items.size();
@ -103,14 +104,13 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
if (item.isChange()) {
T toRemove = hashed.remove(value);
remove(tableData, toRemove, failedToRemove);
monitor.incrementProgress(1);
}
else if (item.isRemove()) {
T toRemove = hashed.remove(value);
remove(tableData, toRemove, failedToRemove);
it.remove();
}
monitor.checkCancelled();
monitor.increment();
}
if (!failedToRemove.isEmpty()) {
@ -119,7 +119,7 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
monitor.setMessage("Removing " + message);
tableData.process((data, sortContext) -> {
return expungeLostItems(failedToRemove, data, sortContext);
return expungeLostItems(failedToRemove, data, sortContext, monitor);
});
}
@ -137,8 +137,7 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
tableData.insert(value);
hashed.put(value, value);
}
monitor.checkCancelled();
monitor.incrementProgress(1);
monitor.increment();
}
monitor.setMessage("Done adding/removing");
@ -165,6 +164,17 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
return new HashSet<>(map.values());
}
private Map<T, T> hashAllTableData(TableData<T> tableData, TaskMonitor monitor)
throws CancelledException {
TableData<T> allData = tableData.getRootData();
Map<T, T> hashed = new HashMap<>();
for (T t : allData) {
monitor.checkCancelled();
hashed.put(t, t);
}
return hashed;
}
private void handleAdd(AddRemoveListItem<T> item, Map<T, AddRemoveListItem<T>> map) {
T rowObject = item.getValue();
@ -241,7 +251,7 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
* against the entire list of table data, locating the item to be removed.
*/
private List<T> expungeLostItems(Set<T> toRemove, List<T> data,
TableSortingContext<T> sortContext) {
TableSortingContext<T> sortContext, TaskMonitor monitor) {
if (sortContext.isUnsorted()) {
// this can happen if the data is unsorted and we were asked to remove an item that
@ -249,10 +259,14 @@ public class CoalescingAddRemoveStrategy<T> implements TableAddRemoveStrategy<T>
return data;
}
// Copy to a new list those items that are not marked for removal. This saves the
// list move its items every time a remove takes place
// Copy to a new list those items that are not marked for removal. This saves a list move
// time a remove takes place
List<T> newList = new ArrayList<>(data.size() - toRemove.size());
for (int i = 0; i < data.size(); i++) {
if (monitor.isCancelled()) {
return newList;
}
T rowObject = data.get(i);
if (!toRemove.contains(rowObject)) {
newList.add(rowObject);

View file

@ -170,7 +170,7 @@ public class TableData<ROW_OBJECT> implements Iterable<ROW_OBJECT> {
return true;
}
// We used to have code that pass proxy objects to this class to remove items. That code
// We used to have code that passed proxy objects to this class to remove items. That code
// has been updated to no longer pass proxy objects. Leaving this code here for a while
// just in case we find another client doing the same thing.
// return data.remove(t);
@ -189,6 +189,10 @@ public class TableData<ROW_OBJECT> implements Iterable<ROW_OBJECT> {
public void process(
BiFunction<List<ROW_OBJECT>, TableSortingContext<ROW_OBJECT>, List<ROW_OBJECT>> function) {
if (!isSorted()) {
return;
}
if (source != null) {
source.process(function);
}

View file

@ -4,16 +4,16 @@
* 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.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package docking.widgets.table;
package docking.widgets.table.threaded;
import static docking.widgets.table.AddRemoveListItem.Type.*;
import static org.junit.Assert.*;
@ -23,7 +23,8 @@ import java.util.*;
import org.junit.Before;
import org.junit.Test;
import docking.widgets.table.threaded.TestTableData;
import docking.widgets.table.*;
import docking.widgets.table.threaded.CoalescingAddRemoveStrategy;
import ghidra.util.task.TaskMonitor;
public class CoalescingAddRemoveStrategyTest {