ca.odell.glazedlists.impl.adt.barcode2.FourColorNode Maven / Gradle / Ivy
/* Glazed Lists (c) 2003-2006 */
/* http://publicobject.com/glazedlists/ publicobject.com,*/
/* O'Dell Engineering Ltd.*/
package ca.odell.glazedlists.impl.adt.barcode2;
import java.util.Arrays;
import java.util.List;
/*
# some M4 Macros that make it easy to use m4 with Java
M4 Macros
# define a function NODE_WIDTH(boolean) to get the node's size for this color
# define a function NODE_SIZE(node, colors) to no node.nodeSize()
# define a function to refresh counts
# multiple values
*/
/*[ BEGIN_M4_JAVA ]*/
/**
* A node in a tree which supports both a value and compressed nodes that
* contain a size, useful for index offsetting.
*
* Note that the counts
summary member is created lazily when
* this node is given children. This causes the code to be less easy to read,
* but it means we can put off about a huge number of object allocations since
* 50% of the nodes in an arbitrary tree are leaf nodes, and these leaf nodes
* now don't have counts.
*
* @author Jesse Wilson
*/
class FourColorNode < T0> implements Element {
/** the number of elements of each color in this subtree */
int count1;
int count2;
int count4;
int count8;
/** the node's color */
byte color;
/** the node's value */
T0 t0;
/** the size of this node */
int size;
/** values for managing the node within the tree */
byte height;
FourColorNode < T0> left, right, parent;
/** whether this node is consistent in the sorting order */
int sorted = SORTED;
/**
* Create a new node.
*
* @param color a bitmask value such as 1, 2, 4, 8 or 16.
* @param size the size of the node
* @param value the value of the node
* @param parent the parent node in the tree, or null
for the
* root node.
*/
public FourColorNode/**/( byte color, int size, T0 value, FourColorNode < T0> parent) {
assert(FourColorTree.colorAsIndex(color) >= 0 && FourColorTree.colorAsIndex(color) < 7);
this.color = color;
this.size = size;
this.t0 = value;
this.height = 1;
this.parent = parent;
if(color == 1) count1 += size;
if(color == 2) count2 += size;
if(color == 4) count4 += size;
if(color == 8) count8 += size;
}
/**
* Get the value of this element.
*/
public T0 get() {
return t0;
}
/**
* Set the value of this element.
*/
public void set(T0 value) {
this.t0 = value;
}
/** access the node's values */
public T0 get0() { return t0; }
public void set0(T0 value) { this.t0 = value; }
/**
* Get the color of this element.
*/
public byte getColor() {
return color ;
}
/**
* The size of this entire node, including the left child, this node
* and the right child.
*/
final int size(byte colors) {
// total the values of the specified array for the specified colors.
int result = 0;
if((colors & 1) != 0) result += count1;
if((colors & 2) != 0) result += count2;
if((colors & 4) != 0) result += count4;
if((colors & 8) != 0) result += count8;
return result;
}
/**
* The size of the node for the specified colors.
*/
final int nodeSize(byte colors) {
return (colors & color) > 0 ? size : 0;
}
/**
* Update the counts member variable by examining the counts of
* the child nodes and the size member variable.
*/
final void refreshCounts( ) {
count1 = 0;
count2 = 0;
count4 = 0;
count8 = 0;
// left child
if(left != null) {
count1 += left.count1;
count2 += left.count2;
count4 += left.count4;
count8 += left.count8;
}
// right child
if(right != null) {
count1 += right.count1;
count2 += right.count2;
count4 += right.count4;
count8 += right.count8;
}
// this node
if(color == 1) count1 += size;
if(color == 2) count2 += size;
if(color == 4) count4 += size;
if(color == 8) count8 += size;
}
/** {@inheritDoc} */
@Override
public String toString() {
return toString(Arrays.asList(new String[] { "A", "B", "C", "D", "E", "F", "G", "H"}));
}
/**
* Write this node out as a String, using the specified colors to write
* each of the node values.
*/
String toString(List colors) {
StringBuffer result = new StringBuffer();
asTree(0, result, colors);
return result.toString();
}
/**
* Dump this node as a String for diagnostic and debugging purposes.
*/
void asTree(int indentation, StringBuffer out, List colors) {
// write the left subtree
if(left != null) left.asTree(indentation + 1, out, colors);
// write this node
for(int i = 0; i < indentation; i++) {
out.append(" ");
}
out.append(colors.get(FourColorTree.colorAsIndex(color)));
out.append(" [").append(size).append("]");
if(t0 != null) {
out.append(": ");
if(t0 instanceof FourColorNode) {
out.append("");
} else {
out.append(t0);
}
}
out.append("\n");
// write the right subtree
if(right != null) right.asTree(indentation + 1, out, colors);
}
/**
* Toggle whether this node is sorted.
*/
public void setSorted(int sorted) {
this.sorted = sorted;
}
/**
* Get whether the value of this node is greater than the previous node
* and less than the next node. This is useful to have occasional unsorted
* elements in an otherwise sorted collection, such as what happens when the
* user expects order to be both sorted and stable during edits which would
* otherwise change the sorting order.
*/
public int getSorted() {
return sorted;
}
/** {@inheritDoc} */
public Element next() {
return FourColorTree.next(this);
}
/** {@inheritDoc} */
public Element previous() {
return FourColorTree.previous(this);
}
}
/*[ END_M4_JAVA ]*/