use of org.cytoscape.util.intr.LongObjHash in project cytoscape-impl by cytoscape.
the class RTree method empty.
/**
* Empties this R-tree of all entries. This method returns in constant
* time (note however that garbage collection will take place in the
* background).
*/
public final void empty() {
m_root = new Node(m_maxBranches, true);
m_entryMap = new LongObjHash();
m_zOrderMap = new HashMap<Long, Double>();
m_deletedEntries = 0;
m_mapExpansionThreshold = LongObjHash.maxCapacity(m_entryMap.size());
}
use of org.cytoscape.util.intr.LongObjHash in project cytoscape-impl by cytoscape.
the class RTree method insert.
/**
* Inserts a new data entry into this tree; the entry's extents
* are specified by the input parameters. "Extents" is a short way
* of saying "minimum bounding rectangle". The minimum bounding rectangle
* of an entry is axis-aligned, meaning that its sides are parallel to the
* axes of the data space.
* @param objKey a user-defined unique identifier used to refer to the entry
* being inserted in later operations; this identifier must be
* non-negative.
* @param xMin the minimum X coordinate of the entry's extents rectangle.
* @param yMin the minimum Y coordinate of the entry's extents rectangle.
* @param xMax the maximum X coordinate of the entry's extents rectangle.
* @param yMax the maximum Y coordinate of the entry's extents rectangle.
* @exception IllegalStateException if objKey is already used for an
* existing entry in this R-tree.
* @exception IllegalArgumentException if objKey is negative,
* if xMin is not less than or equal to xMax, or
* if yMin is not less than or equal to yMax.
*/
public final void insert(final long objKey, final float xMin, final float yMin, final float xMax, final float yMax, final double z) {
if (objKey < 0)
throw new IllegalArgumentException("objKey is negative");
if (!(xMin <= xMax))
throw new IllegalArgumentException("xMin <= xMax not true: xMin " + xMin + " xMax " + xMax);
if (!(yMin <= yMax))
throw new IllegalArgumentException("yMin <= yMax not true: yMin " + yMin + " yMax " + yMax);
if (m_entryMap.get(objKey) != null) {
if (m_entryMap.get(objKey) != m_deletedEntry)
throw new IllegalStateException("objkey " + objKey + " is already in this tree");
m_deletedEntries--;
} else // Old entry is m_deletedEntry.
// We only allow underlying hashtable expansions if the number of deleted
// keys in the table is one quarter or less of the total number of keys.
{
if (m_entryMap.size() == m_mapExpansionThreshold) {
if ((m_deletedEntries * 4) > m_entryMap.size()) {
// Prune map.
final LongObjHash newEntryMap = new LongObjHash();
final LongEnumerator objKeys = m_entryMap.keys();
final Iterator leafNodes = m_entryMap.values();
while (objKeys.numRemaining() > 0) {
final Object leafNode = leafNodes.next();
if (leafNode == m_deletedEntry) {
objKeys.nextLong();
continue;
}
newEntryMap.put(objKeys.nextLong(), leafNode);
}
m_entryMap = newEntryMap;
m_deletedEntries = 0;
}
m_mapExpansionThreshold = LongObjHash.maxCapacity(m_entryMap.size() + 1);
}
}
final Node rootSplit = insert(m_root, objKey, xMin, yMin, xMax, yMax, m_maxBranches, m_minBranches, m_entryMap, m_MBR, m_objKeyBuff, m_childrenBuff, m_xMinBuff, m_yMinBuff, m_xMaxBuff, m_yMaxBuff, m_tempBuff1, m_tempBuff2);
if (rootSplit != null) {
final Node newRoot = new Node(m_maxBranches, false);
newRoot.entryCount = 2;
m_root.parent = newRoot;
rootSplit.parent = newRoot;
newRoot.data.children[0] = m_root;
newRoot.data.children[1] = rootSplit;
newRoot.xMins[0] = m_root.xMins[m_maxBranches - 1];
newRoot.yMins[0] = m_root.yMins[m_maxBranches - 1];
newRoot.xMaxs[0] = m_root.xMaxs[m_maxBranches - 1];
newRoot.yMaxs[0] = m_root.yMaxs[m_maxBranches - 1];
newRoot.xMins[1] = rootSplit.xMins[m_maxBranches - 1];
newRoot.yMins[1] = rootSplit.yMins[m_maxBranches - 1];
newRoot.xMaxs[1] = rootSplit.xMaxs[m_maxBranches - 1];
newRoot.yMaxs[1] = rootSplit.yMaxs[m_maxBranches - 1];
if (isLeafNode(m_root))
newRoot.data.deepCount = m_root.entryCount + rootSplit.entryCount;
else
newRoot.data.deepCount = m_root.data.deepCount + rootSplit.data.deepCount;
m_root = newRoot;
m_MBR[0] = Math.min(m_root.xMins[0], m_root.xMins[1]);
m_MBR[1] = Math.min(m_root.yMins[0], m_root.yMins[1]);
m_MBR[2] = Math.max(m_root.xMaxs[0], m_root.xMaxs[1]);
m_MBR[3] = Math.max(m_root.yMaxs[0], m_root.yMaxs[1]);
}
// OK, now that we've done all *that*, add z
if (z != 0.0 || m_zOrderMap.get(objKey) != null) {
if (z == 0.0)
m_zOrderMap.remove(objKey);
else
m_zOrderMap.put(objKey, Double.valueOf(z));
}
}
use of org.cytoscape.util.intr.LongObjHash in project cytoscape-impl by cytoscape.
the class RTree method delete.
/**
* Deletes the specified data entry from this tree.
* @param objKey a user-defined identifier that was potentially used in a
* previous insertion.
* @return true if and only if objKey existed in this R-tree prior to this
* method invocation.
*/
public final boolean delete(final long objKey) {
if (objKey < 0)
return false;
// Todo: Rename 'n' to 'leafNode'.
final Node n;
{
final Object o = m_entryMap.get(objKey);
if ((o == null) || (o == m_deletedEntry))
return false;
n = (Node) o;
}
// Delete record from leaf node.
final int delInx;
for (int i = 0; ; i++) if (n.objKeys[i] == objKey) {
delInx = i;
break;
}
n.entryCount--;
if (delInx != n.entryCount) {
// Plug the hole at index delInx.
n.objKeys[delInx] = n.objKeys[n.entryCount];
n.xMins[delInx] = n.xMins[n.entryCount];
n.yMins[delInx] = n.yMins[n.entryCount];
n.xMaxs[delInx] = n.xMaxs[n.entryCount];
n.yMaxs[delInx] = n.yMaxs[n.entryCount];
}
// Fix up the tree from leaf to root.
int currentDepth = condenseTree(n, 1, m_nodeStack, m_minBranches, m_MBR) - m_nodeStack.size() + 1;
while (m_nodeStack.size() > 0) {
final Node eliminatedNode = (Node) m_nodeStack.pop();
for (int i = 0; i < eliminatedNode.entryCount; i++) {
final Node rootSplit;
if (isLeafNode(eliminatedNode)) {
rootSplit = insert(m_root, eliminatedNode.objKeys[i], eliminatedNode.xMins[i], eliminatedNode.yMins[i], eliminatedNode.xMaxs[i], eliminatedNode.yMaxs[i], m_maxBranches, m_minBranches, m_entryMap, m_MBR, m_objKeyBuff, m_childrenBuff, m_xMinBuff, m_yMinBuff, m_xMaxBuff, m_yMaxBuff, m_tempBuff1, m_tempBuff2);
} else {
rootSplit = insert(m_root, currentDepth, eliminatedNode.data.children[i], eliminatedNode.xMins[i], eliminatedNode.yMins[i], eliminatedNode.xMaxs[i], eliminatedNode.yMaxs[i], m_maxBranches, m_minBranches, m_MBR, m_childrenBuff, m_xMinBuff, m_yMinBuff, m_xMaxBuff, m_yMaxBuff, m_tempBuff1, m_tempBuff2);
eliminatedNode.data.children[i] = null;
/* Facilitate gc. */
}
if (rootSplit != null) {
final Node newRoot = new Node(m_maxBranches, false);
newRoot.entryCount = 2;
m_root.parent = newRoot;
rootSplit.parent = newRoot;
newRoot.data.children[0] = m_root;
newRoot.data.children[1] = rootSplit;
newRoot.xMins[0] = m_root.xMins[m_maxBranches - 1];
newRoot.yMins[0] = m_root.yMins[m_maxBranches - 1];
newRoot.xMaxs[0] = m_root.xMaxs[m_maxBranches - 1];
newRoot.yMaxs[0] = m_root.yMaxs[m_maxBranches - 1];
newRoot.xMins[1] = rootSplit.xMins[m_maxBranches - 1];
newRoot.yMins[1] = rootSplit.yMins[m_maxBranches - 1];
newRoot.xMaxs[1] = rootSplit.xMaxs[m_maxBranches - 1];
newRoot.yMaxs[1] = rootSplit.yMaxs[m_maxBranches - 1];
newRoot.data.deepCount = m_root.data.deepCount + rootSplit.data.deepCount;
m_root = newRoot;
m_MBR[0] = Math.min(m_root.xMins[0], m_root.xMins[1]);
m_MBR[1] = Math.min(m_root.yMins[0], m_root.yMins[1]);
m_MBR[2] = Math.max(m_root.xMaxs[0], m_root.xMaxs[1]);
m_MBR[3] = Math.max(m_root.yMaxs[0], m_root.yMaxs[1]);
currentDepth++;
}
}
currentDepth++;
}
// If the root node has only one child, make the child the new root.
if ((!isLeafNode(m_root)) && (m_root.entryCount == 1)) {
final Node newRoot = m_root.data.children[0];
newRoot.parent = null;
m_root = newRoot;
}
// Finally, delete the objKey from m_entryMap.
// If m_entryMap contains too many deleted entries, prune.
m_entryMap.put(objKey, m_deletedEntry);
if (((++m_deletedEntries * 2) > m_entryMap.size()) && (m_deletedEntries > 5)) {
final LongObjHash newEntryMap = new LongObjHash();
final LongEnumerator objKeys = m_entryMap.keys();
final Iterator leafNodes = m_entryMap.values();
while (objKeys.numRemaining() > 0) {
final Object leafNode = leafNodes.next();
if (leafNode == m_deletedEntry) {
objKeys.nextLong();
continue;
}
newEntryMap.put(objKeys.nextLong(), leafNode);
}
m_entryMap = newEntryMap;
m_deletedEntries = 0;
m_mapExpansionThreshold = LongObjHash.maxCapacity(m_entryMap.size());
}
return true;
}
Aggregations