mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +02:00
GT-3210 - Delete old files not in use
This commit is contained in:
parent
8eef7ddc0a
commit
a19e3daabb
29 changed files with 0 additions and 5207 deletions
|
@ -1,126 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Iterator;
|
||||
import java.util.SortedSet;
|
||||
|
||||
/**
|
||||
* Provides a list of integer ranges that are maintained in sorted order where
|
||||
* adjacent ranges do not coalesce.
|
||||
* When a range is added any ranges that overlap will coalesce into a single range.
|
||||
* However, ranges which are adjacent to one another will not coalesce.
|
||||
* This list maintains separate ranges which can have one range ending and
|
||||
* the next range beginning at the next available integer value.
|
||||
*/
|
||||
public class AdjacentSortedRangeList extends SortedRangeList {
|
||||
|
||||
/**
|
||||
* Creates a new empty sorted range list which allows adjacent ranges.
|
||||
*/
|
||||
public AdjacentSortedRangeList() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new adjacent sorted range list with ranges equivalent to those in the
|
||||
* specified list.
|
||||
* @param list the adjacent sorted range list to make an equivalent copy of.
|
||||
*/
|
||||
public AdjacentSortedRangeList(AdjacentSortedRangeList list) {
|
||||
set = new TreeSet<Range>();
|
||||
Iterator<Range> it = list.set.iterator();
|
||||
while(it.hasNext()) {
|
||||
Range r = it.next();
|
||||
addRange(r.min, r.max);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the range from min to max to this adjacent sorted range list.
|
||||
* If the range overlaps any other existing ranges, then those ranges will coalesce.
|
||||
* If the range is adjacent to other
|
||||
* @param min the range minimum
|
||||
* @param max the range maximum (inclusive)
|
||||
*/
|
||||
@Override
|
||||
public void addRange(int min, int max) {
|
||||
Range key = new Range(min, min);
|
||||
SortedSet<Range> headSet = set.headSet(key);
|
||||
if (!headSet.isEmpty()) {
|
||||
Range last = headSet.last();
|
||||
if (min <= last.max){
|
||||
last.max = Math.max(last.max, max);
|
||||
coalesce(last, set.tailSet(key).iterator());
|
||||
return;
|
||||
}
|
||||
}
|
||||
SortedSet<Range> ss = set.tailSet(key);
|
||||
if (ss.isEmpty()) {
|
||||
set.add(new Range(min, max));
|
||||
return;
|
||||
}
|
||||
Iterator<Range> it = ss.iterator();
|
||||
Range first = it.next();
|
||||
if (max < first.min) {
|
||||
set.add(new Range(min, max));
|
||||
return;
|
||||
}
|
||||
first.min = Math.min(first.min, min);
|
||||
first.max = Math.max(first.max, max);
|
||||
coalesce(first, it);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new AdjacentSortedRangeList that is the intersection of this
|
||||
* range list and the other range list specified. The ranges in the new list will
|
||||
* have breaks between adjacent ranges wherever either this range list
|
||||
* or the other range list have breaks between adjacent ranges.
|
||||
* @param other the other adjacent sorted range list
|
||||
* @return the new AdjacentSortedRangeList representing the intersection.
|
||||
*/
|
||||
public AdjacentSortedRangeList intersect(AdjacentSortedRangeList other) {
|
||||
AdjacentSortedRangeList srl = new AdjacentSortedRangeList(this);
|
||||
srl.remove(other);
|
||||
AdjacentSortedRangeList srl2 = new AdjacentSortedRangeList(this);
|
||||
srl2.remove(srl);
|
||||
// Split ranges where other list's breaks are between adjacent ranges.
|
||||
int num = other.getNumRanges();
|
||||
for(int otherIndex=0; otherIndex < num-1; otherIndex++) {
|
||||
Range r = other.getRange(otherIndex);
|
||||
Range rNext = other.getRange(otherIndex+1);
|
||||
if (r.max+1 == rNext.min) {
|
||||
// Adjacent
|
||||
int myIndex = srl2.getRangeIndex(r.max);
|
||||
if (myIndex < 0) {
|
||||
continue;
|
||||
}
|
||||
Range myRange = srl2.getRange(myIndex);
|
||||
int min = myRange.min;
|
||||
int max = myRange.max;
|
||||
if (max >= rNext.min) {
|
||||
// split the range
|
||||
srl2.removeRange(min, max);
|
||||
srl2.addRange(min, r.max);
|
||||
srl2.addRange(rNext.min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
return srl2;
|
||||
}
|
||||
}
|
|
@ -1,133 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.BytePropertySet;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Stores ranges of byte values throughout "long" space. Every "long" index has
|
||||
* an associated byte value (initially 0). Users can paint (set) ranges of
|
||||
* indexes to a given byte value, overwriting any value that currently exists
|
||||
* in that range.
|
||||
*
|
||||
* This class is implemented using an BytePropertySet. The first index
|
||||
* (0) will always contain a value. The value at any other given
|
||||
* index will either be the value stored at that index, or if no
|
||||
* value stored there, then the value stored at the nearest previous index
|
||||
* that contains a value.
|
||||
*/
|
||||
public class ByteRangeMap implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
|
||||
BytePropertySet map;
|
||||
|
||||
/**
|
||||
* Constructor for RangeMap.
|
||||
*/
|
||||
public ByteRangeMap() {
|
||||
map = new BytePropertySet("RangeMap");
|
||||
map.putByte(0, (byte)0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the given value with every index from start to end (inclusive)
|
||||
* Any previous associates are overwritten.
|
||||
* @param start the start index of the range to fill.
|
||||
* @param end the end index of the range to fill
|
||||
* @param value the value to put at every index in the range.
|
||||
*/
|
||||
public void paintRange(long start, long end, byte value) {
|
||||
|
||||
// first fix up the end of the range, unless the end goes to the END
|
||||
if (end != Long.MAX_VALUE) {
|
||||
byte origEndValue = getValue(end+1);
|
||||
if (origEndValue != value) {
|
||||
map.putByte(end+1, origEndValue);
|
||||
}
|
||||
else {
|
||||
map.remove(end+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now remove any values stored from start to end
|
||||
LongIterator it = map.getPropertyIterator(start);
|
||||
while(it.hasNext()) {
|
||||
long next = it.next();
|
||||
if (next <= end) {
|
||||
map.remove(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (start == 0) {
|
||||
map.putByte(0,value);
|
||||
}
|
||||
else {
|
||||
byte startValue = getValue(start);
|
||||
if (startValue != value) {
|
||||
map.putByte(start, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the int value associated with the given index.
|
||||
* @param index the index at which to get the value.
|
||||
*/
|
||||
public byte getValue(long index) {
|
||||
try {
|
||||
return map.getByte(index);
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
try {
|
||||
index = map.getPreviousPropertyIndex(index);
|
||||
return map.getByte(index);
|
||||
}
|
||||
catch(NoSuchIndexException ex) {
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* returns an iterator over the ranges
|
||||
* @param index index to start the iterator
|
||||
* @return IndexRangeIterator the iterator over the index ranges
|
||||
*/
|
||||
public IndexRangeIterator getIndexRangeIterator(long index) {
|
||||
return new PropertySetIndexRangeIterator(map, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over all indexes where the values changes.
|
||||
* @param start start index of iterator
|
||||
* @param end end index of iterator
|
||||
* @return LongIterator the iterator over index values that represent
|
||||
* changes in values.
|
||||
*/
|
||||
public LongIterator getChangePointIterator(long start, long end) {
|
||||
return map.getPropertyIterator(start, end);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Manages an array of lists of ints. It provides methods for
|
||||
* adding, deleting, and retrieving int values for specific lists.
|
||||
*/
|
||||
public class IntIntIndexedList implements Serializable {
|
||||
|
||||
private final static short DEFAULT_CAPACITY=16;
|
||||
|
||||
private int []values; // array to store the values
|
||||
private IntListIndexer indexer; // keeps track of lists of indexes into values array.
|
||||
private int capacity; // current size of values array.
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param numLists initial number of lists.
|
||||
*/
|
||||
public IntIntIndexedList (int numLists) {
|
||||
|
||||
indexer = new IntListIndexer(numLists, DEFAULT_CAPACITY);
|
||||
capacity = indexer.getCapacity();
|
||||
values = new int[capacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the front of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be added.
|
||||
* @param value the value to be added to the list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void add(int listID, int value) {
|
||||
|
||||
int index = indexer.add(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the back of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be appended.
|
||||
* @param value the value to be added to the linked list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void append(int listID, int value) {
|
||||
|
||||
int index = indexer.append(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the value from the list indexed by listID.
|
||||
* @param listID specifies from which list to remove the value.
|
||||
* @param value the value to remove removed from the specified list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean remove(int listID, int value) {
|
||||
|
||||
// find index that contains value
|
||||
int index = findIndex(listID, value);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
indexer.remove(listID, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all values from a specified list.
|
||||
* @param listID the id of the list to be cleared.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void removeAll(int listID) {
|
||||
|
||||
indexer.removeAll(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value exists in the specified list.
|
||||
* @param listID the id of the list to check for the value.
|
||||
* @param value the value to searched for in the given list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean contains(int listID, int value) {
|
||||
int index = findIndex(listID, value);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of values in the specified list.
|
||||
* @param listID the id of the list for which to get the number of values.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public int getCount(int listID) {
|
||||
return indexer.getListSize(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of values stored in the specified list.
|
||||
* @param listID the id of the list to get values for.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public int[] get(int listID) {
|
||||
|
||||
int count = indexer.getListSize(listID);
|
||||
|
||||
int []lvalues = new int[count];
|
||||
|
||||
int p = indexer.first(listID);
|
||||
|
||||
for(int i=0;i<count;i++) {
|
||||
lvalues[i] = values[p];
|
||||
p = indexer.next(p);
|
||||
}
|
||||
|
||||
return lvalues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of lists.
|
||||
*/
|
||||
public int getNumLists() {
|
||||
return indexer.getNumLists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the number of lists.
|
||||
* @param numLists the new number of lists.
|
||||
*/
|
||||
public void growNumLists(int numLists) {
|
||||
indexer.growNumLists(numLists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all values from all lists.
|
||||
*/
|
||||
public void clear() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the capacity for the linked list of values.
|
||||
*/
|
||||
private void grow(int newCapacity) {
|
||||
|
||||
capacity = newCapacity;
|
||||
int []tempValues = new int[newCapacity];
|
||||
|
||||
System.arraycopy(values, 0, tempValues, 0, values.length);
|
||||
|
||||
values = tempValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the value in the list specified by listID.
|
||||
*/
|
||||
private int findIndex(int listID, int value) {
|
||||
|
||||
int p = indexer.first(listID);
|
||||
|
||||
while (p != -1) {
|
||||
if (values[p] == value) {
|
||||
return p;
|
||||
}
|
||||
p = indexer.next(p);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -1,49 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
/**
|
||||
* Iterator over a set of Java-type int values.
|
||||
*
|
||||
*/
|
||||
public interface IntIterator {
|
||||
/**
|
||||
* Return true if there is a next int in this iterator.
|
||||
*/
|
||||
public boolean hasNext();
|
||||
|
||||
/**
|
||||
* Get the next int value in this iterator.
|
||||
*/
|
||||
public int next();
|
||||
|
||||
/**
|
||||
* Return true if there a previous int in this iterator.
|
||||
*/
|
||||
public boolean hasPrevious();
|
||||
/**
|
||||
* Get the previous int value in this iterator.
|
||||
*/
|
||||
public int previous();
|
||||
|
||||
/**
|
||||
* Removes from the underlying collection the last element returned
|
||||
* by the iterator (optional operation).
|
||||
*
|
||||
*/
|
||||
public void remove();
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Manages an array of lists of longs. It provides methods for
|
||||
* adding, deleting, and retrieving int values for specific lists.
|
||||
*/
|
||||
public class IntLongIndexedList implements Serializable {
|
||||
|
||||
private final static short DEFAULT_CAPACITY=16;
|
||||
|
||||
private long []values; // array to store the values
|
||||
private IntListIndexer indexer; // keeps track of lists of indexes into values array.
|
||||
private int capacity; // current size of values array.
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param numLists initial number of lists.
|
||||
*/
|
||||
public IntLongIndexedList (int numLists) {
|
||||
|
||||
indexer = new IntListIndexer(numLists, DEFAULT_CAPACITY);
|
||||
capacity = indexer.getCapacity();
|
||||
values = new long[capacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the front of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be added.
|
||||
* @param value the value to be added to the list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void add(int listID, long value) {
|
||||
|
||||
int index = indexer.add(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the back of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be appended.
|
||||
* @param value the value to be added to the linked list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void append(int listID, long value) {
|
||||
|
||||
int index = indexer.append(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the value from the list indexed by listID.
|
||||
* @param listID the id of the list from which to remove the value.
|
||||
* @param value the value to be removed from the specified list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean remove(int listID, long value) {
|
||||
|
||||
// find index that contains value
|
||||
int index = findIndex(listID, value);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
indexer.remove(listID, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all values from a specified list.
|
||||
* @param listID the id of the list to be cleared.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void removeAll(int listID) {
|
||||
|
||||
indexer.removeAll(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value exists in the specified list.
|
||||
* @param listID the id of the list to be tested for the given value.
|
||||
* @param value the value to search for in the specified list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean contains(int listID, long value) {
|
||||
int index = findIndex(listID, value);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of values in the specified list.
|
||||
* @param listID the id of the list for which to get the count.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public int getCount(int listID) {
|
||||
return indexer.getListSize(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of values stored in the specified list.
|
||||
* @param listID the id of the list from which to get the values.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public long[] get(int listID) {
|
||||
|
||||
int count = indexer.getListSize(listID);
|
||||
|
||||
long []lvalues = new long[count];
|
||||
|
||||
int p = indexer.first(listID);
|
||||
|
||||
for(int i=0;i<count;i++) {
|
||||
lvalues[i] = values[p];
|
||||
p = indexer.next(p);
|
||||
}
|
||||
|
||||
return lvalues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of lists.
|
||||
*/
|
||||
public int getNumLists() {
|
||||
return indexer.getNumLists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the number of lists.
|
||||
* @param numLists the new number of lists.
|
||||
*/
|
||||
public void growNumLists(int numLists) {
|
||||
indexer.growNumLists(numLists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all values from all lists.
|
||||
*/
|
||||
public void clear() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the capacity for the linked list of values.
|
||||
*/
|
||||
private void grow(int newCapacity) {
|
||||
|
||||
capacity = newCapacity;
|
||||
long[] tempValues = new long[newCapacity];
|
||||
|
||||
System.arraycopy(values, 0, tempValues, 0, values.length);
|
||||
|
||||
values = tempValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the value in the list specified by listID.
|
||||
*/
|
||||
private int findIndex(int listID, long value) {
|
||||
|
||||
int p = indexer.first(listID);
|
||||
|
||||
while (p != -1) {
|
||||
if (values[p] == value) {
|
||||
return p;
|
||||
}
|
||||
p = indexer.next(p);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -1,165 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class that maps a long key to a list of ints.
|
||||
*/
|
||||
|
||||
public class LongIntHashedList implements Serializable {
|
||||
|
||||
private LongKeyIndexer indexer; // maps keys to index values
|
||||
private IntIntIndexedList values; // keeps a linked list of int values.
|
||||
private int capacity;
|
||||
|
||||
private final static int DEFAULT_CAPACITY=16;
|
||||
|
||||
/**
|
||||
* Constructs a new LongIntHashedList with a default capacity.
|
||||
*/
|
||||
public LongIntHashedList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new LongIntHashedList with a given capacity.
|
||||
* @param capacity the initial capacity
|
||||
*/
|
||||
public LongIntHashedList(int capacity) {
|
||||
this.capacity = capacity;
|
||||
indexer = new LongKeyIndexer(capacity);
|
||||
values = new IntIntIndexedList(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given value to list associated with the given key.
|
||||
* @param key the key to be associated with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
*/
|
||||
public void add(long key,int value) {
|
||||
int index = indexer.put(key);
|
||||
|
||||
// if the indexer grew (because its key array became full),
|
||||
// then we need to grow also.
|
||||
if (index >= capacity) {
|
||||
capacity = indexer.getCapacity();
|
||||
values.growNumLists(capacity);
|
||||
}
|
||||
|
||||
// add the value to the list.
|
||||
values.add(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given value to list associated with the given key.
|
||||
* @param key the key to be associated with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
*/
|
||||
public void append(long key,int value) {
|
||||
int index = indexer.put(key);
|
||||
// if the indexer grew (because its key array became full),
|
||||
// then we need to grow also.
|
||||
if (index >= capacity) {
|
||||
capacity = indexer.getCapacity();
|
||||
values.growNumLists(capacity);
|
||||
}
|
||||
|
||||
// add the value to the list.
|
||||
values.append(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given value is in the list of values associated with
|
||||
* the given key.
|
||||
* @param key key whose list is to be searched for the given value.
|
||||
* @param value the value to be searched for in the list associated with the
|
||||
* key.
|
||||
*/
|
||||
public boolean contains(long key, int value) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found!
|
||||
return false;
|
||||
}
|
||||
return values.contains(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of int values associated with the given key.
|
||||
* @param key the key for which to return a set of associated values.
|
||||
*/
|
||||
public int[] get(long key) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found!
|
||||
return null;
|
||||
}
|
||||
|
||||
return values.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the int value from the list associated with the given key.
|
||||
* @param key the key associated with a list of valus from which to remove the
|
||||
* given value.
|
||||
* @param value the value to be removed from the list of values associated with
|
||||
* the given key.
|
||||
*/
|
||||
public boolean remove(long key,int value) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean ret = values.remove(index, value);
|
||||
|
||||
// if the list becomes empty, no need to reserve the
|
||||
// index for that key.
|
||||
if (values.getCount(index) == 0) {
|
||||
indexer.remove(key);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the values in the list associated with the given key.
|
||||
* @param key the key whose list of values should be cleared.
|
||||
*/
|
||||
public void removeAll(long key) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found, nothing to remove
|
||||
return;
|
||||
}
|
||||
values.removeAll(index);
|
||||
indexer.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all values from all keys.
|
||||
*/
|
||||
public void clear() {
|
||||
indexer.clear();
|
||||
values.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,172 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class that maps a long key to a list of longs.
|
||||
*/
|
||||
|
||||
public class LongLongHashedList implements Serializable {
|
||||
|
||||
private LongKeyIndexer indexer; // maps keys to index values
|
||||
private IntLongIndexedList values; // keeps a linked list of int values.
|
||||
private int capacity;
|
||||
|
||||
private final static int DEFAULT_CAPACITY=16;
|
||||
|
||||
/**
|
||||
* Constructs a new LongLongHashedList with a default capacity.
|
||||
*/
|
||||
public LongLongHashedList() {
|
||||
this(DEFAULT_CAPACITY);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new LongLongHashedList with a given capacity.
|
||||
* @param capacity the initial capacity
|
||||
*/
|
||||
public LongLongHashedList(int capacity) {
|
||||
this.capacity = capacity;
|
||||
indexer = new LongKeyIndexer(capacity);
|
||||
values = new IntLongIndexedList(capacity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of keys.
|
||||
*/
|
||||
public long[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given value to list associated with the given key.
|
||||
* @param key key to be associated with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
*/
|
||||
public void add(long key,long value) {
|
||||
int index = indexer.put(key);
|
||||
|
||||
// if the indexer grew (because its key array became full),
|
||||
// then we need to grow also.
|
||||
if (index >= capacity) {
|
||||
capacity = indexer.getCapacity();
|
||||
values.growNumLists(capacity);
|
||||
}
|
||||
|
||||
// add the value to the list.
|
||||
values.add(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given value to list associated with the given key.
|
||||
* @param key key to be associated with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
*/
|
||||
public void append(long key,long value) {
|
||||
int index = indexer.put(key);
|
||||
// if the indexer grew (because its key array became full),
|
||||
// then we need to grow also.
|
||||
if (index >= capacity) {
|
||||
capacity = indexer.getCapacity();
|
||||
values.growNumLists(capacity);
|
||||
}
|
||||
|
||||
// add the value to the list.
|
||||
values.append(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if the given value is in the list of values associated with
|
||||
* the given key.
|
||||
* @param key key whose list is to be searched for the given value.
|
||||
* @param value the value to be searched for in the list associated with the
|
||||
* key.
|
||||
*/
|
||||
public boolean contains(long key, long value) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found!
|
||||
return false;
|
||||
}
|
||||
return values.contains(index, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of int values associated with the given key.
|
||||
* @param key the key for which to return a set of associated values.
|
||||
*/
|
||||
public long[] get(long key) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found!
|
||||
return null;
|
||||
}
|
||||
|
||||
return values.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the int value from the list associated with the given key.
|
||||
* @param key the key associated with a list of values from which to remove the
|
||||
* given value.
|
||||
* @param value the value to be removed from the list of values associated with
|
||||
* the given key.
|
||||
*/
|
||||
public boolean remove(long key,long value) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean ret = values.remove(index, value);
|
||||
|
||||
// if the list becomes empty, no need to reserve the
|
||||
// index for that key.
|
||||
if (values.getCount(index) == 0) {
|
||||
indexer.remove(key);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all the values in the list associated with the given key.
|
||||
* @param key the key whose list of values should be cleared.
|
||||
*/
|
||||
public void removeAll(long key) {
|
||||
int index = indexer.get(key);
|
||||
|
||||
if (index < 0) {
|
||||
// key not found, nothing to remove
|
||||
return;
|
||||
}
|
||||
values.removeAll(index);
|
||||
indexer.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all values from all keys.
|
||||
*/
|
||||
public void clear() {
|
||||
indexer.clear();
|
||||
values.clear();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import ghidra.util.LongIterator;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
import ghidra.util.prop.LongPropertySet;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Stores ranges of long values throughout "long" space. Every "long" index has
|
||||
* an associated long value (initially 0). Users can paint (set) ranges of
|
||||
* indexes to a given integer value, overwriting any value that currently exists
|
||||
* in that range.
|
||||
*
|
||||
* This class is implemented using a LongPropertySet. The first index
|
||||
* (0) will always contain a value. The value at any other given
|
||||
* index will either be the value stored at that index, or if no
|
||||
* value stored there, then the value stored at the nearest previous index
|
||||
* that contains a value.
|
||||
*/
|
||||
public class LongRangeMap implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
|
||||
LongPropertySet map;
|
||||
|
||||
/**
|
||||
* Constructor for RangeMap.
|
||||
*/
|
||||
public LongRangeMap() {
|
||||
map = new LongPropertySet("RangeMap");
|
||||
map.putLong(0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates the given value with every index from start to end (inclusive)
|
||||
* Any previous associates are overwritten.
|
||||
* @param start the start index of the range to fill.
|
||||
* @param end the end index of the range to fill
|
||||
* @param value the value to put at every index in the range.
|
||||
*/
|
||||
public void paintRange(long start, long end, long value) {
|
||||
|
||||
// first fix up the end of the range, unless the end goes to the END
|
||||
if (end != Long.MAX_VALUE) {
|
||||
long origEndValue = getValue(end+1);
|
||||
if (origEndValue != value) {
|
||||
map.putLong(end+1, origEndValue);
|
||||
}
|
||||
else {
|
||||
map.remove(end+1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// now remove any values stored from start to end
|
||||
LongIterator it = map.getPropertyIterator(start);
|
||||
while(it.hasNext()) {
|
||||
long next = it.next();
|
||||
if (next <= end) {
|
||||
map.remove(next);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (start == 0) {
|
||||
map.putLong(0,value);
|
||||
}
|
||||
else {
|
||||
long startValue = getValue(start);
|
||||
if (startValue != value) {
|
||||
map.putLong(start, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the long value associated with the given index.
|
||||
* @param index the index at which to get the value.
|
||||
*/
|
||||
public long getValue(long index) {
|
||||
try {
|
||||
return map.getLong(index);
|
||||
}
|
||||
catch(NoValueException e) {
|
||||
try {
|
||||
index = map.getPreviousPropertyIndex(index);
|
||||
return map.getLong(index);
|
||||
}
|
||||
catch(NoSuchIndexException ex) {
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an index range iterator over all occupied ranges in the map
|
||||
* @param index the index to start the iterator.
|
||||
* @return IndexRangeIterator that iterates over all occupied ranges in th
|
||||
* map.
|
||||
*/
|
||||
public IndexRangeIterator getIndexRangeIterator(long index) {
|
||||
return new PropertySetIndexRangeIterator(map, index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over all indexes where the value changes. The value
|
||||
* is considered to change when it goes from one value to another, or goes
|
||||
* from no value to a value or goes from a value to no value.
|
||||
* @param start the starting index to search.
|
||||
* @param end the ending index to search.
|
||||
* @return iterator over all indexes where value changes occur.
|
||||
*/
|
||||
public LongIterator getChangePointIterator(long start, long end) {
|
||||
return map.getPropertyIterator(start, end);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,936 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Container class for storing objects sorted on a long key. Uses the
|
||||
* RedBlack Tree algorithm to store the objects.
|
||||
*/
|
||||
|
||||
public class LongRedBlackTree implements Serializable {
|
||||
|
||||
private transient RBNode root;
|
||||
private transient int size;
|
||||
private transient long modification = 0;
|
||||
public LongRedBlackTree() {
|
||||
|
||||
}
|
||||
private static final byte RED = (byte)0;
|
||||
private static final byte BLACK = (byte)1;
|
||||
|
||||
// RedBlack Tree node
|
||||
static class RBNode {
|
||||
long key;
|
||||
Object value;
|
||||
byte color;
|
||||
RBNode parent;
|
||||
RBNode left;
|
||||
RBNode right;
|
||||
RBNode(long key, Object value, RBNode parent) {
|
||||
this.key = key;
|
||||
this.color = BLACK;
|
||||
this.parent = parent;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number keys in this set.
|
||||
*/
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the key is in the set.
|
||||
* @param key the key whose presence is to be tested.
|
||||
*/
|
||||
public boolean containsKey(long key) {
|
||||
RBNode node = root;
|
||||
while(node != null) {
|
||||
if (key == node.key) {
|
||||
return true;
|
||||
}
|
||||
if (key < node.key) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the object value for the given key or null if the key
|
||||
* is not in the tree set.
|
||||
* @param key the key whose associated value is to be returned.
|
||||
*/
|
||||
|
||||
public Object get(long key) {
|
||||
RBNode node = root;
|
||||
while(node != null) {
|
||||
if (key == node.key) {
|
||||
return node.value;
|
||||
}
|
||||
if (key < node.key) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value object for the smallest key in the set that is greater than
|
||||
* or equal to the given key. Returns -1 if
|
||||
* there are no keys greater than or equal to the given key.
|
||||
* @param key the search key.
|
||||
*/
|
||||
public Object getAtOrAfter(long key) {
|
||||
Object bestValue = null;
|
||||
|
||||
RBNode node = root;
|
||||
while (node != null) {
|
||||
if (key == node.key) {
|
||||
return node.value;
|
||||
}
|
||||
if (key > node.key) {
|
||||
node = node.right;
|
||||
}
|
||||
else {
|
||||
bestValue = node.value;
|
||||
node = node.left;
|
||||
}
|
||||
|
||||
}
|
||||
return bestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value object for the largest key in the set that is less than
|
||||
* or equal to the given key. Returns -1 if
|
||||
* there are no keys less than or equal to the given key.
|
||||
* @param key the search key.
|
||||
*/
|
||||
public Object getAtOrBefore(long key) {
|
||||
Object bestValue = null;
|
||||
|
||||
RBNode node = root;
|
||||
while (node != null) {
|
||||
if (key == node.key) {
|
||||
return node.value;
|
||||
}
|
||||
if (key <= node.key) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
bestValue = node.value;
|
||||
node = node.right;
|
||||
}
|
||||
|
||||
}
|
||||
return bestValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first key in this set.
|
||||
* @exception NoSuchIndexException thrown if no keys exist in this tree.
|
||||
*/
|
||||
public long getFirst() throws NoSuchIndexException {
|
||||
if (root == null) {
|
||||
throw NoSuchIndexException.noSuchIndexException;
|
||||
}
|
||||
RBNode node = root;
|
||||
|
||||
while(node.left != null) {
|
||||
node = node.left;
|
||||
}
|
||||
return node.key;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the last key in this set.
|
||||
* @exception NoSuchIndexException thrown if no keys exist in this tree.
|
||||
*/
|
||||
public long getLast() throws NoSuchIndexException {
|
||||
if (root == null) {
|
||||
throw NoSuchIndexException.noSuchIndexException;
|
||||
}
|
||||
RBNode node = root;
|
||||
|
||||
while(node.right != null) {
|
||||
node = node.right;
|
||||
}
|
||||
return node.key;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the smallest key in the set that is greater than the given key.
|
||||
* @param key the search key.
|
||||
* @exception NoSuchIndexException thrown if no keys exist in this tree past
|
||||
* the given key.
|
||||
*/
|
||||
public long getNext(long key) throws NoSuchIndexException {
|
||||
|
||||
boolean foundValue = false;
|
||||
long bestkey = Long.MIN_VALUE;
|
||||
|
||||
RBNode node = root;
|
||||
while (node != null) {
|
||||
if (key >= node.key) {
|
||||
node = node.right;
|
||||
}
|
||||
else {
|
||||
foundValue = true;
|
||||
bestkey = node.key;
|
||||
node = node.left;
|
||||
}
|
||||
|
||||
}
|
||||
if (foundValue) {
|
||||
return bestkey;
|
||||
}
|
||||
throw NoSuchIndexException.noSuchIndexException;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the largest key in the set that is less than the given key. Returns -1 if
|
||||
* there are not keys less than the given key.
|
||||
* @param key the search key.
|
||||
* @exception NoSuchIndexException thrown if no keys exist in this tree before
|
||||
* the given key.
|
||||
*/
|
||||
public long getPrevious(long key) throws NoSuchIndexException {
|
||||
boolean foundValue = false;
|
||||
long bestkey = 0;
|
||||
|
||||
RBNode node = root;
|
||||
while (node != null) {
|
||||
if (key <= node.key) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
foundValue = true;
|
||||
bestkey = node.key;
|
||||
node = node.right;
|
||||
}
|
||||
|
||||
}
|
||||
if (foundValue) {
|
||||
return bestkey;
|
||||
}
|
||||
throw NoSuchIndexException.noSuchIndexException;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given key,value pair to this tree.
|
||||
* @param key the key with which the object is to be associated.
|
||||
* @param obj object to be associated with the specified key.
|
||||
*/
|
||||
public void put(long key, Object obj) {
|
||||
modification++;
|
||||
if (root == null) {
|
||||
size++;
|
||||
root = new RBNode(key, obj, null);
|
||||
}
|
||||
RBNode node = root;
|
||||
|
||||
while (true) {
|
||||
|
||||
if (key == node.key) {
|
||||
node.value = obj;
|
||||
return;
|
||||
}
|
||||
else if (key < node.key) {
|
||||
if (node.left != null) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
size++;
|
||||
node.left = new RBNode(key, obj, node);
|
||||
fixAfterInsertion(node.left);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (node.right != null) {
|
||||
node = node.right;
|
||||
}
|
||||
else {
|
||||
size++;
|
||||
node.right = new RBNode(key, obj, node);
|
||||
fixAfterInsertion(node.right);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the given key from the set.
|
||||
* @param key key whose mapping is to be removed from the map.
|
||||
*
|
||||
*/
|
||||
public Object remove(long key) {
|
||||
modification++;
|
||||
RBNode node = root;
|
||||
while(node != null) {
|
||||
if (key == node.key) {
|
||||
break;
|
||||
}
|
||||
if (key < node.key) {
|
||||
node = node.left;
|
||||
}
|
||||
else {
|
||||
node = node.right;
|
||||
}
|
||||
}
|
||||
|
||||
if (node == null) {
|
||||
return null;
|
||||
}
|
||||
Object obj = node.value;
|
||||
size--;
|
||||
deleteEntry(node);
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all keys from the set.
|
||||
*/
|
||||
public void removeAll() {
|
||||
modification++;
|
||||
size = 0;
|
||||
root = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if the set is empty.
|
||||
*@return true if the set is empty.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return size == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over all the objects stored in this tree.
|
||||
*/
|
||||
public Iterator<?> iterator() {
|
||||
return new LongRedBlackTreeIterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Balancing operations.
|
||||
*
|
||||
* Implementations of rebalancings during insertion and deletion are
|
||||
* slightly different than the CLR version. Rather than using dummy
|
||||
* nilnodes, we use a set of accessors that deal properly with null. They
|
||||
* are used to avoid messiness surrounding nullness checks in the main
|
||||
* algorithms.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the color of the given node.
|
||||
*/
|
||||
private static byte colorOf(RBNode p) {
|
||||
return (p == null ? BLACK : p.color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the parent of the given node.
|
||||
*/
|
||||
private static RBNode parentOf(RBNode p) {
|
||||
return (p == null ? null: p.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of the given node to the given color.
|
||||
*/
|
||||
private static void setColor(RBNode p, byte c) {
|
||||
if (p != null) p.color = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the left child of the given node.
|
||||
*/
|
||||
private static RBNode leftOf(RBNode p) {
|
||||
return (p == null)? null: p.left;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the right child of the given node.
|
||||
*/
|
||||
private static RBNode rightOf(RBNode p) {
|
||||
return (p == null)? null: p.right;
|
||||
}
|
||||
|
||||
/** From CLR **/
|
||||
private void rotateLeft(RBNode p) {
|
||||
RBNode r = p.right;
|
||||
p.right = r.left;
|
||||
if (r.left != null) {
|
||||
r.left.parent = p;
|
||||
}
|
||||
r.parent = p.parent;
|
||||
if (p.parent == null) {
|
||||
root = r;
|
||||
}
|
||||
else if (p.parent.left == p) {
|
||||
p.parent.left = r;
|
||||
}
|
||||
else {
|
||||
p.parent.right = r;
|
||||
}
|
||||
r.left = p;
|
||||
p.parent = r;
|
||||
}
|
||||
|
||||
/** From CLR **/
|
||||
private void rotateRight(RBNode p) {
|
||||
RBNode l = p.left;
|
||||
p.left = l.right;
|
||||
if (l.right != null) {
|
||||
l.right.parent = p;
|
||||
}
|
||||
l.parent = p.parent;
|
||||
if (p.parent == null) {
|
||||
root = l;
|
||||
}
|
||||
else if (p.parent.right == p) {
|
||||
p.parent.right = l;
|
||||
}
|
||||
else {
|
||||
p.parent.left = l;
|
||||
}
|
||||
l.right = p;
|
||||
p.parent = l;
|
||||
}
|
||||
|
||||
|
||||
/** From CLR **/
|
||||
private void fixAfterInsertion(RBNode x) {
|
||||
x.color = RED;
|
||||
|
||||
while (x != null && x != root && x.parent.color == RED) {
|
||||
if (parentOf(x) == leftOf(parentOf(parentOf(x)))) {
|
||||
RBNode y = rightOf(parentOf(parentOf(x)));
|
||||
if (colorOf(y) == RED) {
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(y, BLACK);
|
||||
setColor(parentOf(parentOf(x)), RED);
|
||||
x = parentOf(parentOf(x));
|
||||
}
|
||||
else {
|
||||
if (x == rightOf(parentOf(x))) {
|
||||
x = parentOf(x);
|
||||
rotateLeft(x);
|
||||
}
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(parentOf(parentOf(x)), RED);
|
||||
if (parentOf(parentOf(x)) != null) {
|
||||
rotateRight(parentOf(parentOf(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
RBNode y = leftOf(parentOf(parentOf(x)));
|
||||
if (colorOf(y) == RED) {
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(y, BLACK);
|
||||
setColor(parentOf(parentOf(x)), RED);
|
||||
x = parentOf(parentOf(x));
|
||||
}
|
||||
else {
|
||||
if (x == leftOf(parentOf(x))) {
|
||||
x = parentOf(x);
|
||||
rotateRight(x);
|
||||
}
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(parentOf(parentOf(x)), RED);
|
||||
if (parentOf(parentOf(x)) != null) {
|
||||
rotateLeft(parentOf(parentOf(x)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
root.color = BLACK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete node p, and then rebalance the tree.
|
||||
*/
|
||||
private void deleteEntry(RBNode p) {
|
||||
|
||||
// If strictly internal, first swap position with successor.
|
||||
if (p.left != null && p.right != null) {
|
||||
|
||||
RBNode s = null;
|
||||
|
||||
RBNode node = root;
|
||||
while (node != null) {
|
||||
if (p.key >= node.key) {
|
||||
node = node.right;
|
||||
}
|
||||
else {
|
||||
s = node;
|
||||
node = node.left;
|
||||
}
|
||||
}
|
||||
|
||||
swapPosition(s, p);
|
||||
}
|
||||
|
||||
// Start fixup at replacement node, if it exists.
|
||||
RBNode replacement = (p.left != null ? p.left : p.right);
|
||||
|
||||
if (replacement != null) {
|
||||
// Link replacement to parent
|
||||
replacement.parent = p.parent;
|
||||
if (p.parent == null) {
|
||||
root = replacement;
|
||||
}
|
||||
else if (p == p.parent.left) {
|
||||
p.parent.left = replacement;
|
||||
}
|
||||
else {
|
||||
p.parent.right = replacement;
|
||||
}
|
||||
|
||||
// Null out links so they are OK to use by fixAfterDeletion.
|
||||
p.left = p.right = p.parent = null;
|
||||
|
||||
// Fix replacement
|
||||
if (p.color == BLACK) {
|
||||
fixAfterDeletion(replacement);
|
||||
}
|
||||
}
|
||||
else if (p.parent == null) { // return if we are the only node.
|
||||
root = null;
|
||||
}
|
||||
else { // No children. Use self as phantom replacement and unlink.
|
||||
if (p.color == BLACK) {
|
||||
fixAfterDeletion(p);
|
||||
}
|
||||
|
||||
if (p.parent != null) {
|
||||
if (p == p.parent.left) {
|
||||
p.parent.left = null;
|
||||
}
|
||||
else if (p == p.parent.right) {
|
||||
p.parent.right = null;
|
||||
}
|
||||
p.parent = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** From CLR **/
|
||||
private void fixAfterDeletion(RBNode x) {
|
||||
while (x != root && colorOf(x) == BLACK) {
|
||||
if (x == leftOf(parentOf(x))) {
|
||||
RBNode sib = rightOf(parentOf(x));
|
||||
|
||||
if (colorOf(sib) == RED) {
|
||||
setColor(sib, BLACK);
|
||||
setColor(parentOf(x), RED);
|
||||
rotateLeft(parentOf(x));
|
||||
sib = rightOf(parentOf(x));
|
||||
}
|
||||
|
||||
if (colorOf(leftOf(sib)) == BLACK &&
|
||||
colorOf(rightOf(sib)) == BLACK) {
|
||||
setColor(sib, RED);
|
||||
x = parentOf(x);
|
||||
}
|
||||
else {
|
||||
if (colorOf(rightOf(sib)) == BLACK) {
|
||||
setColor(leftOf(sib), BLACK);
|
||||
setColor(sib, RED);
|
||||
rotateRight(sib);
|
||||
sib = rightOf(parentOf(x));
|
||||
}
|
||||
setColor(sib, colorOf(parentOf(x)));
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(rightOf(sib), BLACK);
|
||||
rotateLeft(parentOf(x));
|
||||
x = root;
|
||||
}
|
||||
}
|
||||
else { // symmetric
|
||||
RBNode sib = leftOf(parentOf(x));
|
||||
|
||||
if (colorOf(sib) == RED) {
|
||||
setColor(sib, BLACK);
|
||||
setColor(parentOf(x), RED);
|
||||
rotateRight(parentOf(x));
|
||||
sib = leftOf(parentOf(x));
|
||||
}
|
||||
|
||||
if (colorOf(rightOf(sib)) == BLACK &&
|
||||
colorOf(leftOf(sib)) == BLACK) {
|
||||
setColor(sib, RED);
|
||||
x = parentOf(x);
|
||||
}
|
||||
else {
|
||||
if (colorOf(leftOf(sib)) == BLACK) {
|
||||
setColor(rightOf(sib), BLACK);
|
||||
setColor(sib, RED);
|
||||
rotateLeft(sib);
|
||||
sib = leftOf(parentOf(x));
|
||||
}
|
||||
setColor(sib, colorOf(parentOf(x)));
|
||||
setColor(parentOf(x), BLACK);
|
||||
setColor(leftOf(sib), BLACK);
|
||||
rotateRight(parentOf(x));
|
||||
x = root;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setColor(x, BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swap the linkages of two nodes in a tree.
|
||||
*/
|
||||
private void swapPosition(RBNode x, RBNode y) {
|
||||
// Save initial values.
|
||||
RBNode px = x.parent, lx = x.left, rx = x.right;
|
||||
RBNode py = y.parent, ly = y.left, ry = y.right;
|
||||
boolean xWasLeftChild = px != null && x == px.left;
|
||||
boolean yWasLeftChild = py != null && y == py.left;
|
||||
|
||||
// Swap, handling special cases of one being the other's parent.
|
||||
if (x == py) { // x was y's parent
|
||||
x.parent = y;
|
||||
if (yWasLeftChild) {
|
||||
y.left = x;
|
||||
y.right = rx;
|
||||
}
|
||||
else {
|
||||
y.right = x;
|
||||
y.left = lx;
|
||||
}
|
||||
}
|
||||
else {
|
||||
x.parent = py;
|
||||
if (py != null) {
|
||||
if (yWasLeftChild) {
|
||||
py.left = x;
|
||||
}
|
||||
else {
|
||||
py.right = x;
|
||||
}
|
||||
}
|
||||
y.left = lx;
|
||||
y.right = rx;
|
||||
}
|
||||
|
||||
if (y == px) { // y was x's parent
|
||||
y.parent = x;
|
||||
if (xWasLeftChild) {
|
||||
x.left = y;
|
||||
x.right = ry;
|
||||
}
|
||||
else {
|
||||
x.right = y;
|
||||
x.left = ly;
|
||||
}
|
||||
}
|
||||
else {
|
||||
y.parent = px;
|
||||
if (px != null) {
|
||||
if (xWasLeftChild) {
|
||||
px.left = y;
|
||||
}
|
||||
else {
|
||||
px.right = y;
|
||||
}
|
||||
}
|
||||
x.left = ly;
|
||||
x.right = ry;
|
||||
}
|
||||
|
||||
// Fix children's parent pointers
|
||||
if (x.left != null) {
|
||||
x.left.parent = x;
|
||||
}
|
||||
if (x.right != null) {
|
||||
x.right.parent = x;
|
||||
}
|
||||
if (y.left != null) {
|
||||
y.left.parent = y;
|
||||
}
|
||||
if (y.right != null) {
|
||||
y.right.parent = y;
|
||||
}
|
||||
|
||||
// Swap colors
|
||||
byte c = x.color;
|
||||
x.color = y.color;
|
||||
y.color = c;
|
||||
|
||||
// Check if root changed
|
||||
if (root == x) {
|
||||
root = y;
|
||||
}
|
||||
else if (root == y) {
|
||||
root = x;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Save the state of the <tt>TreeMap</tt> instance to a stream (i.e.,
|
||||
* serialize it).
|
||||
*
|
||||
* @serialData The <i>size</i> of the TreeMap (the number of key-value
|
||||
* mappings) is emitted (int), followed by the key (Object)
|
||||
* and value (Object) for each key-value mapping represented
|
||||
* by the TreeMap. The key-value mappings are emitted in
|
||||
* key-order (as determined by the TreeMap's Comparator,
|
||||
* or by the keys' natural ordering if the TreeMap has no
|
||||
* Comparator).
|
||||
*/
|
||||
private void writeObject(java.io.ObjectOutputStream s)
|
||||
throws java.io.IOException {
|
||||
// Write out the Comparator and any hidden stuff
|
||||
s.defaultWriteObject();
|
||||
|
||||
// Write out size (number of Mappings)
|
||||
s.writeInt(size);
|
||||
if (root != null) {
|
||||
writeInOrder(s, root);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeInOrder(java.io.ObjectOutputStream s, RBNode node)
|
||||
throws java.io.IOException {
|
||||
|
||||
if (node.left != null) {
|
||||
writeInOrder(s, node.left);
|
||||
}
|
||||
s.writeLong(node.key);
|
||||
s.writeObject(node.value);
|
||||
if (node.right != null) {
|
||||
writeInOrder(s, node.right);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitute the <tt>TreeMap</tt> instance from a stream (i.e.,
|
||||
* deserialize it).
|
||||
*/
|
||||
private void readObject(final java.io.ObjectInputStream s)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
// Read in the Comparator and any hidden stuff
|
||||
s.defaultReadObject();
|
||||
|
||||
// Read in size
|
||||
size = s.readInt();
|
||||
|
||||
root = buildFromSorted(0,0,size-1,computeRedLevel(size),s);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Recursive "helper method" that does the real work of the
|
||||
* of the previous method. Identically named parameters have
|
||||
* identical definitions. Additional parameters are documented below.
|
||||
* It is assumed that the comparator and size fields of the TreeMap are
|
||||
* already set prior to calling this method. (It ignores both fields.)
|
||||
*
|
||||
* @param level the current level of tree. Initial call should be 0.
|
||||
* @param lo the first element index of this subtree. Initial should be 0.
|
||||
* @param hi the last element index of this subtree. Initial should be
|
||||
* size-1.
|
||||
* @param redLevel the level at which nodes should be red.
|
||||
* Must be equal to computeRedLevel for tree of this size.
|
||||
*/
|
||||
private static RBNode buildFromSorted(int level, int lo, int hi,
|
||||
int redLevel,
|
||||
java.io.ObjectInputStream str)
|
||||
throws java.io.IOException, ClassNotFoundException {
|
||||
/*
|
||||
* Strategy: The root is the middlemost element. To get to it, we
|
||||
* have to first recursively construct the entire left subtree,
|
||||
* so as to grab all of its elements. We can then proceed with right
|
||||
* subtree.
|
||||
*
|
||||
* The lo and hi arguments are the minimum and maximum
|
||||
* indices to pull out of the iterator or stream for current subtree.
|
||||
* They are not actually indexed, we just proceed sequentially,
|
||||
* ensuring that items are extracted in corresponding order.
|
||||
*/
|
||||
|
||||
if (hi < lo) return null;
|
||||
|
||||
int mid = (lo + hi) / 2;
|
||||
|
||||
RBNode left = null;
|
||||
if (lo < mid) {
|
||||
left = buildFromSorted(level+1, lo, mid - 1, redLevel, str);
|
||||
}
|
||||
// extract from stream
|
||||
long key = str.readLong();
|
||||
Object value = str.readObject();
|
||||
|
||||
RBNode middle = new RBNode(key, value, null);
|
||||
|
||||
// color nodes in non-full bottommost level red
|
||||
if (level == redLevel)
|
||||
middle.color = RED;
|
||||
|
||||
if (left != null) {
|
||||
middle.left = left;
|
||||
left.parent = middle;
|
||||
}
|
||||
|
||||
if (mid < hi) {
|
||||
RBNode right = buildFromSorted(level+1, mid+1, hi, redLevel, str);
|
||||
middle.right = right;
|
||||
right.parent = middle;
|
||||
}
|
||||
|
||||
return middle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the level down to which to assign all nodes BLACK. This is the
|
||||
* last `full' level of the complete binary tree produced by
|
||||
* buildTree. The remaining nodes are colored RED. (This makes a `nice'
|
||||
* set of color assignments wrt future insertions.) This level number is
|
||||
* computed by finding the number of splits needed to reach the zeroeth
|
||||
* node. (The answer is ~lg(N), but in any case must be computed by same
|
||||
* quick O(lg(N)) loop.)
|
||||
*/
|
||||
private static int computeRedLevel(int sz) {
|
||||
int level = 0;
|
||||
for (int m = sz - 1; m >= 0; m = m / 2 - 1)
|
||||
level++;
|
||||
return level;
|
||||
}
|
||||
|
||||
/**
|
||||
* The Iterator implementation for iterating over the objects in the tree.
|
||||
*/
|
||||
class LongRedBlackTreeIterator implements Iterator<Object> {
|
||||
|
||||
private long mod; // the tree modification number when this iterator
|
||||
// was created.
|
||||
private RBNode cur; // Keeps the state of the iterator. This node
|
||||
// is always the node whose object should be returned
|
||||
// on the next call to "next()". It will be null
|
||||
// when we reach the end.
|
||||
|
||||
/**
|
||||
* Constructor set cur to the first node. (The leftmost node in the tree.)
|
||||
*/
|
||||
public LongRedBlackTreeIterator() {
|
||||
mod = modification;
|
||||
cur = root;
|
||||
|
||||
// set cur to leftmost node
|
||||
|
||||
// if tree is empty just return and let cur be null;
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
while(cur.left != null) {
|
||||
cur = cur.left;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* returns true if there are more objects to be returned.
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
if (modification != mod) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
// as long as cur is not null, we have more objects.
|
||||
return cur != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next object in the sorted list.
|
||||
*/
|
||||
public Object next() {
|
||||
if (modification != mod) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
// cur is null, so there are no more objects.
|
||||
if (cur == null) {
|
||||
return null;
|
||||
}
|
||||
// ok, just return the object for the current node, but first
|
||||
// lets set up for the next time.
|
||||
Object obj = cur.value;
|
||||
findNext();
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the last retrieved object from the list. Not supported.
|
||||
*/
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
/**
|
||||
* finds the next node in the tree using an in-order traversal.
|
||||
*/
|
||||
private void findNext() {
|
||||
// if there is a right branch process that
|
||||
if (cur.right != null) {
|
||||
cur = cur.right;
|
||||
while(cur.left != null) {
|
||||
cur = cur.left;
|
||||
}
|
||||
return;
|
||||
}
|
||||
// otherwise go up until we exit a left branch
|
||||
RBNode child = cur;
|
||||
cur = cur.parent;
|
||||
while (cur != null) {
|
||||
if (cur.left == child) {
|
||||
return;
|
||||
}
|
||||
child = cur;
|
||||
cur = cur.parent;
|
||||
}
|
||||
// cur is null, so there are no more nodes to process.
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Class that implements a hashtable with long keys and short values.
|
||||
*/
|
||||
|
||||
|
||||
public class LongShortHashtable implements Serializable {
|
||||
|
||||
private LongKeyIndexer indexer; // allocates and manages index values for keys.
|
||||
private short[] values; // array for holding the values.
|
||||
private int capacity; // current capacity
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor creates a table with an initial default capacity.
|
||||
*/
|
||||
public LongShortHashtable() {
|
||||
this((short)3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a table with an initial given capacity. The capacity
|
||||
* will be adjusted to the next highest prime in the PRIMES table.
|
||||
* @param capacity the initial capacity.
|
||||
*/
|
||||
public LongShortHashtable(int capacity) {
|
||||
|
||||
capacity = Prime.nextPrime(capacity);
|
||||
this.capacity = capacity;
|
||||
indexer = new LongKeyIndexer(capacity);
|
||||
values = new short[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key/value pair to the hashtable. If the key is already in the table,
|
||||
* the old value is replaced with the new value. If the hashtable is already
|
||||
* full, the hashtable will attempt to approximately double in size
|
||||
* (it will use a prime number), and all the current entries will
|
||||
* be rehashed.
|
||||
* @param key the key to associate with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
* @exception ArrayIndexOutOfBoundsException thrown if the maximum capacity is
|
||||
* reached.
|
||||
*/
|
||||
public void put(long key, short value) {
|
||||
|
||||
int index = indexer.put(key);
|
||||
|
||||
// make sure there is room
|
||||
if (index >= capacity) {
|
||||
grow();
|
||||
}
|
||||
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
* @param key the key whose associated value is to be returned.
|
||||
* @exception NoValueException thrown if there is no value for the given key.
|
||||
*/
|
||||
public short get(long key) throws NoValueException {
|
||||
int index = indexer.get(key);
|
||||
if (index < 0) {
|
||||
throw NoValueException.noValueException;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the hashtable
|
||||
* @param key key to be removed from the hashtable.
|
||||
* @return true if key is found and removed, false otherwise.
|
||||
*/
|
||||
public boolean remove(long key) {
|
||||
if (indexer.remove(key) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the hashtable.
|
||||
*/
|
||||
public void removeAll() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in the hashtable.
|
||||
* @param key the key whose presence in this map is to be tested.
|
||||
*/
|
||||
public boolean contains(long key) {
|
||||
return indexer.get(key) >=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of key/value pairs stored in the hashtable.
|
||||
*/
|
||||
public int size() {
|
||||
return indexer.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the long keys.
|
||||
*/
|
||||
public long[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the hashtable to allow more entries.
|
||||
*/
|
||||
private void grow() {
|
||||
|
||||
capacity = indexer.getCapacity();
|
||||
|
||||
short[] oldValues = values;
|
||||
|
||||
values = new short[capacity];
|
||||
|
||||
System.arraycopy(oldValues,0,values,0,oldValues.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Class that implements a hashtable with short keys and byte values.
|
||||
*/
|
||||
|
||||
|
||||
public class ShortByteHashtable implements Serializable {
|
||||
|
||||
private ShortKeyIndexer indexer; // allocates and manages index values for keys.
|
||||
private byte[] values; // array for holding the values.
|
||||
private int capacity; // current capacity
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor creates a table with an initial default capacity.
|
||||
*/
|
||||
public ShortByteHashtable() {
|
||||
this((short)3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a table with an initial given capacity. The capacity
|
||||
* will be adjusted to the next highest prime in the PRIMES table.
|
||||
* @param capacity the initial capacity.
|
||||
*/
|
||||
public ShortByteHashtable(short capacity) {
|
||||
|
||||
capacity = (short)Prime.nextPrime(capacity);
|
||||
this.capacity = capacity;
|
||||
indexer = new ShortKeyIndexer(capacity);
|
||||
values = new byte[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key/value pair to the hashtable. If the key is already in the table,
|
||||
* the old value is replaced with the new value. If the hashtable is already
|
||||
* full, the hashtable will attempt to approximately double in size
|
||||
* (it will use a prime number), and all the current entries will
|
||||
* be rehashed.
|
||||
* @param key the key to associate with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
* @exception ArrayIndexOutOfBoundsException thrown if the maximum capacity is
|
||||
* reached.
|
||||
*/
|
||||
public void put(short key, byte value) {
|
||||
|
||||
int index = indexer.put(key);
|
||||
|
||||
// make sure there is room
|
||||
if (index >= capacity) {
|
||||
grow();
|
||||
}
|
||||
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
* @param key the key whose associated value is to be returned.
|
||||
*/
|
||||
public byte get(short key) throws NoValueException {
|
||||
int index = indexer.get(key);
|
||||
if (index < 0) {
|
||||
throw NoValueException.noValueException;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the hashtable
|
||||
* @param key key to be removed from the hashtable.
|
||||
* @return true if key is found and removed, false otherwise.
|
||||
*/
|
||||
public boolean remove(short key) {
|
||||
if (indexer.remove(key) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the hashtable.
|
||||
*/
|
||||
public void removeAll() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in the hashtable.
|
||||
* @param key the key whose presence in this map is to be tested.
|
||||
*/
|
||||
public boolean contains(short key) {
|
||||
return indexer.get(key) >=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of key/value pairs stored in the hashtable.
|
||||
*/
|
||||
public int size() {
|
||||
return indexer.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the short keys.
|
||||
*/
|
||||
public short[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the hashtable to allow more entries.
|
||||
*/
|
||||
private void grow() {
|
||||
|
||||
capacity = indexer.getCapacity();
|
||||
|
||||
byte[] oldValues = values;
|
||||
|
||||
values = new byte[capacity];
|
||||
|
||||
System.arraycopy(oldValues,0,values,0,oldValues.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
* REVIEWED: YES
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* Class to generate short indexes to be used for arrays or tables. If a location
|
||||
* or entry in a table becomes available, the index for that location is released.
|
||||
* This class manages the use and reuse of those indexes.
|
||||
*/
|
||||
public class ShortIndexManager implements Serializable {
|
||||
private final static long serialVersionUID = 1;
|
||||
|
||||
private short nextIndex; // the smallest index that has never been used.
|
||||
private ArrayList<Short> freeList;
|
||||
|
||||
/**
|
||||
* Constructs an ShortIndexManager.
|
||||
*/
|
||||
public ShortIndexManager() {
|
||||
nextIndex = 0;
|
||||
freeList = new ArrayList<Short>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest unused index value.
|
||||
* @exception IndexOutOfBoundsException thrown if there are no unused
|
||||
* indexes.
|
||||
*/
|
||||
public short allocate() {
|
||||
if (freeList.size() == 0) {
|
||||
if (nextIndex < 0) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
short temp = nextIndex;
|
||||
nextIndex++;
|
||||
return temp;
|
||||
}
|
||||
Short s = freeList.remove(freeList.size()-1);
|
||||
return s.shortValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the index value so that it can be reused.
|
||||
* @param index the index to be free'd for reuse.
|
||||
*/
|
||||
public void deallocate(short index) {
|
||||
if ((index < 0) || (index >= nextIndex)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
|
||||
if (index == nextIndex-1) {
|
||||
nextIndex--;
|
||||
}
|
||||
else {
|
||||
freeList.add(new Short(index));
|
||||
}
|
||||
|
||||
// all nodes are free, so reset...
|
||||
if (nextIndex == freeList.size()) {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* frees all index values.
|
||||
*/
|
||||
public void clear() {
|
||||
nextIndex = 0;
|
||||
freeList.clear();
|
||||
}
|
||||
}
|
|
@ -1,145 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Class that implements a hashtable with short keys and int values.
|
||||
*/
|
||||
|
||||
|
||||
public class ShortIntHashtable implements Serializable {
|
||||
|
||||
private ShortKeyIndexer indexer; // allocates and manages index values for keys.
|
||||
private int[] values; // array for holding the values.
|
||||
private int capacity; // current capacity
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor creates a table with an initial default capacity.
|
||||
*/
|
||||
public ShortIntHashtable() {
|
||||
this((short)3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a table with an initial given capacity. The capacity
|
||||
* will be adjusted to the next highest prime in the PRIMES table.
|
||||
* @param capacity the initial capacity.
|
||||
*/
|
||||
public ShortIntHashtable(short capacity) {
|
||||
|
||||
capacity = (short)Prime.nextPrime(capacity);
|
||||
this.capacity = capacity;
|
||||
indexer = new ShortKeyIndexer(capacity);
|
||||
values = new int[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key/value pair to the hashtable. If the key is already in the table,
|
||||
* the old value is replaced with the new value. If the hashtable is already
|
||||
* full, the hashtable will attempt to approximately double in size
|
||||
* (it will use a prime number), and all the current entries will
|
||||
* be rehashed.
|
||||
* @param key the key to associate with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
* @exception ArrayIndexOutOfBoundsException thrown if the maximum capacity is
|
||||
* reached.
|
||||
*/
|
||||
public void put(short key, int value) {
|
||||
|
||||
int index = indexer.put(key);
|
||||
|
||||
// make sure there is room
|
||||
if (index >= capacity) {
|
||||
grow();
|
||||
}
|
||||
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
* @param key the key whose associated value is to be returned.
|
||||
*/
|
||||
public int get(short key) throws NoValueException {
|
||||
int index = indexer.get(key);
|
||||
if (index < 0) {
|
||||
throw NoValueException.noValueException;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the hashtable
|
||||
* @param key key to be removed from the hashtable.
|
||||
* @return true if key is found and removed, false otherwise.
|
||||
*/
|
||||
public boolean remove(short key) {
|
||||
if (indexer.remove(key) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the hashtable.
|
||||
*/
|
||||
public void removeAll() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in the hashtable.
|
||||
* @param key the key whose presence in this map is to be tested.
|
||||
*/
|
||||
public boolean contains(short key) {
|
||||
return indexer.get(key) >=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of key/value pairs stored in the hashtable.
|
||||
*/
|
||||
public int size() {
|
||||
return indexer.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the short keys.
|
||||
*/
|
||||
public short[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the hashtable to allow more entries.
|
||||
*/
|
||||
private void grow() {
|
||||
|
||||
capacity = indexer.getCapacity();
|
||||
|
||||
int[] oldValues = values;
|
||||
|
||||
values = new int[capacity];
|
||||
|
||||
System.arraycopy(oldValues,0,values,0,oldValues.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Manages an array of lists of longs. It provides methods for
|
||||
* adding, deleting, and retrieving long values for specific lists.
|
||||
*/
|
||||
public class ShortLongIndexedList implements Serializable {
|
||||
|
||||
private final static short DEFAULT_CAPACITY=16;
|
||||
|
||||
private long []values; // array to store the values
|
||||
private ShortListIndexer indexer; // keeps track of lists of indexes into values array.
|
||||
private int capacity; // current size of values array.
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param numLists initial number of lists.
|
||||
*/
|
||||
public ShortLongIndexedList (short numLists) {
|
||||
|
||||
indexer = new ShortListIndexer(numLists, DEFAULT_CAPACITY);
|
||||
capacity = indexer.getCapacity();
|
||||
values = new long[capacity];
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the front of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be added.
|
||||
* @param value the value to be added to the list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void add(short listID, long value) {
|
||||
|
||||
int index = indexer.add(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a value to the back of the list indexed by listID.
|
||||
* @param listID specifies which list the value is to be appended.
|
||||
* @param value the value to be added to the linked list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void append(short listID, long value) {
|
||||
|
||||
int index = indexer.append(listID);
|
||||
if (index >= capacity) {
|
||||
grow(indexer.getCapacity());
|
||||
}
|
||||
values[index] = value;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove the value from the list indexed by listID.
|
||||
* @param listID the id of the list from which to remove the value.
|
||||
* @param value the value to be removed from the specified list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean remove(short listID, long value) {
|
||||
|
||||
// find index that contains value
|
||||
short index = findIndex(listID, value);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
indexer.remove(listID, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all values from a specified list.
|
||||
* @param listID the id of the list to be cleared.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public void removeAll(short listID) {
|
||||
|
||||
indexer.removeAll(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the value exists in the specified list.
|
||||
* @param listID the id of the list to be tested for the given value.
|
||||
* @param value the value to search for in the specified list.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public boolean contains(short listID, long value) {
|
||||
int index = findIndex(listID, value);
|
||||
if (index == -1) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of values in the specified list.
|
||||
* @param listID the id of the list for which to get the count.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public int getCount(short listID) {
|
||||
return indexer.getListSize(listID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get values stored in the specified list.
|
||||
* @param listID the id of the list from which to get the values.
|
||||
* @exception IndexOutOfBoundsException thrown if the listID
|
||||
* is not in the range [0, numLists].
|
||||
*/
|
||||
public long[] get(short listID) {
|
||||
|
||||
int count = indexer.getListSize(listID);
|
||||
|
||||
long []lvalues = new long[count];
|
||||
|
||||
short p = indexer.first(listID);
|
||||
|
||||
for(int i=0;i<count;i++) {
|
||||
lvalues[i] = values[p];
|
||||
p = indexer.next(p);
|
||||
}
|
||||
|
||||
return lvalues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of lists.
|
||||
*/
|
||||
public short getNumLists() {
|
||||
return indexer.getNumLists();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the number of lists.
|
||||
* @param numLists the new number of lists.
|
||||
*/
|
||||
public void growNumLists(short numLists) {
|
||||
indexer.growNumLists(numLists);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes all values from all lists.
|
||||
*/
|
||||
public void clear() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Increase the capacity for the linked list of values.
|
||||
*/
|
||||
private void grow(int newCapacity) {
|
||||
|
||||
capacity = newCapacity;
|
||||
long[] tempValues = new long[newCapacity];
|
||||
|
||||
System.arraycopy(values, 0, tempValues, 0, values.length);
|
||||
|
||||
values = tempValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the index of the value in the list specified by listID.
|
||||
*/
|
||||
private short findIndex(short listID, long value) {
|
||||
|
||||
short p = indexer.first(listID);
|
||||
|
||||
while (p != -1) {
|
||||
if (values[p] == value) {
|
||||
return p;
|
||||
}
|
||||
p = indexer.next(p);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
|
@ -1,153 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
import java.util.Iterator;
|
||||
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Class that implements a hashtable with String keys and long values.
|
||||
*/
|
||||
|
||||
|
||||
public class StringLongHashtable implements Serializable {
|
||||
|
||||
private StringKeyIndexer indexer; // allocates and manages index values for keys.
|
||||
private long[] values; // array for holding the values.
|
||||
private int capacity; // current capacity
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor creates a table with an initial default capacity.
|
||||
*/
|
||||
public StringLongHashtable() {
|
||||
this((short)3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a table with an initial given capacity. The capacity
|
||||
* will be adjusted to the next highest prime in the PRIMES table.
|
||||
* @param capacity the initial capacity.
|
||||
*/
|
||||
public StringLongHashtable(int capacity) {
|
||||
|
||||
capacity = Prime.nextPrime(capacity);
|
||||
this.capacity = capacity;
|
||||
indexer = new StringKeyIndexer(capacity);
|
||||
values = new long[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key/value pair to the hashtable. If the key is already in the table,
|
||||
* the old value is replaced with the new value. If the hashtable is already
|
||||
* full, the hashtable will attempt to approximately double in size
|
||||
* (it will use a prime number), and all the current entries will
|
||||
* be rehashed.
|
||||
* @param key the key to associate with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
* @exception ArrayIndexOutOfBoundsException thrown if the maximum capacity is
|
||||
* reached.
|
||||
*/
|
||||
public void put(String key, long value) {
|
||||
|
||||
int index = indexer.put(key);
|
||||
|
||||
// make sure there is room
|
||||
if (index >= capacity) {
|
||||
grow();
|
||||
}
|
||||
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
* @param key the key whose assocated value is to be returned.
|
||||
* @exception NoValueException thrown if there is no value for the given key.
|
||||
*/
|
||||
public long get(String key) throws NoValueException {
|
||||
int index = indexer.get(key);
|
||||
if (index < 0) {
|
||||
throw NoValueException.noValueException;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator over the keys in this hashtable.
|
||||
*/
|
||||
public Iterator<String> getKeyIterator() {
|
||||
return indexer.getKeyIterator();
|
||||
}
|
||||
/**
|
||||
* Removes a key from the hashtable
|
||||
* @param key key to be removed from the hashtable.
|
||||
* @return true if key is found and removed, false otherwise.
|
||||
*/
|
||||
public boolean remove(String key) {
|
||||
if (indexer.remove(key) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the hashtable.
|
||||
*/
|
||||
public void removeAll() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in the hashtable.
|
||||
* @param key the key whose presence in this map is to be tested.
|
||||
*/
|
||||
public boolean contains(String key) {
|
||||
return indexer.get(key) >=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of key/value pairs stored in the hashtable.
|
||||
*/
|
||||
public int size() {
|
||||
return indexer.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the String keys.
|
||||
*/
|
||||
public String[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the hashtable to allow more entries.
|
||||
*/
|
||||
private void grow() {
|
||||
|
||||
capacity = indexer.getCapacity();
|
||||
|
||||
long[] oldValues = values;
|
||||
|
||||
values = new long[capacity];
|
||||
|
||||
System.arraycopy(oldValues,0,values,0,oldValues.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,146 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.io.Serializable;
|
||||
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
/**
|
||||
* Class that implements a hashtable with String keys and short values.
|
||||
*/
|
||||
|
||||
|
||||
public class StringShortHashtable implements Serializable {
|
||||
|
||||
private StringKeyIndexer indexer; // allocates and manages index values for keys.
|
||||
private short[] values; // array for holding the values.
|
||||
private int capacity; // current capacity
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor creates a table with an initial default capacity.
|
||||
*/
|
||||
public StringShortHashtable() {
|
||||
this((short)3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor creates a table with an initial given capacity. The capacity
|
||||
* will be adjusted to the next highest prime in the PRIMES table.
|
||||
* @param capacity the initial capacity.
|
||||
*/
|
||||
public StringShortHashtable(int capacity) {
|
||||
|
||||
capacity = Prime.nextPrime(capacity);
|
||||
this.capacity = capacity;
|
||||
indexer = new StringKeyIndexer(capacity);
|
||||
values = new short[capacity];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds a key/value pair to the hashtable. If the key is already in the table,
|
||||
* the old value is replaced with the new value. If the hashtable is already
|
||||
* full, the hashtable will attempt to approximately double in size
|
||||
* (it will use a prime number), and all the current entries will
|
||||
* be rehashed.
|
||||
* @param key the key to associate with the given value.
|
||||
* @param value the value to associate with the given key.
|
||||
* @exception ArrayIndexOutOfBoundsException thrown if the maximum capacity is
|
||||
* reached.
|
||||
*/
|
||||
public void put(String key, short value) {
|
||||
|
||||
int index = indexer.put(key);
|
||||
|
||||
// make sure there is room
|
||||
if (index >= capacity) {
|
||||
grow();
|
||||
}
|
||||
|
||||
values[index] = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value for the given key.
|
||||
* @param key the key whose assocated value is to be returned.
|
||||
* @exception NoValueException thrown if there is no value for the given key.
|
||||
*/
|
||||
public short get(String key) throws NoValueException {
|
||||
int index = indexer.get(key);
|
||||
if (index < 0) {
|
||||
throw NoValueException.noValueException;
|
||||
}
|
||||
return values[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a key from the hashtable
|
||||
* @param key key to be removed from the hashtable.
|
||||
* @return true if key is found and removed, false otherwise.
|
||||
*/
|
||||
public boolean remove(String key) {
|
||||
if (indexer.remove(key) < 0) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove all entries from the hashtable.
|
||||
*/
|
||||
public void removeAll() {
|
||||
indexer.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given key is in the hashtable.
|
||||
* @param key the key whose presence is this map is to be tested.
|
||||
*/
|
||||
public boolean contains(String key) {
|
||||
return indexer.get(key) >=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of key/value pairs stored in the hashtable.
|
||||
*/
|
||||
public int size() {
|
||||
return indexer.getSize();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array containing all the String keys.
|
||||
*/
|
||||
public String[] getKeys() {
|
||||
return indexer.getKeys();
|
||||
}
|
||||
|
||||
/**
|
||||
* resizes the hashtable to allow more entries.
|
||||
*/
|
||||
private void grow() {
|
||||
|
||||
capacity = indexer.getCapacity();
|
||||
|
||||
short[] oldValues = values;
|
||||
|
||||
values = new short[capacity];
|
||||
|
||||
System.arraycopy(oldValues,0,values,0,oldValues.length);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,546 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
|
||||
public class AdjacentSortedRangeListTest extends AbstractGenericTest {
|
||||
private AdjacentSortedRangeList list;
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AdjacentSortedRangeListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
list = new AdjacentSortedRangeList();
|
||||
}
|
||||
@Test
|
||||
public void testAdd1() {
|
||||
list.addRange(5, 7);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
assertEquals(new Range(5, 7), list.getRanges().next());
|
||||
|
||||
list.addRange(20, 22);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(5, 7), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
|
||||
list.addRange(0,2);
|
||||
assertEquals(3, list.getNumRanges());
|
||||
it = list.getRanges();
|
||||
assertEquals(new Range(0, 2), it.next());
|
||||
assertEquals(new Range(5, 7), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
|
||||
list.addRange(12,12);
|
||||
assertEquals(4, list.getNumRanges());
|
||||
it = list.getRanges();
|
||||
assertEquals(new Range(0, 2), it.next());
|
||||
assertEquals(new Range(5, 7), it.next());
|
||||
assertEquals(new Range(12, 12), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
|
||||
list.addRange(23,27);
|
||||
assertEquals(5, list.getNumRanges());
|
||||
it = list.getRanges();
|
||||
assertEquals(new Range(0, 2), it.next());
|
||||
assertEquals(new Range(5, 7), it.next());
|
||||
assertEquals(new Range(12, 12), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
assertEquals(new Range(23, 27), it.next());
|
||||
|
||||
list.addRange(3,4);
|
||||
assertEquals(6, list.getNumRanges());
|
||||
it = list.getRanges();
|
||||
assertEquals(new Range(0, 2), it.next());
|
||||
assertEquals(new Range(3, 4), it.next());
|
||||
assertEquals(new Range(5, 7), it.next());
|
||||
assertEquals(new Range(12, 12), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
assertEquals(new Range(23, 27), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd2() {
|
||||
list.addRange(3,7);
|
||||
list.addRange(4,10);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
assertEquals(new Range(3, 10), list.getRanges().next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd3() {
|
||||
list.addRange(4,10);
|
||||
list.addRange(3, 7);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
assertEquals(new Range(3, 10), list.getRanges().next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd4() {
|
||||
list.addRange(3,7);
|
||||
list.addRange(8,10);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(3, 7), it.next());
|
||||
assertEquals(new Range(8, 10), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd5() {
|
||||
list.addRange(8,10);
|
||||
list.addRange(3,7);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(3, 7), it.next());
|
||||
assertEquals(new Range(8, 10), it.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdd6() {
|
||||
list.addRange(3,7);
|
||||
list.addRange(8,10);
|
||||
list.addRange(4,12);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
assertEquals(new Range(3, 12), list.getRanges().next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd7() {
|
||||
list.addRange(12, 20);
|
||||
list.addRange(14, 16);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
assertEquals(new Range(12, 20), list.getRanges().next());
|
||||
}
|
||||
@Test
|
||||
public void testAdd8() {
|
||||
list.addRange(0,4);
|
||||
list.addRange(6, 10);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
list.addRange(5,5);
|
||||
assertEquals(3, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 4), it.next());
|
||||
assertEquals(new Range(5, 5), it.next());
|
||||
assertEquals(new Range(6, 10), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testAddNegFirst() {
|
||||
list.addRange(-20480, -20352); // -20480, -20352
|
||||
list.addRange(-16384, -15824); //
|
||||
list.addRange(-16128, -15616);
|
||||
list.addRange(-12288, -12235);
|
||||
list.addRange(-12234, -12224);
|
||||
list.addRange(-8192, 184565760);
|
||||
assertEquals(5, list.getNumRanges());
|
||||
assertEquals(new Range(-20480, -20352), list.getRange(0));
|
||||
assertEquals(new Range(-16384, -15616), list.getRange(1));
|
||||
assertEquals(new Range(-12288, -12235), list.getRange(2));
|
||||
assertEquals(new Range(-12234, -12224), list.getRange(3));
|
||||
assertEquals(new Range(-8192, 184565760), list.getRange(4));
|
||||
list.addRange(5,5);
|
||||
list.addRange(201334784, 201338880);
|
||||
assertEquals(6, list.getNumRanges());
|
||||
assertEquals(new Range(-20480, -20352), list.getRange(0));
|
||||
assertEquals(new Range(-16384, -15616), list.getRange(1));
|
||||
assertEquals(new Range(-12288, -12235), list.getRange(2));
|
||||
assertEquals(new Range(-12234, -12224), list.getRange(3));
|
||||
assertEquals(new Range(-8192, 184565760), list.getRange(4));
|
||||
assertEquals(new Range(201334784, 201338880), list.getRange(5));
|
||||
}
|
||||
@Test
|
||||
public void testAddPosFirst() {
|
||||
list.addRange(0, 4);
|
||||
list.addRange(6, 10);
|
||||
list.addRange(3500, 4400);
|
||||
list.addRange(135676, 149987);
|
||||
assertEquals(4, list.getNumRanges());
|
||||
assertEquals(new Range(0, 4), list.getRange(0));
|
||||
assertEquals(new Range(6, 10), list.getRange(1));
|
||||
assertEquals(new Range(3500, 4400), list.getRange(2));
|
||||
assertEquals(new Range(135676, 149987), list.getRange(3));
|
||||
|
||||
list.addRange(-20480, -20352);
|
||||
list.addRange(-16384, -15824);
|
||||
list.addRange(-16128, -15616);
|
||||
list.addRange(-12288, -12235);
|
||||
list.addRange(-12234, -12224);
|
||||
list.addRange(-8192, 3);
|
||||
assertEquals(8, list.getNumRanges());
|
||||
assertEquals(new Range(-20480, -20352), list.getRange(0));
|
||||
assertEquals(new Range(-16384, -15616), list.getRange(1));
|
||||
assertEquals(new Range(-12288, -12235), list.getRange(2));
|
||||
assertEquals(new Range(-12234, -12224), list.getRange(3));
|
||||
assertEquals(new Range(-8192, 4), list.getRange(4));
|
||||
assertEquals(new Range(6, 10), list.getRange(5));
|
||||
assertEquals(new Range(3500, 4400), list.getRange(6));
|
||||
assertEquals(new Range(135676, 149987), list.getRange(7));
|
||||
|
||||
list.addRange(4200, 4800);
|
||||
list.addRange(149988, 150000);
|
||||
assertEquals(9, list.getNumRanges());
|
||||
assertEquals(new Range(-20480, -20352), list.getRange(0));
|
||||
assertEquals(new Range(-16384, -15616), list.getRange(1));
|
||||
assertEquals(new Range(-12288, -12235), list.getRange(2));
|
||||
assertEquals(new Range(-12234, -12224), list.getRange(3));
|
||||
assertEquals(new Range(-8192, 4), list.getRange(4));
|
||||
assertEquals(new Range(6, 10), list.getRange(5));
|
||||
assertEquals(new Range(3500, 4800), list.getRange(6));
|
||||
assertEquals(new Range(135676, 149987), list.getRange(7));
|
||||
assertEquals(new Range(149988, 150000), list.getRange(8));
|
||||
}
|
||||
@Test
|
||||
public void testRemove1() {
|
||||
list.addRange(0,10);
|
||||
list.removeRange(5,5);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 4), it.next());
|
||||
assertEquals(new Range(6, 10), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove2() {
|
||||
list.addRange(0,2);
|
||||
list.addRange(6,8);
|
||||
list.addRange(12, 14);
|
||||
list.removeRange(6,7);
|
||||
assertEquals(3, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 2), it.next());
|
||||
assertEquals(new Range(8, 8), it.next());
|
||||
assertEquals(new Range(12, 14), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove3() {
|
||||
list.addRange(0,2);
|
||||
list.addRange(6,8);
|
||||
list.addRange(12, 14);
|
||||
list.removeRange(1,50);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 0), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove4() {
|
||||
list.addRange(0,2);
|
||||
list.addRange(6,8);
|
||||
list.addRange(12, 14);
|
||||
list.removeRange(0,11);
|
||||
assertEquals(1, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(12, 14), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove5() {
|
||||
list.addRange(0,4);
|
||||
list.addRange(5,10);
|
||||
list.removeRange(5,5);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 4), it.next());
|
||||
assertEquals(new Range(6, 10), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove6() {
|
||||
list.addRange(0,4);
|
||||
list.addRange(7,10);
|
||||
list.removeRange(5,5);
|
||||
assertEquals(2, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(0, 4), it.next());
|
||||
assertEquals(new Range(7, 10), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove7() {
|
||||
list.addRange(0,4);
|
||||
list.addRange(7,10);
|
||||
list.addRange(11,14);
|
||||
list.addRange(25,30);
|
||||
list.addRange(40,44);
|
||||
list.addRange(45,49);
|
||||
assertEquals(6, list.getNumRanges());
|
||||
list.removeRange(26,27);
|
||||
list.removeRange(38,52);
|
||||
list.removeRange(3,8);
|
||||
assertEquals(5, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range( 0, 2), it.next());
|
||||
assertEquals(new Range( 9, 10), it.next());
|
||||
assertEquals(new Range(11, 14), it.next());
|
||||
assertEquals(new Range(25, 25), it.next());
|
||||
assertEquals(new Range(28, 30), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testRemove8() {
|
||||
list.addRange(Integer.MIN_VALUE, Integer.MIN_VALUE+5);
|
||||
list.addRange(-466, -460);
|
||||
list.addRange(-12, -11);
|
||||
list.addRange(-10, -5);
|
||||
list.addRange(0,2);
|
||||
list.addRange(6,8);
|
||||
list.addRange(9,11);
|
||||
list.addRange(12, 14);
|
||||
list.removeRange(1, 10);
|
||||
list.removeRange(Integer.MIN_VALUE+3, -8);
|
||||
assertEquals(5, list.getNumRanges());
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(Integer.MIN_VALUE, Integer.MIN_VALUE+2), it.next());
|
||||
assertEquals(new Range(-7, -5), it.next());
|
||||
assertEquals(new Range(0, 0), it.next());
|
||||
assertEquals(new Range(11, 11), it.next());
|
||||
assertEquals(new Range(12, 14), it.next());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testContains() {
|
||||
list.addRange(4, 7);
|
||||
list.addRange(10,11);
|
||||
assertTrue(!list.contains(2));
|
||||
assertTrue(!list.contains(3));
|
||||
assertTrue(list.contains(4));
|
||||
assertTrue(list.contains(5));
|
||||
assertTrue(list.contains(6));
|
||||
assertTrue(list.contains(7));
|
||||
assertTrue(!list.contains(8));
|
||||
assertTrue(!list.contains(9));
|
||||
assertTrue(list.contains(10));
|
||||
assertTrue(list.contains(11));
|
||||
assertTrue(!list.contains(12));
|
||||
assertTrue(!list.contains(13));
|
||||
}
|
||||
@Test
|
||||
public void testGetRangeIndex() {
|
||||
list.addRange(2,4);
|
||||
list.addRange(6,8);
|
||||
list.addRange(12,15);
|
||||
|
||||
assertEquals(-1, list.getRangeIndex(0));
|
||||
assertEquals(-1, list.getRangeIndex(1));
|
||||
assertEquals(0, list.getRangeIndex(2));
|
||||
assertEquals(0, list.getRangeIndex(3));
|
||||
assertEquals(0, list.getRangeIndex(4));
|
||||
assertEquals(-2, list.getRangeIndex(5));
|
||||
assertEquals(1, list.getRangeIndex(6));
|
||||
assertEquals(1, list.getRangeIndex(7));
|
||||
assertEquals(1, list.getRangeIndex(8));
|
||||
assertEquals(-3, list.getRangeIndex(9));
|
||||
assertEquals(-3, list.getRangeIndex(10));
|
||||
assertEquals(-3, list.getRangeIndex(11));
|
||||
assertEquals(2, list.getRangeIndex(12));
|
||||
assertEquals(2, list.getRangeIndex(13));
|
||||
assertEquals(2, list.getRangeIndex(14));
|
||||
assertEquals(2, list.getRangeIndex(15));
|
||||
assertEquals(-4, list.getRangeIndex(16));
|
||||
assertEquals(-4, list.getRangeIndex(17));
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testGetRange() {
|
||||
list.addRange(-231, -111);
|
||||
list.addRange(-120, -109);
|
||||
list.addRange(-108, -105);
|
||||
list.addRange(2, 4);
|
||||
list.addRange(6, 8);
|
||||
list.addRange(9, 11);
|
||||
list.addRange(12, 15);
|
||||
assertEquals(new Range(-231, -109), list.getRange(0));
|
||||
assertEquals(new Range(-108, -105), list.getRange(1));
|
||||
assertEquals(new Range(2, 4), list.getRange(2));
|
||||
assertEquals(new Range(6, 8), list.getRange(3));
|
||||
assertEquals(new Range(9, 11), list.getRange(4));
|
||||
assertEquals(new Range(12, 15), list.getRange(5));
|
||||
assertEquals(null, list.getRange(6));
|
||||
}
|
||||
@Test
|
||||
public void testIterator() {
|
||||
list.addRange(Integer.MIN_VALUE, Integer.MIN_VALUE+1);
|
||||
list.addRange(-1234,-1231);
|
||||
list.addRange(-13, -9);
|
||||
list.addRange(-8, -7);
|
||||
list.addRange(-1, 1);
|
||||
list.addRange(3,4);
|
||||
list.addRange(5,5);
|
||||
list.addRange(6,8);
|
||||
list.addRange(12,15);
|
||||
list.addRange(Integer.MAX_VALUE-3, Integer.MAX_VALUE);
|
||||
Iterator<Range> it = list.getRanges();
|
||||
assertEquals(new Range(Integer.MIN_VALUE, Integer.MIN_VALUE+1), it.next());
|
||||
assertEquals(new Range(-1234,-1231), it.next());
|
||||
assertEquals(new Range(-13, -9), it.next());
|
||||
assertEquals(new Range(-8, -7), it.next());
|
||||
assertEquals(new Range(-1, 1), it.next());
|
||||
assertEquals(new Range(3,4), it.next());
|
||||
assertEquals(new Range(5,5), it.next());
|
||||
assertEquals(new Range(6,8), it.next());
|
||||
assertEquals(new Range(12,15), it.next());
|
||||
assertEquals(new Range(Integer.MAX_VALUE-3, Integer.MAX_VALUE), it.next());
|
||||
|
||||
it = list.getRanges(false);
|
||||
assertEquals(new Range(Integer.MAX_VALUE-3, Integer.MAX_VALUE), it.next());
|
||||
assertEquals(new Range(12,15), it.next());
|
||||
assertEquals(new Range(6,8), it.next());
|
||||
assertEquals(new Range(5,5), it.next());
|
||||
assertEquals(new Range(3,4), it.next());
|
||||
assertEquals(new Range(-1, 1), it.next());
|
||||
assertEquals(new Range(-8, -7), it.next());
|
||||
assertEquals(new Range(-13, -9), it.next());
|
||||
assertEquals(new Range(-1234,-1231), it.next());
|
||||
assertEquals(new Range(Integer.MIN_VALUE, Integer.MIN_VALUE+1), it.next());
|
||||
}
|
||||
@Test
|
||||
public void testSize() {
|
||||
list.addRange(Integer.MIN_VALUE, Integer.MIN_VALUE+1);
|
||||
list.addRange(-1234,-1231);
|
||||
list.addRange(-13, -9);
|
||||
list.addRange(-8, -6);
|
||||
list.addRange(-1, 1);
|
||||
list.addRange(3, 4);
|
||||
list.addRange(6, 8);
|
||||
list.addRange(12, 15);
|
||||
list.addRange(16, 19);
|
||||
list.addRange(Integer.MAX_VALUE-1, Integer.MAX_VALUE);
|
||||
assertEquals(32, list.getNumValues());
|
||||
}
|
||||
@Test
|
||||
public void testIntersects() {
|
||||
list.addRange(10,19);
|
||||
list.addRange(40,49);
|
||||
list.addRange(60,69);
|
||||
assertTrue(!list.intersects(0,5));
|
||||
assertTrue(!list.intersects(0,9));
|
||||
assertTrue(!list.intersects(20,39));
|
||||
assertTrue(!list.intersects(50,55));
|
||||
assertTrue(!list.intersects(50,59));
|
||||
assertTrue(!list.intersects(70,80));
|
||||
assertTrue(!list.intersects(100,200));
|
||||
|
||||
assertTrue(list.intersects(0,10));
|
||||
assertTrue(list.intersects(0,11));
|
||||
assertTrue(list.intersects(0,19));
|
||||
assertTrue(list.intersects(0,20));
|
||||
assertTrue(list.intersects(0,21));
|
||||
assertTrue(list.intersects(0,45));
|
||||
assertTrue(list.intersects(0, 100));
|
||||
|
||||
assertTrue(list.intersects(9,10));
|
||||
assertTrue(list.intersects(9,11));
|
||||
assertTrue(list.intersects(9,19));
|
||||
assertTrue(list.intersects(9,20));
|
||||
assertTrue(list.intersects(9,21));
|
||||
assertTrue(list.intersects(9,40));
|
||||
assertTrue(list.intersects(9,100));
|
||||
|
||||
assertTrue(list.intersects(10,10));
|
||||
assertTrue(list.intersects(10,11));
|
||||
assertTrue(list.intersects(10,19));
|
||||
assertTrue(list.intersects(10,20));
|
||||
assertTrue(list.intersects(10,21));
|
||||
assertTrue(list.intersects(10,40));
|
||||
assertTrue(list.intersects(10,100));
|
||||
|
||||
assertTrue(list.intersects(11,11));
|
||||
assertTrue(list.intersects(11,19));
|
||||
assertTrue(list.intersects(11,20));
|
||||
assertTrue(list.intersects(11,21));
|
||||
assertTrue(list.intersects(11,40));
|
||||
assertTrue(list.intersects(11,100));
|
||||
|
||||
assertTrue(list.intersects(15,16));
|
||||
assertTrue(list.intersects(15,19));
|
||||
assertTrue(list.intersects(15,20));
|
||||
assertTrue(list.intersects(15,21));
|
||||
assertTrue(list.intersects(15,40));
|
||||
assertTrue(list.intersects(15,100));
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testIntersect() {
|
||||
list.addRange(10,19);
|
||||
list.addRange(40,49);
|
||||
list.addRange(60,69);
|
||||
AdjacentSortedRangeList other = new AdjacentSortedRangeList();
|
||||
other.addRange(5,15);
|
||||
other.addRange(38, 52);
|
||||
other.addRange(62,65);
|
||||
AdjacentSortedRangeList intersection = list.intersect(other);
|
||||
Iterator<Range> it = intersection.getRanges();
|
||||
assertEquals(new Range(10,15), it.next());
|
||||
assertEquals(new Range(40, 49), it.next());
|
||||
assertEquals(new Range(62, 65), it.next());
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testIntersect2() {
|
||||
list.addRange(10,19);
|
||||
list.addRange(20,25);
|
||||
list.addRange(40,49);
|
||||
list.addRange(60,69);
|
||||
AdjacentSortedRangeList other = new AdjacentSortedRangeList();
|
||||
other.addRange(5,15);
|
||||
other.addRange(19,22);
|
||||
other.addRange(38,52);
|
||||
other.addRange(62,65);
|
||||
other.addRange(66,67);
|
||||
AdjacentSortedRangeList intersection = list.intersect(other);
|
||||
Iterator<Range> it = intersection.getRanges();
|
||||
assertEquals(new Range(10, 15), it.next());
|
||||
assertEquals(new Range(19, 19), it.next());
|
||||
assertEquals(new Range(20, 22), it.next());
|
||||
assertEquals(new Range(40, 49), it.next());
|
||||
assertEquals(new Range(62, 65), it.next());
|
||||
assertEquals(new Range(66, 67), it.next());
|
||||
|
||||
}
|
||||
@Test
|
||||
public void testIntersectPosAndNeg() {
|
||||
list.addRange(-555666777, -555444333);
|
||||
list.addRange(-555444332, -555444329);
|
||||
list.addRange(-888997890, -888111222);
|
||||
list.addRange(Integer.MIN_VALUE, -2142002000);
|
||||
list.addRange(-987, 234);
|
||||
list.addRange(500, 1500);
|
||||
list.addRange(654321, Integer.MAX_VALUE);
|
||||
AdjacentSortedRangeList other = new AdjacentSortedRangeList();
|
||||
other.addRange(-5,15);
|
||||
other.addRange(38, 48);
|
||||
other.addRange(49, 52);
|
||||
other.addRange(300, 600);
|
||||
other.addRange(-123456789, -111222333);
|
||||
other.addRange(-555777000, -555444888);
|
||||
other.addRange(-555444555, -555444222);
|
||||
other.addRange(-2143002000, -2142001000);
|
||||
AdjacentSortedRangeList intersection = list.intersect(other);
|
||||
Iterator<Range> it = intersection.getRanges();
|
||||
assertEquals(new Range(-2143002000, -2142002000), it.next());
|
||||
assertEquals(new Range(-555666777, -555444888), it.next());
|
||||
assertEquals(new Range(-555444555, -555444333), it.next());
|
||||
assertEquals(new Range(-555444332, -555444329), it.next());
|
||||
assertEquals(new Range(-5,15), it.next());
|
||||
assertEquals(new Range(38, 48), it.next());
|
||||
assertEquals(new Range(49, 52), it.next());
|
||||
assertEquals(new Range(500, 600), it.next());
|
||||
}
|
||||
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class IntIntIndexedListTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public IntIntIndexedListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntIntIndexedList() {
|
||||
|
||||
IntIntIndexedList ilist = new IntIntIndexedList(7);
|
||||
|
||||
System.out.println("Test add to list 0");
|
||||
ilist.add(0,20);
|
||||
ilist.add(0,10);
|
||||
ilist.add(0,0);
|
||||
expect(ilist,0, new int[] {0,10,20}, "Add: ");
|
||||
|
||||
System.out.println("Test append");
|
||||
ilist.append(6,30);
|
||||
ilist.append(6,40);
|
||||
ilist.append(6,50);
|
||||
expect(ilist,0, new int[] {0,10,20}, "Add: ");
|
||||
expect(ilist, 6, new int[] {30,40,50}, "Append");
|
||||
|
||||
|
||||
System.out.println("Test contains");
|
||||
if (!ilist.contains(0,0)) {
|
||||
Assert.fail("list 0 does not contain 0, but it should");
|
||||
}
|
||||
if (!ilist.contains(0,10)) {
|
||||
Assert.fail("list 0 does not contain 10, but it should");
|
||||
}
|
||||
if (!ilist.contains(0,20)) {
|
||||
Assert.fail("list 0 does not contain 20, but it should");
|
||||
}
|
||||
if (ilist.contains(0,30)) {
|
||||
Assert.fail("list 0 contains 30, but it should not");
|
||||
}
|
||||
if (ilist.contains(1,50)) {
|
||||
Assert.fail("list 1 contains 50, but it should not");
|
||||
}
|
||||
if (!ilist.contains(6,50)) {
|
||||
Assert.fail("list 6 does not contain 50, but it should");
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ilist.remove(0,0);
|
||||
ilist.remove(6,50);
|
||||
expect(ilist,0, new int[] {10,20}, "Remove ");
|
||||
expect(ilist, 6, new int[] {30,40}, "Remove ");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ilist.removeAll(0);
|
||||
expect(ilist,0,new int[]{},"RemoveAll ");
|
||||
expect(ilist,1,new int[]{},"RemoveAll ");
|
||||
expect(ilist,6,new int[]{30,40},"RemoveAll ");
|
||||
|
||||
|
||||
|
||||
System.out.println("Test add after removeAll");
|
||||
ilist.add(0,100);
|
||||
ilist.add(0,200);
|
||||
ilist.add(0,300);
|
||||
expect(ilist,0,new int[]{300,200,100}, "Add after removeAll");
|
||||
|
||||
ilist.removeAll(0);
|
||||
ilist.removeAll(6);
|
||||
System.out.println("Test growing the number of lists");
|
||||
for(int i=0;i<ilist.getNumLists();i++) {
|
||||
for(int j=0;j<10;j++) {
|
||||
ilist.append(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
ilist.growNumLists(13);
|
||||
for(int i=0;i<13;i++) {
|
||||
if (i < 7) {
|
||||
expect(ilist,i,new int[]{0,1,2,3,4,5,6,7,8,9}, "Grow lists ");
|
||||
}
|
||||
else {
|
||||
expect(ilist,i,new int[]{},"Grow Lists ");
|
||||
}
|
||||
}
|
||||
}// end doTest()
|
||||
|
||||
public static void expect(IntIntIndexedList ilist, int listId, int[] values, String test) {
|
||||
|
||||
int[] listValues = ilist.get(listId);
|
||||
if (values.length != listValues.length) {
|
||||
Assert.fail(test + " expected list "+listId+ "to be of length "+
|
||||
values.length + ", but instead it was of length "+listValues.length);
|
||||
}
|
||||
for(int i=0;i<listValues.length;i++) {
|
||||
if (listValues[i] != values[i]) {
|
||||
Assert.fail(test + "list["+listId+"], item "+i+
|
||||
"should contain "+values[i]+", but instead contains "+listValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class IntLongIndexedListTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public IntLongIndexedListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntLongIndexedList() {
|
||||
|
||||
IntLongIndexedList ilist = new IntLongIndexedList(7);
|
||||
|
||||
System.out.println("Test add to list 0");
|
||||
ilist.add(0,20l);
|
||||
ilist.add(0,10l);
|
||||
ilist.add(0,0l);
|
||||
expect(ilist,0, new long[] {0l,10l,20l}, "Add: ");
|
||||
|
||||
System.out.println("Test append");
|
||||
ilist.append(6,30l);
|
||||
ilist.append(6,40l);
|
||||
ilist.append(6,50l);
|
||||
expect(ilist,0, new long[] {0l,10l,20l}, "Add: ");
|
||||
expect(ilist, 6, new long[] {30l,40l,50l}, "Append");
|
||||
|
||||
|
||||
System.out.println("Test contains");
|
||||
if (!ilist.contains(0,0l)) {
|
||||
Assert.fail("list 0 does not contain 0, but it should");
|
||||
}
|
||||
if (!ilist.contains(0,10l)) {
|
||||
Assert.fail("list 0 does not contain 10, but it should");
|
||||
}
|
||||
if (!ilist.contains(0,20l)) {
|
||||
Assert.fail("list 0 does not contain 20, but it should");
|
||||
}
|
||||
if (ilist.contains(0,30l)) {
|
||||
Assert.fail("list 0 contains 30, but it should not");
|
||||
}
|
||||
if (ilist.contains(1,50l)) {
|
||||
Assert.fail("list 1 contains 50, but it should not");
|
||||
}
|
||||
if (!ilist.contains(6,50l)) {
|
||||
Assert.fail("list 6 does not contain 50, but it should");
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ilist.remove(0,0l);
|
||||
ilist.remove(6,50l);
|
||||
expect(ilist,0, new long[] {10l,20l}, "Remove ");
|
||||
expect(ilist, 6, new long[] {30l,40l}, "Remove ");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ilist.removeAll(0);
|
||||
expect(ilist,0,new long[]{},"RemoveAll ");
|
||||
expect(ilist,1,new long[]{},"RemoveAll ");
|
||||
expect(ilist,6,new long[]{30,40},"RemoveAll ");
|
||||
|
||||
|
||||
|
||||
System.out.println("Test add after removeAll");
|
||||
ilist.add(0,100l);
|
||||
ilist.add(0,200l);
|
||||
ilist.add(0,300l);
|
||||
expect(ilist,0,new long[]{300l,200l,100l}, "Add after removeAll");
|
||||
|
||||
ilist.removeAll(0);
|
||||
ilist.removeAll(6);
|
||||
System.out.println("Test growing the number of lists");
|
||||
for(int i=0;i<ilist.getNumLists();i++) {
|
||||
for(long j=0;j<10;j++) {
|
||||
ilist.append(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
ilist.growNumLists(13);
|
||||
for(int i=0;i<13;i++) {
|
||||
if (i < 7) {
|
||||
expect(ilist,i,new long[]{0,1,2,3,4,5,6,7,8,9}, "Grow lists ");
|
||||
}
|
||||
else {
|
||||
expect(ilist,i,new long[]{},"Grow Lists ");
|
||||
}
|
||||
}
|
||||
}// end doTest()
|
||||
|
||||
public static void expect(IntLongIndexedList ilist, int listId, long[] values, String test) {
|
||||
|
||||
long[] listValues = ilist.get(listId);
|
||||
if (values.length != listValues.length) {
|
||||
Assert.fail(test + " expected list "+listId+ "to be of length "+
|
||||
values.length + ", but instead it was of length "+listValues.length);
|
||||
}
|
||||
for(int i=0;i<listValues.length;i++) {
|
||||
if (listValues[i] != values[i]) {
|
||||
Assert.fail(test + "list["+listId+"], item "+i+
|
||||
"should contain "+values[i]+", but instead contains "+listValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class LongIntHashedListTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public LongIntHashedListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongIntHashedList() {
|
||||
|
||||
LongIntHashedList ilist = new LongIntHashedList(7);
|
||||
|
||||
System.out.println("Test add to list 0");
|
||||
ilist.add(50000,20);
|
||||
ilist.add(50000,10);
|
||||
ilist.add(50000,0);
|
||||
expect(ilist,50000, new int[] {0,10,20}, "Add: ");
|
||||
|
||||
System.out.println("Test append");
|
||||
ilist.append(6,30);
|
||||
ilist.append(6,40);
|
||||
ilist.append(6,50);
|
||||
expect(ilist,50000, new int[] {0,10,20}, "Add: ");
|
||||
expect(ilist, 6, new int[] {30,40,50}, "Append");
|
||||
|
||||
|
||||
System.out.println("Test contains");
|
||||
if (!ilist.contains(50000,0)) {
|
||||
Assert.fail("list 50000 does not contain 0, but it should");
|
||||
}
|
||||
if (!ilist.contains(50000,10)) {
|
||||
Assert.fail("list 50000 does not contain 10, but it should");
|
||||
}
|
||||
if (!ilist.contains(50000,20)) {
|
||||
Assert.fail("list 50000 does not contain 20, but it should");
|
||||
}
|
||||
if (ilist.contains(50000,30)) {
|
||||
Assert.fail("list 50000 contains 30, but it should not");
|
||||
}
|
||||
if (ilist.contains(1,50)) {
|
||||
Assert.fail("list 1 contains 50, but it should not");
|
||||
}
|
||||
if (!ilist.contains(6,50)) {
|
||||
Assert.fail("list 6 does not contain 50, but it should");
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ilist.remove(50000,0);
|
||||
ilist.remove(6,50);
|
||||
expect(ilist,50000, new int[] {10,20}, "Remove ");
|
||||
expect(ilist, 6, new int[] {30,40}, "Remove ");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ilist.removeAll(50000);
|
||||
expect(ilist,50000,new int[]{},"RemoveAll ");
|
||||
expect(ilist,1,new int[]{},"RemoveAll ");
|
||||
expect(ilist,6,new int[]{30,40},"RemoveAll ");
|
||||
|
||||
|
||||
|
||||
System.out.println("Test add after removeAll");
|
||||
ilist.add(50000,100);
|
||||
ilist.add(50000,200);
|
||||
ilist.add(50000,300);
|
||||
expect(ilist,50000,new int[]{300,200,100}, "Add after removeAll");
|
||||
|
||||
ilist.removeAll(50000);
|
||||
ilist.removeAll(6);
|
||||
|
||||
System.out.println("Test growing the number of lists");
|
||||
for(int i = 0;i<20;i++) {
|
||||
for(int j=0;j<10;j++) {
|
||||
ilist.append(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
}// end doTest()
|
||||
|
||||
public static void expect(LongIntHashedList ilist, long listId, int[] values, String test) {
|
||||
|
||||
int[] listValues = ilist.get(listId);
|
||||
if (listValues == null) {
|
||||
listValues = new int[0];
|
||||
}
|
||||
if (values.length != listValues.length) {
|
||||
Assert.fail(test + " expected list "+listId+ "to be of length "+
|
||||
values.length + ", but instead it was of length "+listValues.length);
|
||||
}
|
||||
for(int i=0;i<listValues.length;i++) {
|
||||
if (listValues[i] != values[i]) {
|
||||
Assert.fail(test + "list["+listId+"], item "+i+
|
||||
"should contain "+values[i]+", but instead contains "+listValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,121 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class LongLongHashedListTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public LongLongHashedListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongLongHashedList() {
|
||||
|
||||
LongLongHashedList ilist = new LongLongHashedList(7);
|
||||
|
||||
System.out.println("Test add to list 0");
|
||||
ilist.add(50000,20);
|
||||
ilist.add(50000,10);
|
||||
ilist.add(50000,0);
|
||||
expect(ilist,50000, new long[] {0,10,20}, "Add: ");
|
||||
|
||||
System.out.println("Test append");
|
||||
ilist.append(6,30);
|
||||
ilist.append(6,40);
|
||||
ilist.append(6,50);
|
||||
expect(ilist,50000, new long[] {0,10,20}, "Add: ");
|
||||
expect(ilist, 6, new long[] {30,40,50}, "Append");
|
||||
|
||||
|
||||
System.out.println("Test contains");
|
||||
if (!ilist.contains(50000,0)) {
|
||||
Assert.fail("list 50000 does not contain 0, but it should");
|
||||
}
|
||||
if (!ilist.contains(50000,10)) {
|
||||
Assert.fail("list 50000 does not contain 10, but it should");
|
||||
}
|
||||
if (!ilist.contains(50000,20)) {
|
||||
Assert.fail("list 50000 does not contain 20, but it should");
|
||||
}
|
||||
if (ilist.contains(50000,30)) {
|
||||
Assert.fail("list 50000 contains 30, but it should not");
|
||||
}
|
||||
if (ilist.contains(1,50)) {
|
||||
Assert.fail("list 1 contains 50, but it should not");
|
||||
}
|
||||
if (!ilist.contains(6,50)) {
|
||||
Assert.fail("list 6 does not contain 50, but it should");
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ilist.remove(50000,0);
|
||||
ilist.remove(6,50);
|
||||
expect(ilist,50000, new long[] {10,20}, "Remove ");
|
||||
expect(ilist, 6, new long[] {30,40}, "Remove ");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ilist.removeAll(50000);
|
||||
expect(ilist,50000,new long[]{},"RemoveAll ");
|
||||
expect(ilist,1,new long[]{},"RemoveAll ");
|
||||
expect(ilist,6,new long[]{30,40},"RemoveAll ");
|
||||
|
||||
|
||||
|
||||
System.out.println("Test add after removeAll");
|
||||
ilist.add(50000,100);
|
||||
ilist.add(50000,200);
|
||||
ilist.add(50000,300);
|
||||
expect(ilist,50000,new long[]{300,200,100}, "Add after removeAll");
|
||||
|
||||
ilist.removeAll(50000);
|
||||
ilist.removeAll(6);
|
||||
|
||||
System.out.println("Test growing the number of lists");
|
||||
for(int i = 0;i<20;i++) {
|
||||
for(int j=0;j<10;j++) {
|
||||
ilist.append(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
}// end doTest()
|
||||
|
||||
public static void expect(LongLongHashedList ilist, long listId, long[] values, String test) {
|
||||
|
||||
long[] listValues = ilist.get(listId);
|
||||
if (listValues == null) {
|
||||
listValues = new long[0];
|
||||
}
|
||||
if (values.length != listValues.length) {
|
||||
Assert.fail(test + " expected list "+listId+ "to be of length "+
|
||||
values.length + ", but instead it was of length "+listValues.length);
|
||||
}
|
||||
for(int i=0;i<listValues.length;i++) {
|
||||
if (listValues[i] != values[i]) {
|
||||
Assert.fail(test + "list["+listId+"], item "+i+
|
||||
"should contain "+values[i]+", but instead contains "+listValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class LongRedBlackTreeTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public LongRedBlackTreeTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongRedBlackTree() {
|
||||
|
||||
LongRedBlackTree rbt = new LongRedBlackTree();
|
||||
|
||||
System.out.println("Test put method");
|
||||
|
||||
rbt.put(25, new Long(25));
|
||||
rbt.put(234, new Long(234));
|
||||
rbt.put(2,new Long(2) );
|
||||
rbt.put(999, new Long(999));
|
||||
rbt.put(0, new Long(0));
|
||||
rbt.put(700, new Long(700));
|
||||
|
||||
test(rbt, 25, new Long(25));
|
||||
test(rbt,234, new Long(234));
|
||||
test(rbt,2,new Long(2) );
|
||||
test(rbt,999, new Long(999));
|
||||
test(rbt,0, new Long(0));
|
||||
test(rbt,700, new Long(700));
|
||||
|
||||
System.out.println("Test atOrBefore and atOrAfter methods");
|
||||
|
||||
Object obj = rbt.getAtOrBefore(600);
|
||||
if (!obj.equals(new Long(234))) {
|
||||
Assert.fail("Value at or before 600 should be 234, but was "+rbt.getAtOrBefore(600));
|
||||
}
|
||||
obj = rbt.getAtOrAfter(600);
|
||||
if (!obj.equals(new Long(700))) {
|
||||
Assert.fail("Value at or after 600 should be 700, but was "+rbt.getAtOrBefore(600));
|
||||
}
|
||||
obj = rbt.getAtOrBefore(700);
|
||||
if (!obj.equals(new Long(700))) {
|
||||
Assert.fail("Value at or before 700 should be 700, but was "+rbt.getAtOrBefore(600));
|
||||
}
|
||||
obj = rbt.getAtOrBefore(10000);
|
||||
if (!obj.equals(new Long(999))) {
|
||||
Assert.fail("Value at or before 10000 should be 999, but was "+rbt.getAtOrBefore(600));
|
||||
}
|
||||
|
||||
|
||||
System.out.println("Test the iterator");
|
||||
Iterator<?> it = rbt.iterator();
|
||||
|
||||
Object[] objs = new Object[6];
|
||||
objs[0] = new Long(0);
|
||||
objs[1] = new Long(2);
|
||||
objs[2] = new Long(25);
|
||||
objs[3] = new Long(234);
|
||||
objs[4] = new Long(700);
|
||||
objs[5] = new Long(999);
|
||||
|
||||
int i = 0;
|
||||
while(it.hasNext()) {
|
||||
Object o = it.next();
|
||||
if (!o.equals(objs[i])) {
|
||||
Assert.fail("expected "+objs[i]+" but got "+o);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
public static void test(LongRedBlackTree rbt, long key, Object value) {
|
||||
|
||||
Object obj = rbt.get(key);
|
||||
if (!value.equals(obj)) {
|
||||
Assert.fail("Expected value for key "+key +" was "+value +
|
||||
" but got "+obj+" instead");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
public class LongShortHashtableTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public LongShortHashtableTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLongShortHashtable() {
|
||||
|
||||
LongShortHashtable ht = new LongShortHashtable();
|
||||
System.out.println("Test put method");
|
||||
|
||||
ht.put(10000, (short)100);
|
||||
ht.put(20000, (short)200);
|
||||
ht.put(30000, (short)300);
|
||||
ht.put(40000, (short)400);
|
||||
|
||||
test(ht, 10000, (short)100);
|
||||
test(ht, 20000, (short)200);
|
||||
test(ht, 30000, (short)300);
|
||||
test(ht, 40000, (short)400);
|
||||
|
||||
try {
|
||||
short value = ht.get(50000);
|
||||
Assert.fail("The value "+value+" was found at key "+
|
||||
"50000, but there should not have been a value there.");
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
|
||||
System.out.println("Test contains method");
|
||||
|
||||
testContains(ht, new long[]{10000,20000,30000,40000}, "Add");
|
||||
|
||||
System.out.println("Test size method");
|
||||
if (ht.size() != 4) {
|
||||
Assert.fail("size should be 4, but it is "+ht.size());
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ht.remove(20000);
|
||||
|
||||
if (ht.size() != 3) {
|
||||
Assert.fail("size should be 3, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht, new long[]{10000,30000,40000}, "Remove");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ht.removeAll();
|
||||
if (ht.size() != 0) {
|
||||
Assert.fail("size should be 0, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht,new long[]{}, "RemoveAll");
|
||||
|
||||
|
||||
System.out.println("Test grow by adding 500 values");
|
||||
for(int i=0;i<500;i++) {
|
||||
ht.put(i*100, (short)i);
|
||||
}
|
||||
|
||||
for(int i= 0;i<50000;i++) {
|
||||
if (ht.contains(i)) {
|
||||
if (i%100 != 0) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i%100 == 0) {
|
||||
Assert.fail("hashtable should contain key "+i+", but it doesn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(LongShortHashtable ht, long key, short value) {
|
||||
|
||||
try {
|
||||
if (ht.get(key) != value) {
|
||||
Assert.fail("Value at key "+key+" should be "+value+
|
||||
" but instead is "+ht.get(key));
|
||||
}
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
Assert.fail("No value found at key "+key+" but should have had value "+value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testContains(LongShortHashtable ht, long[] keys, String test) {
|
||||
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (!ht.contains(keys[i])) {
|
||||
Assert.fail("hastable should contain key "+keys[i]+", but it doesn't");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0;i<=50000;i++) {
|
||||
if (ht.contains(i)) {
|
||||
if (!contains(keys,i)) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean contains(long[] keys, long key) {
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (keys[i] == key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
public class ShortByteHashtableTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public ShortByteHashtableTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortByteHashtable() {
|
||||
|
||||
ShortByteHashtable ht = new ShortByteHashtable();
|
||||
System.out.println("Test put method");
|
||||
|
||||
ht.put((short)100, (byte)10);
|
||||
ht.put((short)200, (byte)20);
|
||||
ht.put((short)300, (byte)30);
|
||||
ht.put((short)400, (byte)40);
|
||||
|
||||
test(ht, (short)100, (byte)10);
|
||||
test(ht, (short)200, (byte)20);
|
||||
test(ht, (short)300, (byte)30);
|
||||
test(ht, (short)400, (byte)40);
|
||||
|
||||
try {
|
||||
byte value = ht.get((short)500);
|
||||
Assert.fail("The value "+value+" was found at key "+
|
||||
"50000, but there should not have been a value there.");
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
|
||||
System.out.println("Test contains method");
|
||||
|
||||
testContains(ht, new short[]{100,200,300,400}, "Add");
|
||||
|
||||
System.out.println("Test size method");
|
||||
if (ht.size() != 4) {
|
||||
Assert.fail("size should be 4, but it is "+ht.size());
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ht.remove((short)200);
|
||||
|
||||
if (ht.size() != 3) {
|
||||
Assert.fail("size should be 3, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht, new short[]{100,300,400}, "Remove");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ht.removeAll();
|
||||
if (ht.size() != 0) {
|
||||
Assert.fail("size should be 0, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht,new short[]{}, "RemoveAll");
|
||||
|
||||
|
||||
System.out.println("Test grow by adding 500 values");
|
||||
for(int i=0;i<5000;i++) {
|
||||
ht.put((short)(i*10), (byte)i);
|
||||
}
|
||||
|
||||
for(int i= 0;i<5000;i++) {
|
||||
if (ht.contains((short)i)) {
|
||||
if (i%10 != 0) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i%10 == 0) {
|
||||
Assert.fail("hashtable should contain key "+i+", but it doesn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(ShortByteHashtable ht, short key, byte value) {
|
||||
|
||||
try {
|
||||
if (ht.get(key) != value) {
|
||||
Assert.fail("Value at key "+key+" should be "+value+
|
||||
" but instead is "+ht.get(key));
|
||||
}
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
Assert.fail("No value found at key "+key+" but should have had value "+value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testContains(ShortByteHashtable ht, short[] keys, String test) {
|
||||
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (!ht.contains(keys[i])) {
|
||||
Assert.fail("hastable should contain key "+keys[i]+", but it doesn't");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0;i<=50000;i++) {
|
||||
if (ht.contains((short)i)) {
|
||||
if (!contains(keys,(short)i)) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean contains(short[] keys, short key) {
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (keys[i] == key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class ShortIndexManagerTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public ShortIndexManagerTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* regression test driver
|
||||
*/
|
||||
@Test
|
||||
public void testShortIndexManager() {
|
||||
ShortIndexManager imgr = new ShortIndexManager();
|
||||
|
||||
System.out.println("test basic allocation");
|
||||
|
||||
short index;
|
||||
for(short i=0;i<10;i++) {
|
||||
if ((index = imgr.allocate()) != i) {
|
||||
Assert.fail("Allocate: expected "+i+", and got "+index);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
System.out.println("test deallocation");
|
||||
for(short i=5;i<8;i++) {
|
||||
imgr.deallocate(i);
|
||||
}
|
||||
for(short i = 7;i>=5;i--) {
|
||||
if ((index = imgr.allocate()) != i) {
|
||||
Assert.fail("Deallocate: expected "+i+", and got "+index);
|
||||
}
|
||||
}
|
||||
if (imgr.allocate() != 10) {
|
||||
Assert.fail("Deallocate: unexpected allocated index for 10");
|
||||
}
|
||||
|
||||
|
||||
System.out.println("test clear all");
|
||||
imgr.clear();
|
||||
for(int i=0;i<10;i++) {
|
||||
if ((index = imgr.allocate()) != i) {
|
||||
Assert.fail("ClearAll: expected "+i+", and got "+index);
|
||||
}
|
||||
}
|
||||
|
||||
}//end doTest()
|
||||
|
||||
}
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
public class ShortIntHashtableTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public ShortIntHashtableTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortIntHashtable() {
|
||||
|
||||
ShortIntHashtable ht = new ShortIntHashtable();
|
||||
System.out.println("Test put method");
|
||||
|
||||
ht.put((short)100, 100);
|
||||
ht.put((short)200, 200);
|
||||
ht.put((short)300, 300);
|
||||
ht.put((short)400, 400);
|
||||
|
||||
test(ht, (short)100, 100);
|
||||
test(ht, (short)200, 200);
|
||||
test(ht, (short)300, 300);
|
||||
test(ht, (short)400, 400);
|
||||
|
||||
try {
|
||||
int value = ht.get((short)500);
|
||||
Assert.fail("The value "+value+" was found at key "+
|
||||
"50000, but there should not have been a value there.");
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
|
||||
System.out.println("Test contains method");
|
||||
|
||||
testContains(ht, new short[]{100,200,300,400}, "Add");
|
||||
|
||||
System.out.println("Test size method");
|
||||
if (ht.size() != 4) {
|
||||
Assert.fail("size should be 4, but it is "+ht.size());
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ht.remove((short)200);
|
||||
|
||||
if (ht.size() != 3) {
|
||||
Assert.fail("size should be 3, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht, new short[]{100,300,400}, "Remove");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ht.removeAll();
|
||||
if (ht.size() != 0) {
|
||||
Assert.fail("size should be 0, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht,new short[]{}, "RemoveAll");
|
||||
|
||||
|
||||
System.out.println("Test grow by adding 500 values");
|
||||
for(int i=0;i<5000;i++) {
|
||||
ht.put((short)(i*10), i);
|
||||
}
|
||||
|
||||
for(int i= 0;i<5000;i++) {
|
||||
if (ht.contains((short)i)) {
|
||||
if (i%10 != 0) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i%10 == 0) {
|
||||
Assert.fail("hashtable should contain key "+i+", but it doesn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(ShortIntHashtable ht, short key, int value) {
|
||||
|
||||
try {
|
||||
if (ht.get(key) != value) {
|
||||
Assert.fail("Value at key "+key+" should be "+value+
|
||||
" but instead is "+ht.get(key));
|
||||
}
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
Assert.fail("No value found at key "+key+" but should have had value "+value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testContains(ShortIntHashtable ht, short[] keys, String test) {
|
||||
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (!ht.contains(keys[i])) {
|
||||
Assert.fail("hastable should contain key "+keys[i]+", but it doesn't");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0;i<=50000;i++) {
|
||||
if (ht.contains((short)i)) {
|
||||
if (!contains(keys,(short)i)) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean contains(short[] keys, short key) {
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (keys[i] == key) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
|
||||
public class ShortLongIndexedListTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public ShortLongIndexedListTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShortLongIndexedList() {
|
||||
|
||||
ShortLongIndexedList ilist = new ShortLongIndexedList((short)7);
|
||||
|
||||
System.out.println("Test add to list 0");
|
||||
ilist.add((short)0,20l);
|
||||
ilist.add((short)0,10l);
|
||||
ilist.add((short)0,0l);
|
||||
expect(ilist,(short)0, new long[] {0l,10l,20l}, "Add: ");
|
||||
|
||||
System.out.println("Test append");
|
||||
ilist.append((short)6,30l);
|
||||
ilist.append((short)6,40l);
|
||||
ilist.append((short)6,50l);
|
||||
expect(ilist,(short)0, new long[] {0l,10l,20l}, "Add: ");
|
||||
expect(ilist, (short)6, new long[] {30l,40l,50l}, "Append");
|
||||
|
||||
|
||||
System.out.println("Test contains");
|
||||
if (!ilist.contains((short)0,0l)) {
|
||||
Assert.fail("list 0 does not contain 0, but it should");
|
||||
}
|
||||
if (!ilist.contains((short)0,10l)) {
|
||||
Assert.fail("list 0 does not contain 10, but it should");
|
||||
}
|
||||
if (!ilist.contains((short)0,20l)) {
|
||||
Assert.fail("list 0 does not contain 20, but it should");
|
||||
}
|
||||
if (ilist.contains((short)0,30l)) {
|
||||
Assert.fail("list 0 contains 30, but it should not");
|
||||
}
|
||||
if (ilist.contains((short)1,50l)) {
|
||||
Assert.fail("list 1 contains 50, but it should not");
|
||||
}
|
||||
if (!ilist.contains((short)6,50l)) {
|
||||
Assert.fail("list 6 does not contain 50, but it should");
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ilist.remove((short)0,0l);
|
||||
ilist.remove((short)6,50l);
|
||||
expect(ilist,(short)0, new long[] {10l,20l}, "Remove ");
|
||||
expect(ilist, (short)6, new long[] {30l,40l}, "Remove ");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ilist.removeAll((short)0);
|
||||
expect(ilist,(short)0,new long[]{},"RemoveAll ");
|
||||
expect(ilist,(short)1,new long[]{},"RemoveAll ");
|
||||
expect(ilist,(short)6,new long[]{30,40},"RemoveAll ");
|
||||
|
||||
|
||||
|
||||
System.out.println("Test add after removeAll");
|
||||
ilist.add((short)0,100l);
|
||||
ilist.add((short)0,200l);
|
||||
ilist.add((short)0,300l);
|
||||
expect(ilist,(short)0,new long[]{300l,200l,100l}, "Add after removeAll");
|
||||
|
||||
ilist.removeAll((short)0);
|
||||
ilist.removeAll((short)6);
|
||||
System.out.println("Test growing the number of lists");
|
||||
for(short i=0;i<ilist.getNumLists();i++) {
|
||||
for(long j=0;j<10;j++) {
|
||||
ilist.append(i,j);
|
||||
}
|
||||
}
|
||||
|
||||
ilist.growNumLists((short)13);
|
||||
for(short i=0;i<13;i++) {
|
||||
if (i < 7) {
|
||||
expect(ilist,i,new long[]{0,1,2,3,4,5,6,7,8,9}, "Grow lists ");
|
||||
}
|
||||
else {
|
||||
expect(ilist,i,new long[]{},"Grow Lists ");
|
||||
}
|
||||
}
|
||||
}// end doTest()
|
||||
|
||||
public static void expect(ShortLongIndexedList ilist, short listId, long[] values, String test) {
|
||||
|
||||
long[] listValues = ilist.get(listId);
|
||||
if (values.length != listValues.length) {
|
||||
Assert.fail(test + " expected list "+listId+ "to be of length "+
|
||||
values.length + ", but instead it was of length "+listValues.length);
|
||||
}
|
||||
for(int i=0;i<listValues.length;i++) {
|
||||
if (listValues[i] != values[i]) {
|
||||
Assert.fail(test + "list["+listId+"], item "+i+
|
||||
"should contain "+values[i]+", but instead contains "+listValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
public class StringLongHashtableTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public StringLongHashtableTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringLongHashtable() {
|
||||
|
||||
StringLongHashtable ht = new StringLongHashtable();
|
||||
System.out.println("Test put method");
|
||||
|
||||
ht.put("A", 100);
|
||||
ht.put("B", 200);
|
||||
ht.put("C", 300);
|
||||
ht.put("D", 400);
|
||||
|
||||
test(ht, "A", 100);
|
||||
test(ht, "B", 200);
|
||||
test(ht, "C", 300);
|
||||
test(ht, "D", 400);
|
||||
|
||||
try {
|
||||
long value = ht.get("G");
|
||||
Assert.fail("The value "+value+" was found at key "+
|
||||
"G, but there should not have been a value there.");
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
|
||||
System.out.println("Test contains method");
|
||||
|
||||
testContains(ht, new String[]{"A","B","C","D"}, "Add");
|
||||
|
||||
System.out.println("Test size method");
|
||||
if (ht.size() != 4) {
|
||||
Assert.fail("size should be 4, but it is "+ht.size());
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ht.remove("B");
|
||||
|
||||
if (ht.size() != 3) {
|
||||
Assert.fail("size should be 3, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht, new String[]{"A","C","D"}, "Remove");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ht.removeAll();
|
||||
if (ht.size() != 0) {
|
||||
Assert.fail("size should be 0, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht,new String[]{}, "RemoveAll");
|
||||
|
||||
|
||||
System.out.println("Test grow by adding 500 values");
|
||||
for(int i=0;i<500;i++) {
|
||||
ht.put("LAB"+(100*i), i);
|
||||
}
|
||||
|
||||
for(int i= 0;i<50000;i++) {
|
||||
if (ht.contains("LAB"+i)) {
|
||||
if (i%100 != 0) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i%100 == 0) {
|
||||
Assert.fail("hashtable should contain key "+i+", but it doesn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(StringLongHashtable ht, String key, int value) {
|
||||
|
||||
try {
|
||||
if (ht.get(key) != value) {
|
||||
Assert.fail("Value at key "+key+" should be "+value+
|
||||
" but instead is "+ht.get(key));
|
||||
}
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
Assert.fail("No value found at key "+key+" but should have had value "+value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testContains(StringLongHashtable ht, String[] keys, String test) {
|
||||
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (!ht.contains(keys[i])) {
|
||||
Assert.fail("hastable should contain key "+keys[i]+", but it doesn't");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0;i<=50000;i++) {
|
||||
if (ht.contains("LAB"+i)) {
|
||||
if (!contains(keys,"LAB"+i)) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean contains(String[] keys, String key) {
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (keys[i].equals(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -1,142 +0,0 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* 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 ghidra.util.datastruct;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import generic.test.AbstractGenericTest;
|
||||
import ghidra.util.exception.NoValueException;
|
||||
|
||||
public class StringShortHashtableTest extends AbstractGenericTest {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param arg0
|
||||
*/
|
||||
public StringShortHashtableTest() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStringShortHashtable() {
|
||||
|
||||
StringShortHashtable ht = new StringShortHashtable();
|
||||
System.out.println("Test put method");
|
||||
|
||||
ht.put("A", (short)100);
|
||||
ht.put("B", (short)200);
|
||||
ht.put("C", (short)300);
|
||||
ht.put("D", (short)400);
|
||||
|
||||
test(ht, "A", (short)100);
|
||||
test(ht, "B", (short)200);
|
||||
test(ht, "C", (short)300);
|
||||
test(ht, "D", (short)400);
|
||||
|
||||
try {
|
||||
short value = ht.get("G");
|
||||
Assert.fail("The value "+value+" was found at key "+
|
||||
"G, but there should not have been a value there.");
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
}
|
||||
|
||||
System.out.println("Test contains method");
|
||||
|
||||
testContains(ht, new String[]{"A","B","C","D"}, "Add");
|
||||
|
||||
System.out.println("Test size method");
|
||||
if (ht.size() != 4) {
|
||||
Assert.fail("size should be 4, but it is "+ht.size());
|
||||
}
|
||||
|
||||
System.out.println("Test remove");
|
||||
ht.remove("B");
|
||||
|
||||
if (ht.size() != 3) {
|
||||
Assert.fail("size should be 3, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht, new String[]{"A","C","D"}, "Remove");
|
||||
|
||||
System.out.println("Test removeAll");
|
||||
ht.removeAll();
|
||||
if (ht.size() != 0) {
|
||||
Assert.fail("size should be 0, but it is "+ht.size());
|
||||
}
|
||||
testContains(ht,new String[]{}, "RemoveAll");
|
||||
|
||||
|
||||
System.out.println("Test grow by adding 500 values");
|
||||
for(int i=0;i<500;i++) {
|
||||
ht.put("LAB"+(100*i), (short)i);
|
||||
}
|
||||
|
||||
for(int i= 0;i<50000;i++) {
|
||||
if (ht.contains("LAB"+i)) {
|
||||
if (i%100 != 0) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (i%100 == 0) {
|
||||
Assert.fail("hashtable should contain key "+i+", but it doesn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void test(StringShortHashtable ht, String key, short value) {
|
||||
|
||||
try {
|
||||
if (ht.get(key) != value) {
|
||||
Assert.fail("Value at key "+key+" should be "+value+
|
||||
" but instead is "+ht.get(key));
|
||||
}
|
||||
}
|
||||
catch(NoValueException ex) {
|
||||
Assert.fail("No value found at key "+key+" but should have had value "+value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void testContains(StringShortHashtable ht, String[] keys, String test) {
|
||||
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (!ht.contains(keys[i])) {
|
||||
Assert.fail("hastable should contain key "+keys[i]+", but it doesn't");
|
||||
}
|
||||
}
|
||||
|
||||
for(int i= 0;i<=50000;i++) {
|
||||
if (ht.contains("LAB"+i)) {
|
||||
if (!contains(keys,"LAB"+i)) {
|
||||
Assert.fail("hashtable contains key "+i+", but it shouldn't");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean contains(String[] keys, String key) {
|
||||
for(int i=0;i<keys.length;i++) {
|
||||
if (keys[i].equals(key)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue