//
// ========================================================================
-// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
import java.util.Set;
/* ------------------------------------------------------------ */
-/** A Trie String lookup data structure using a fixed size array.
+/**
+ * <p>A Trie String lookup data structure using a fixed size array.</p>
* <p>This implementation is always case insensitive and is optimal for
- * a small number of fixed strings with few special characters.
+ * a small number of fixed strings with few special characters. The
+ * Trie is stored in an array of lookup tables, each indexed by the
+ * next character of the key. Frequently used characters are directly
+ * indexed in each lookup table, whilst infrequently used characters
+ * must use a big character table.
+ * </p>
+ * <p>This Trie is very space efficient if the key characters are
+ * from ' ', '+', '-', ':', ';', '.', 'A' to 'Z' or 'a' to 'z'.
+ * Other ISO-8859-1 characters can be used by the key, but less space
+ * efficiently.
+ * </p>
+ * <p>This Trie is not Threadsafe and contains no mutual exclusion
+ * or deliberate memory barriers. It is intended for an ArrayTrie to be
+ * built by a single thread and then used concurrently by multiple threads
+ * and not mutated during that access. If concurrent mutations of the
+ * Trie is required external locks need to be applied.
* </p>
* @param <V>
*/
private static final int[] __lookup =
{ // 0 1 2 3 4 5 6 7 8 9 A B C D E F
/*0*/-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- /*1*/-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 30,
- /*2*/31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, 27, -1, -1,
+ /*1*/-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ /*2*/31, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, 27, 30, -1,
/*3*/-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, 29, -1, -1, -1, -1,
/*4*/-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
/*5*/15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
* The value (if any) for a Trie row.
* A row may be a leaf, a node or both in the Trie tree.
*/
- private final Object[] _value;
+ private final V[] _value;
/**
* A big index for each row.
this(128);
}
- public ArrayTrie(int capacityInNodes)
+ /* ------------------------------------------------------------ */
+ /**
+ * @param capacity The capacity of the trie, which at the worst case
+ * is the total number of characters of all keys stored in the Trie.
+ * The capacity needed is dependent of the shared prefixes of the keys.
+ * For example, a capacity of 6 nodes is required to store keys "foo"
+ * and "bar", but a capacity of only 4 is required to
+ * store "bar" and "bat".
+ */
+ @SuppressWarnings("unchecked")
+ public ArrayTrie(int capacity)
{
super(true);
- _value=new Object[capacityInNodes];
- _rowIndex=new char[capacityInNodes*32];
- _key=new String[capacityInNodes];
+ _value=(V[])new Object[capacity];
+ _rowIndex=new char[capacity*32];
+ _key=new String[capacity];
}
}
}
}
+
+ if (t>=_key.length)
+ {
+ _rows=(char)_key.length;
+ return false;
+ }
+
_key[t]=v==null?null:s;
- V old=(V)_value[t];
_value[t] = v;
return true;
}
return null;
}
}
- return (V)_value[t];
+ return _value[t];
}
/* ------------------------------------------------------------ */
}
- private <V> void toString(Appendable out, int t)
+ private void toString(Appendable out, int t)
{
if (_value[t]!=null)
{
@Override
public boolean isFull()
{
- return _rows+1==_key.length;
+ return _rows+1>=_key.length;
}
}