Added Trove!
parent
9c9ec18802
commit
90ac307779
|
@ -0,0 +1,316 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
import gnu.trove.iterator.TByteIterator;
|
||||
import gnu.trove.procedure.TByteProcedure;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An interface that mimics the <tt>Collection</tt> interface.
|
||||
*
|
||||
* @author Eric D. Friedman
|
||||
* @author Rob Eden
|
||||
* @author Jeff Randall
|
||||
* @version $Id: _E_Collection.template,v 1.1.2.2 2009/09/15 02:38:30 upholderoftruth Exp $
|
||||
*/
|
||||
|
||||
public interface TByteCollection {
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Returns the value that is used to represent null. The default
|
||||
* value is generally zero, but can be changed during construction
|
||||
* of the collection.
|
||||
*
|
||||
* @return the value that represents null
|
||||
*/
|
||||
byte getNoEntryValue();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this collection (its cardinality). If this
|
||||
* collection contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of elements in this collection (its cardinality)
|
||||
*/
|
||||
int size();
|
||||
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this collection contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this collection contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this collection contains the specified element.
|
||||
*
|
||||
* @param entry an <code>byte</code> value
|
||||
* @return true if the collection contains the specified element.
|
||||
*/
|
||||
boolean contains( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Creates an iterator over the values of the collection. The iterator
|
||||
* supports element deletion.
|
||||
*
|
||||
* @return an <code>TByteIterator</code> value
|
||||
*/
|
||||
TByteIterator iterator();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this collection.
|
||||
* If this collection makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the
|
||||
* elements in the same order.
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it
|
||||
* are maintained by this collection. (In other words, this method must
|
||||
* allocate a new array even if this collection is backed by an array).
|
||||
* The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all the elements in this collection
|
||||
*/
|
||||
byte[] toArray();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array containing elements in this collection.
|
||||
*
|
||||
* <p>If this collection fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than this collection), the element in
|
||||
* the array immediately following the end of the collection is collection to
|
||||
* <tt>{@link #getNoEntryValue()}</tt>. (This is useful in determining
|
||||
* the length of this collection <i>only</i> if the caller knows that this
|
||||
* collection does not contain any elements representing null.)
|
||||
*
|
||||
* <p>If the native array is smaller than the collection size,
|
||||
* the array will be filled with elements in Iterator order
|
||||
* until it is full and exclude the remainder.
|
||||
*
|
||||
* <p>If this collection makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the elements
|
||||
* in the same order.
|
||||
*
|
||||
* @param dest the array into which the elements of this collection are to be
|
||||
* stored.
|
||||
* @return an <tt>byte[]</tt> containing all the elements in this collection
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
byte[] toArray( byte[] dest );
|
||||
|
||||
|
||||
/**
|
||||
* Inserts a value into the collection.
|
||||
*
|
||||
* @param entry a <code>byte</code> value
|
||||
* @return true if the collection was modified by the add operation
|
||||
*/
|
||||
boolean add( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Removes <tt>entry</tt> from the collection.
|
||||
*
|
||||
* @param entry an <code>byte</code> value
|
||||
* @return true if the collection was modified by the remove operation.
|
||||
*/
|
||||
boolean remove( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the collection to determine if all of the elements in
|
||||
* <tt>collection</tt> are present.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if all elements were present in the collection.
|
||||
*/
|
||||
boolean containsAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the collection to determine if all of the elements in
|
||||
* <tt>TByteCollection</tt> are present.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if all elements were present in the collection.
|
||||
*/
|
||||
boolean containsAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the collection to determine if all of the elements in
|
||||
* <tt>array</tt> are present.
|
||||
*
|
||||
* @param array as <code>array</code> of byte primitives.
|
||||
* @return true if all elements were present in the collection.
|
||||
*/
|
||||
boolean containsAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in <tt>collection</tt> to the collection.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the collection was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( Collection<? extends Byte> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the <tt>TByteCollection</tt> to the collection.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the collection was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the <tt>array</tt> to the collection.
|
||||
*
|
||||
* @param array a <code>array</code> of byte primitives.
|
||||
* @return true if the collection was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the collection which are not contained in
|
||||
* <tt>collection</tt>.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the collection was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the collection which are not contained in
|
||||
* <tt>TByteCollection</tt>.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the collection was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the collection which are not contained in
|
||||
* <tt>array</tt>.
|
||||
*
|
||||
* @param array an <code>array</code> of byte primitives.
|
||||
* @return true if the collection was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>collection</tt> from the collection.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the collection was modified by the remove all operation.
|
||||
*/
|
||||
boolean removeAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>TByteCollection</tt> from the collection.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the collection was modified by the remove all operation.
|
||||
*/
|
||||
boolean removeAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>array</tt> from the collection.
|
||||
*
|
||||
* @param array an <code>array</code> of byte primitives.
|
||||
* @return true if the collection was modified by the remove all operation.
|
||||
*/
|
||||
boolean removeAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Empties the collection.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
|
||||
/**
|
||||
* Executes <tt>procedure</tt> for each element in the collection.
|
||||
*
|
||||
* @param procedure a <code>TByteProcedure</code> value
|
||||
* @return false if the loop over the collection terminated because
|
||||
* the procedure returned false for some value.
|
||||
*/
|
||||
boolean forEach( TByteProcedure procedure );
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this collection for equality. Returns
|
||||
* <tt>true</tt> if the specified object is also a collection, the two collection
|
||||
* have the same size, and every member of the specified collection is
|
||||
* contained in this collection (or equivalently, every member of this collection is
|
||||
* contained in the specified collection). This definition ensures that the
|
||||
* equals method works properly across different implementations of the
|
||||
* collection interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this collection
|
||||
* @return <tt>true</tt> if the specified object is equal to this collection
|
||||
*/
|
||||
boolean equals( Object o );
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this collection. The hash code of a collection is
|
||||
* defined to be the sum of the hash codes of the elements in the collection.
|
||||
* This ensures that <tt>s1.equals(s2)</tt> implies that
|
||||
* <tt>s1.hashCode()==s2.hashCode()</tt> for any two collection <tt>s1</tt>
|
||||
* and <tt>s2</tt>, as required by the general contract of
|
||||
* {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this collection
|
||||
* @see Object#equals(Object)
|
||||
* @see Collection#equals(Object)
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
|
||||
} // TByteCollection
|
|
@ -0,0 +1,592 @@
|
|||
/*
|
||||
* ///////////////////////////////////////////////////////////////////////////////
|
||||
* // Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
* // Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
* //
|
||||
* // This library is free software; you can redistribute it and/or
|
||||
* // modify it under the terms of the GNU Lesser General Public
|
||||
* // License as published by the Free Software Foundation; either
|
||||
* // version 2.1 of the License, or (at your option) any later version.
|
||||
* //
|
||||
* // This library is distributed in the hope that it will be useful,
|
||||
* // but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* // GNU General Public License for more details.
|
||||
* //
|
||||
* // You should have received a copy of the GNU Lesser General Public
|
||||
* // License along with this program; if not, write to the Free Software
|
||||
* // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
* ///////////////////////////////////////////////////////////////////////////////
|
||||
*/
|
||||
package gnu.trove.generator;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class Generator {
|
||||
private static final WrapperInfo[] WRAPPERS = new WrapperInfo[]{
|
||||
new WrapperInfo("byte", "Byte", "MAX_VALUE", "MIN_VALUE")};
|
||||
|
||||
private static final Pattern PATTERN_v;
|
||||
private static final Pattern PATTERN_V;
|
||||
private static final Pattern PATTERN_VC;
|
||||
private static final Pattern PATTERN_VT;
|
||||
private static final Pattern PATTERN_VMAX;
|
||||
private static final Pattern PATTERN_VMIN;
|
||||
private static final Pattern PATTERN_V_UNDERBAR;
|
||||
|
||||
private static final Pattern PATTERN_k;
|
||||
private static final Pattern PATTERN_K;
|
||||
private static final Pattern PATTERN_KC;
|
||||
private static final Pattern PATTERN_KT;
|
||||
private static final Pattern PATTERN_KMAX;
|
||||
private static final Pattern PATTERN_KMIN;
|
||||
private static final Pattern PATTERN_K_UNDERBAR;
|
||||
|
||||
private static final Pattern PATTERN_e;
|
||||
private static final Pattern PATTERN_E;
|
||||
private static final Pattern PATTERN_EC;
|
||||
private static final Pattern PATTERN_ET;
|
||||
private static final Pattern PATTERN_EMAX;
|
||||
private static final Pattern PATTERN_EMIN;
|
||||
private static final Pattern PATTERN_E_UNDERBAR;
|
||||
|
||||
static {
|
||||
PATTERN_v = Pattern.compile("#v#");
|
||||
PATTERN_V = Pattern.compile("#V#");
|
||||
PATTERN_VC = Pattern.compile("#VC#");
|
||||
PATTERN_VT = Pattern.compile("#VT#");
|
||||
PATTERN_VMAX = Pattern.compile("#VMAX#");
|
||||
PATTERN_VMIN = Pattern.compile("#VMIN#");
|
||||
PATTERN_V_UNDERBAR = Pattern.compile("_V_");
|
||||
|
||||
PATTERN_k = Pattern.compile("#k#");
|
||||
PATTERN_K = Pattern.compile("#K#");
|
||||
PATTERN_KC = Pattern.compile("#KC#");
|
||||
PATTERN_KT = Pattern.compile("#KT#");
|
||||
PATTERN_KMAX = Pattern.compile("#KMAX#");
|
||||
PATTERN_KMIN = Pattern.compile("#KMIN#");
|
||||
PATTERN_K_UNDERBAR = Pattern.compile("_K_");
|
||||
|
||||
PATTERN_e = Pattern.compile("#e#");
|
||||
PATTERN_E = Pattern.compile("#E#");
|
||||
PATTERN_EC = Pattern.compile("#EC#");
|
||||
PATTERN_ET = Pattern.compile("#ET#");
|
||||
PATTERN_EMAX = Pattern.compile("#EMAX#");
|
||||
PATTERN_EMIN = Pattern.compile("#EMIN#");
|
||||
PATTERN_E_UNDERBAR = Pattern.compile("_E_");
|
||||
}
|
||||
|
||||
|
||||
private static File root_output_dir;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*if (args.length == 0) {
|
||||
System.out.println("Usage: Generator [-c] <input_dir> <output_dir>");
|
||||
return;
|
||||
}*/
|
||||
|
||||
File input_directory = new File("C:\\Users\\Administrator\\Desktop\\trove-3.0.0\\templates");
|
||||
File output_directory = new File("C:\\Users\\Administrator\\Desktop\\trove-3.0.0\\templates2");
|
||||
if (!input_directory.exists()) {
|
||||
System.err.println("Directory \"" + input_directory + "\" not found.");
|
||||
System.exit(-1);
|
||||
return;
|
||||
}
|
||||
if (!output_directory.exists()) {
|
||||
makeDirs(output_directory);
|
||||
}
|
||||
|
||||
root_output_dir = output_directory;
|
||||
|
||||
System.out.println("Removing contents of \"" + output_directory + "\"...");
|
||||
cleanDir(output_directory);
|
||||
|
||||
scanForFiles(input_directory, output_directory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates dirs, throw IllegalArgumentException or IllegalStateException if
|
||||
* argument is invalid or creation fails
|
||||
*
|
||||
* @param directory
|
||||
*/
|
||||
private static void makeDirs(File directory) {
|
||||
if (directory.exists() && !directory.isDirectory())
|
||||
throw new IllegalArgumentException(directory + " not a directory");
|
||||
|
||||
if (directory.exists())
|
||||
return;
|
||||
|
||||
if (!directory.mkdirs())
|
||||
throw new IllegalStateException("Could not create directories " + directory);
|
||||
}
|
||||
|
||||
|
||||
private static void scanForFiles(File input_directory, File output_directory)
|
||||
throws IOException {
|
||||
|
||||
File[] files = input_directory.listFiles();
|
||||
for (File file : files) {
|
||||
// Ignore hidden files
|
||||
if (file.isHidden()) continue;
|
||||
|
||||
if (file.isDirectory()) {
|
||||
// Ignore CVS directories
|
||||
if (file.getName().equals("CVS")) continue;
|
||||
|
||||
scanForFiles(file, new File(output_directory, file.getName()));
|
||||
continue;
|
||||
}
|
||||
|
||||
processFile(file, output_directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void processFile(File input_file, File output_directory)
|
||||
throws IOException {
|
||||
|
||||
System.out.println("Process file: " + input_file);
|
||||
|
||||
String content = readFile(input_file);
|
||||
|
||||
String file_name = input_file.getName();
|
||||
file_name = file_name.replaceAll("\\.template", ".java");
|
||||
|
||||
File output_file = new File(output_directory, file_name);
|
||||
|
||||
// See what kind of template markers it's using, either e or k/v. No marker
|
||||
// indicates a replication-only class.
|
||||
if (file_name.contains("_K_")) {
|
||||
processKVMarkers(content, output_directory, file_name);
|
||||
} else if (file_name.contains("_E_")) {
|
||||
processEMarkers(content, output_directory, file_name);
|
||||
} else {
|
||||
if (input_file.lastModified() < output_file.lastModified()) {
|
||||
System.out.println("File " + output_file + " up to date, not processing input");
|
||||
return;
|
||||
}
|
||||
|
||||
// Replication only
|
||||
StringBuilder processed_replication_output = new StringBuilder();
|
||||
Map<Integer, String> replicated_blocks =
|
||||
findReplicatedBlocks(content, processed_replication_output);
|
||||
if (replicated_blocks != null) {
|
||||
content = processReplication(processed_replication_output.toString(),
|
||||
replicated_blocks);
|
||||
}
|
||||
|
||||
writeFile(content, output_file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void processKVMarkers(String content, File output_dir,
|
||||
String file_name) throws IOException {
|
||||
|
||||
for (WrapperInfo info : WRAPPERS) {
|
||||
String k = info.primitive;
|
||||
String KT = info.class_name;
|
||||
String K = abbreviate(KT);
|
||||
String KC = K.toUpperCase();
|
||||
String KMAX = info.max_value;
|
||||
String KMIN = info.min_value;
|
||||
|
||||
String out = content;
|
||||
out = PATTERN_k.matcher(out).replaceAll(k);
|
||||
out = PATTERN_K.matcher(out).replaceAll(K);
|
||||
out = PATTERN_KC.matcher(out).replaceAll(KC);
|
||||
out = PATTERN_KT.matcher(out).replaceAll(KT);
|
||||
out = PATTERN_KMAX.matcher(out).replaceAll(KMAX);
|
||||
out = PATTERN_KMIN.matcher(out).replaceAll(KMIN);
|
||||
|
||||
String out_file_name = "T" + file_name;
|
||||
out_file_name = PATTERN_K_UNDERBAR.matcher(out_file_name).replaceAll(K);
|
||||
|
||||
for (WrapperInfo jinfo : WRAPPERS) {
|
||||
String v = jinfo.primitive;
|
||||
String VT = jinfo.class_name;
|
||||
String V = abbreviate(VT);
|
||||
String VC = V.toUpperCase();
|
||||
String VMAX = jinfo.max_value;
|
||||
String VMIN = jinfo.min_value;
|
||||
|
||||
String vout = out;
|
||||
|
||||
vout = PATTERN_v.matcher(vout).replaceAll(v);
|
||||
vout = PATTERN_V.matcher(vout).replaceAll(V);
|
||||
vout = PATTERN_VC.matcher(vout).replaceAll(VC);
|
||||
vout = PATTERN_VT.matcher(vout).replaceAll(VT);
|
||||
vout = PATTERN_VMAX.matcher(vout).replaceAll(VMAX);
|
||||
String processed_output = PATTERN_VMIN.matcher(vout).replaceAll(VMIN);
|
||||
|
||||
StringBuilder processed_replication_output = new StringBuilder();
|
||||
Map<Integer, String> replicated_blocks =
|
||||
findReplicatedBlocks(processed_output, processed_replication_output);
|
||||
if (replicated_blocks != null) {
|
||||
processed_output = processReplication(
|
||||
processed_replication_output.toString(), replicated_blocks);
|
||||
}
|
||||
|
||||
String processed_filename =
|
||||
PATTERN_V_UNDERBAR.matcher(out_file_name).replaceAll(V);
|
||||
|
||||
writeFile(processed_output, new File(output_dir, processed_filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void processEMarkers(String content, File output_dir,
|
||||
String file_name) throws IOException {
|
||||
|
||||
for (WrapperInfo info : WRAPPERS) {
|
||||
String e = info.primitive;
|
||||
String ET = info.class_name;
|
||||
String E = abbreviate(ET);
|
||||
String EC = E.toUpperCase();
|
||||
String EMAX = info.max_value;
|
||||
String EMIN = info.min_value;
|
||||
|
||||
String out = content;
|
||||
out = PATTERN_e.matcher(out).replaceAll(e);
|
||||
out = PATTERN_E.matcher(out).replaceAll(E);
|
||||
out = PATTERN_EC.matcher(out).replaceAll(EC);
|
||||
out = PATTERN_ET.matcher(out).replaceAll(ET);
|
||||
out = PATTERN_EMAX.matcher(out).replaceAll(EMAX);
|
||||
String processed_output = PATTERN_EMIN.matcher(out).replaceAll(EMIN);
|
||||
|
||||
String out_file_name = "T" + file_name;
|
||||
out_file_name = PATTERN_E_UNDERBAR.matcher(out_file_name).replaceAll(E);
|
||||
|
||||
StringBuilder processed_replication_output = new StringBuilder();
|
||||
Map<Integer, String> replicated_blocks =
|
||||
findReplicatedBlocks(processed_output, processed_replication_output);
|
||||
if (replicated_blocks != null) {
|
||||
processed_output = processReplication(
|
||||
processed_replication_output.toString(), replicated_blocks);
|
||||
}
|
||||
|
||||
writeFile(processed_output, new File(output_dir, out_file_name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static String processReplication(String content,
|
||||
Map<Integer, String> replicated_blocks) {
|
||||
|
||||
for (Map.Entry<Integer, String> entry : replicated_blocks.entrySet()) {
|
||||
// Replace the markers in the replicated content
|
||||
|
||||
StringBuilder entry_buffer = new StringBuilder();
|
||||
|
||||
boolean first_loop = true;
|
||||
for (int i = 0; i < WRAPPERS.length; i++) {
|
||||
WrapperInfo info = WRAPPERS[i];
|
||||
|
||||
String k = info.primitive;
|
||||
String KT = info.class_name;
|
||||
String K = abbreviate(KT);
|
||||
String KC = K.toUpperCase();
|
||||
String KMAX = info.max_value;
|
||||
String KMIN = info.min_value;
|
||||
|
||||
for (int j = 0; j < WRAPPERS.length; j++) {
|
||||
WrapperInfo jinfo = WRAPPERS[j];
|
||||
|
||||
String v = jinfo.primitive;
|
||||
String VT = jinfo.class_name;
|
||||
String V = abbreviate(VT);
|
||||
String VC = V.toUpperCase();
|
||||
String VMAX = jinfo.max_value;
|
||||
String VMIN = jinfo.min_value;
|
||||
|
||||
String out = entry.getValue();
|
||||
String before_e = out;
|
||||
out = Pattern.compile("#e#").matcher(out).replaceAll(k);
|
||||
out = Pattern.compile("#E#").matcher(out).replaceAll(K);
|
||||
out = Pattern.compile("#ET#").matcher(out).replaceAll(KT);
|
||||
out = Pattern.compile("#EC#").matcher(out).replaceAll(KC);
|
||||
out = Pattern.compile("#EMAX#").matcher(out).replaceAll(KMAX);
|
||||
out = Pattern.compile("#EMIN#").matcher(out).replaceAll(KMIN);
|
||||
boolean uses_e = !out.equals(before_e);
|
||||
|
||||
// If we use "e" (instead of "k" & "v", then we don't need the inner
|
||||
// map. Yeah, this is ugly I know... but it works.
|
||||
if (uses_e && j != 0) break;
|
||||
|
||||
out = Pattern.compile("#v#").matcher(out).replaceAll(v);
|
||||
out = Pattern.compile("#V#").matcher(out).replaceAll(V);
|
||||
out = Pattern.compile("#VT#").matcher(out).replaceAll(VT);
|
||||
out = Pattern.compile("#VC#").matcher(out).replaceAll(VC);
|
||||
out = Pattern.compile("#VMAX#").matcher(out).replaceAll(VMAX);
|
||||
out = Pattern.compile("#VMIN#").matcher(out).replaceAll(VMIN);
|
||||
|
||||
out = Pattern.compile("#k#").matcher(out).replaceAll(k);
|
||||
out = Pattern.compile("#K#").matcher(out).replaceAll(K);
|
||||
out = Pattern.compile("#KT#").matcher(out).replaceAll(KT);
|
||||
out = Pattern.compile("#KC#").matcher(out).replaceAll(KC);
|
||||
out = Pattern.compile("#KMAX#").matcher(out).replaceAll(KMAX);
|
||||
out = Pattern.compile("#KMIN#").matcher(out).replaceAll(KMIN);
|
||||
|
||||
if (first_loop) first_loop = false;
|
||||
else {
|
||||
entry_buffer.append("\n\n");
|
||||
}
|
||||
|
||||
entry_buffer.append(out);
|
||||
}
|
||||
}
|
||||
|
||||
content = Pattern.compile("#REPLICATED" + entry.getKey() + "#").matcher(
|
||||
content).replaceAll(entry_buffer.toString());
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
private static void writeFile(String content, File output_file)
|
||||
throws IOException {
|
||||
|
||||
File parent = output_file.getParentFile();
|
||||
makeDirs(parent);
|
||||
|
||||
// Write to a temporary file
|
||||
File temp = File.createTempFile("trove", "gentemp",
|
||||
new File(System.getProperty("java.io.tmpdir")));
|
||||
Writer writer = new BufferedWriter(new FileWriter(temp));
|
||||
writer.write(content);
|
||||
writer.close();
|
||||
|
||||
|
||||
// Now determine if it should be moved to the final location
|
||||
final boolean need_to_move;
|
||||
if (output_file.exists()) {
|
||||
boolean matches;
|
||||
try {
|
||||
MessageDigest digest = MessageDigest.getInstance("MD5");
|
||||
|
||||
byte[] current_file = digest(output_file, digest);
|
||||
byte[] new_file = digest(temp, digest);
|
||||
|
||||
matches = Arrays.equals(current_file, new_file);
|
||||
} catch (NoSuchAlgorithmException ex) {
|
||||
System.err.println(
|
||||
"WARNING: Couldn't load digest algorithm to compare " +
|
||||
"new and old template. Generation will be forced.");
|
||||
matches = false;
|
||||
}
|
||||
|
||||
need_to_move = !matches;
|
||||
} else need_to_move = true;
|
||||
|
||||
|
||||
// Now move it if we need to move it
|
||||
if (need_to_move) {
|
||||
delete(output_file);
|
||||
copyFile( temp, output_file );
|
||||
System.out.println(" Wrote: " + simplifyPath(output_file));
|
||||
} else {
|
||||
System.out.println(" Skipped: " + simplifyPath(output_file));
|
||||
delete(temp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the given file, throws IllegalStateException if delete operation fails
|
||||
*
|
||||
* @param output_file
|
||||
*/
|
||||
private static void delete(File output_file) {
|
||||
if (!output_file.exists())
|
||||
return;
|
||||
|
||||
if (!output_file.delete())
|
||||
throw new IllegalStateException("Could not delete " + output_file);
|
||||
}
|
||||
|
||||
|
||||
private static byte[] digest(File file, MessageDigest digest) throws IOException {
|
||||
digest.reset();
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
InputStream in = new BufferedInputStream(new FileInputStream(file));
|
||||
try {
|
||||
int read = in.read(buffer);
|
||||
while (read >= 0) {
|
||||
digest.update(buffer, 0, read);
|
||||
|
||||
read = in.read(buffer);
|
||||
}
|
||||
|
||||
return digest.digest();
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Abbreviate the type for Integer and Character
|
||||
*/
|
||||
private static String abbreviate(String type) {
|
||||
if (type.equals("Integer")) {
|
||||
return "Int";
|
||||
} else if (type.equals("Character")) {
|
||||
return "Char";
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
private static String readFile(File input_file) throws IOException {
|
||||
if (!input_file.exists()) {
|
||||
throw new NullPointerException("Couldn't find: " + input_file);
|
||||
}
|
||||
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
reader = new BufferedReader(new FileReader(input_file));
|
||||
StringBuilder out = new StringBuilder();
|
||||
|
||||
while (true) {
|
||||
String line = reader.readLine();
|
||||
if (line == null) break;
|
||||
out.append(line);
|
||||
out.append("\n");
|
||||
}
|
||||
return out.toString();
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ex) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Find replicated block definitions at the end of content.
|
||||
*
|
||||
* @param content_in The content
|
||||
* @param content_out A StringBuffer into which the content (without the
|
||||
* definition blocks is placed). This will be untouched
|
||||
* if no definition blocks are found.
|
||||
* @return Null if no definition blocks are found, otherwise a map
|
||||
* containing the blocks, keyed by their number.
|
||||
*/
|
||||
static Map<Integer, String> findReplicatedBlocks(String content_in,
|
||||
StringBuilder content_out) throws IOException {
|
||||
|
||||
Map<Integer, String> to_return = null;
|
||||
|
||||
// Find the replicated content blocks in the template. For ease, read this line
|
||||
// by line.
|
||||
BufferedReader reader = new BufferedReader(new StringReader(content_in));
|
||||
String line;
|
||||
StringBuilder buffer = new StringBuilder();
|
||||
boolean in_replicated_block = false;
|
||||
boolean need_newline = false;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (!in_replicated_block &&
|
||||
line.startsWith("====START_REPLICATED_CONTENT #")) {
|
||||
|
||||
in_replicated_block = true;
|
||||
need_newline = false;
|
||||
|
||||
if (content_out.length() == 0) {
|
||||
content_out.append(buffer.toString());
|
||||
}
|
||||
|
||||
buffer = new StringBuilder();
|
||||
} else if (in_replicated_block &&
|
||||
line.startsWith("=====END_REPLICATED_CONTENT #")) {
|
||||
int number_start_index = "=====END_REPLICATED_CONTENT #".length();
|
||||
int number_end_index = line.indexOf("=", number_start_index);
|
||||
|
||||
String number = line.substring(number_start_index, number_end_index);
|
||||
Integer number_obj = Integer.valueOf(number);
|
||||
|
||||
if (to_return == null) to_return = new HashMap<Integer, String>();
|
||||
to_return.put(number_obj, buffer.toString());
|
||||
|
||||
in_replicated_block = false;
|
||||
need_newline = false;
|
||||
} else {
|
||||
if (need_newline) buffer.append("\n");
|
||||
else need_newline = true;
|
||||
|
||||
buffer.append(line);
|
||||
}
|
||||
}
|
||||
|
||||
return to_return;
|
||||
}
|
||||
|
||||
|
||||
private static String simplifyPath(File file) {
|
||||
String output_string = root_output_dir.toString();
|
||||
|
||||
String file_string = file.toString();
|
||||
return file_string.substring(output_string.length() + 1);
|
||||
}
|
||||
|
||||
|
||||
private static void cleanDir(File directory) {
|
||||
for (File file : directory.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
cleanDir(file);
|
||||
delete(file);
|
||||
}
|
||||
|
||||
delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static void copyFile( File source, File dest ) throws IOException {
|
||||
FileChannel srcChannel = new FileInputStream( source ).getChannel();
|
||||
// Create channel on the destination
|
||||
FileChannel dstChannel = new FileOutputStream( dest ).getChannel();
|
||||
// Copy file contents from source to destination
|
||||
dstChannel.transferFrom(srcChannel, 0, srcChannel.size());
|
||||
// Close the channels
|
||||
srcChannel.close();
|
||||
dstChannel.close();
|
||||
}
|
||||
|
||||
|
||||
private static class WrapperInfo {
|
||||
final String primitive;
|
||||
final String class_name;
|
||||
final String max_value;
|
||||
final String min_value;
|
||||
|
||||
WrapperInfo(String primitive, String class_name, String max_value,
|
||||
String min_value) {
|
||||
|
||||
this.primitive = primitive;
|
||||
this.class_name = class_name;
|
||||
this.max_value = class_name + "." + max_value;
|
||||
this.min_value = class_name + "." + min_value;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
package gnu.trove.impl;
|
||||
|
||||
/**
|
||||
* Central location for constants needed by various implementations.
|
||||
*/
|
||||
public class Constants {
|
||||
|
||||
private static final boolean VERBOSE =
|
||||
System.getProperty( "gnu.trove.verbose", null ) != null;
|
||||
|
||||
/** the default capacity for new collections */
|
||||
public static final int DEFAULT_CAPACITY = 10;
|
||||
|
||||
/** the load above which rehashing occurs. */
|
||||
public static final float DEFAULT_LOAD_FACTOR = 0.5f;
|
||||
|
||||
|
||||
/** the default value that represents for <tt>byte</tt> types. */
|
||||
public static final byte DEFAULT_BYTE_NO_ENTRY_VALUE;
|
||||
static {
|
||||
byte value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.byte", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Byte.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Byte.MIN_VALUE;
|
||||
else value = Byte.valueOf( property );
|
||||
|
||||
if ( value > Byte.MAX_VALUE ) value = Byte.MAX_VALUE;
|
||||
else if ( value < Byte.MIN_VALUE ) value = Byte.MIN_VALUE;
|
||||
DEFAULT_BYTE_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_BYTE_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_BYTE_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>short</tt> types. */
|
||||
public static final short DEFAULT_SHORT_NO_ENTRY_VALUE;
|
||||
static {
|
||||
short value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.short", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Short.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Short.MIN_VALUE;
|
||||
else value = Short.valueOf( property );
|
||||
|
||||
if ( value > Short.MAX_VALUE ) value = Short.MAX_VALUE;
|
||||
else if ( value < Short.MIN_VALUE ) value = Short.MIN_VALUE;
|
||||
DEFAULT_SHORT_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_SHORT_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_SHORT_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>char</tt> types. */
|
||||
public static final char DEFAULT_CHAR_NO_ENTRY_VALUE;
|
||||
static {
|
||||
char value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.char", "\0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Character.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Character.MIN_VALUE;
|
||||
else value = property.toCharArray()[0];
|
||||
|
||||
if ( value > Character.MAX_VALUE ) value = Character.MAX_VALUE;
|
||||
else if ( value < Character.MIN_VALUE ) value = Character.MIN_VALUE;
|
||||
DEFAULT_CHAR_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_CHAR_NO_ENTRY_VALUE: " +
|
||||
Integer.valueOf( value ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>int</tt> types. */
|
||||
public static final int DEFAULT_INT_NO_ENTRY_VALUE;
|
||||
static {
|
||||
int value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.int", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Integer.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Integer.MIN_VALUE;
|
||||
else value = Integer.valueOf( property );
|
||||
DEFAULT_INT_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_INT_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_INT_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>long</tt> types. */
|
||||
public static final long DEFAULT_LONG_NO_ENTRY_VALUE;
|
||||
static {
|
||||
long value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.long", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Long.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Long.MIN_VALUE;
|
||||
else value = Long.valueOf( property );
|
||||
DEFAULT_LONG_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_LONG_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_LONG_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>float</tt> types. */
|
||||
public static final float DEFAULT_FLOAT_NO_ENTRY_VALUE;
|
||||
static {
|
||||
float value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.float", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Float.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Float.MIN_VALUE;
|
||||
// Value from Float.MIN_NORMAL (introduced in 1.6)
|
||||
else if ( "MIN_NORMAL".equalsIgnoreCase( property ) ) value = 0x1.0p-126f;
|
||||
else if ( "NEGATIVE_INFINITY".equalsIgnoreCase( property ) ) value = Float.NEGATIVE_INFINITY;
|
||||
else if ( "POSITIVE_INFINITY".equalsIgnoreCase( property ) ) value = Float.POSITIVE_INFINITY;
|
||||
// else if ( "NaN".equalsIgnoreCase( property ) ) value = Float.NaN;
|
||||
else value = Float.valueOf( property );
|
||||
DEFAULT_FLOAT_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_FLOAT_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_FLOAT_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** the default value that represents for <tt>double</tt> types. */
|
||||
public static final double DEFAULT_DOUBLE_NO_ENTRY_VALUE;
|
||||
static {
|
||||
double value;
|
||||
String property = System.getProperty( "gnu.trove.no_entry.double", "0" );
|
||||
if ( "MAX_VALUE".equalsIgnoreCase( property ) ) value = Double.MAX_VALUE;
|
||||
else if ( "MIN_VALUE".equalsIgnoreCase( property ) ) value = Double.MIN_VALUE;
|
||||
// Value from Double.MIN_NORMAL (introduced in 1.6)
|
||||
else if ( "MIN_NORMAL".equalsIgnoreCase( property ) ) value = 0x1.0p-1022;
|
||||
else if ( "NEGATIVE_INFINITY".equalsIgnoreCase( property ) ) value = Double.NEGATIVE_INFINITY;
|
||||
else if ( "POSITIVE_INFINITY".equalsIgnoreCase( property ) ) value = Double.POSITIVE_INFINITY;
|
||||
// else if ( "NaN".equalsIgnoreCase( property ) ) value = Double.NaN;
|
||||
else value = Double.valueOf( property );
|
||||
DEFAULT_DOUBLE_NO_ENTRY_VALUE = value;
|
||||
if ( VERBOSE ) {
|
||||
System.out.println( "DEFAULT_DOUBLE_NO_ENTRY_VALUE: " +
|
||||
DEFAULT_DOUBLE_NO_ENTRY_VALUE );
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
// Copyright (c) 1999 CERN - European Organization for Nuclear Research.
|
||||
|
||||
// Permission to use, copy, modify, distribute and sell this software and
|
||||
// its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and that
|
||||
// both that copyright notice and this permission notice appear in
|
||||
// supporting documentation. CERN makes no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without expressed or implied warranty.
|
||||
|
||||
package gnu.trove.impl;
|
||||
|
||||
/**
|
||||
* Provides various hash functions.
|
||||
*
|
||||
* @author wolfgang.hoschek@cern.ch
|
||||
* @version 1.0, 09/24/99
|
||||
*/
|
||||
public final class HashFunctions {
|
||||
/**
|
||||
* Returns a hashcode for the specified value.
|
||||
*
|
||||
* @return a hash code value for the specified value.
|
||||
*/
|
||||
public static int hash(double value) {
|
||||
assert !Double.isNaN(value) : "Values of NaN are not supported.";
|
||||
|
||||
long bits = Double.doubleToLongBits(value);
|
||||
return (int)(bits ^ (bits >>> 32));
|
||||
//return (int) Double.doubleToLongBits(value*663608941.737);
|
||||
//this avoids excessive hashCollisions in the case values are
|
||||
//of the form (1.0, 2.0, 3.0, ...)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for the specified value.
|
||||
*
|
||||
* @return a hash code value for the specified value.
|
||||
*/
|
||||
public static int hash(float value) {
|
||||
assert !Float.isNaN(value) : "Values of NaN are not supported.";
|
||||
|
||||
return Float.floatToIntBits(value*663608941.737f);
|
||||
// this avoids excessive hashCollisions in the case values are
|
||||
// of the form (1.0, 2.0, 3.0, ...)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for the specified value.
|
||||
*
|
||||
* @return a hash code value for the specified value.
|
||||
*/
|
||||
public static int hash(int value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for the specified value.
|
||||
*
|
||||
* @return a hash code value for the specified value.
|
||||
*/
|
||||
public static int hash(long value) {
|
||||
return ((int)(value ^ (value >>> 32)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a hashcode for the specified object.
|
||||
*
|
||||
* @return a hash code value for the specified object.
|
||||
*/
|
||||
public static int hash(Object object) {
|
||||
return object==null ? 0 : object.hashCode();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In profiling, it has been found to be faster to have our own local implementation
|
||||
* of "ceil" rather than to call to {@link Math#ceil(double)}.
|
||||
*/
|
||||
public static int fastCeil( float v ) {
|
||||
int possible_result = ( int ) v;
|
||||
if ( v - possible_result > 0 ) possible_result++;
|
||||
return possible_result;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,158 @@
|
|||
// Copyright (c) 1999 CERN - European Organization for Nuclear Research.
|
||||
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear in
|
||||
// supporting documentation. CERN makes no representations about the
|
||||
// suitability of this software for any purpose. It is provided "as is"
|
||||
// without expressed or implied warranty.
|
||||
package gnu.trove.impl;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* Modified for Trove to use the java.util.Arrays sort/search
|
||||
* algorithms instead of those provided with colt.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Used to keep hash table capacities prime numbers.
|
||||
* Not of interest for users; only for implementors of hashtables.
|
||||
*
|
||||
* <p>Choosing prime numbers as hash table capacities is a good idea
|
||||
* to keep them working fast, particularly under hash table
|
||||
* expansions.
|
||||
*
|
||||
* <p>However, JDK 1.2, JGL 3.1 and many other toolkits do nothing to
|
||||
* keep capacities prime. This class provides efficient means to
|
||||
* choose prime capacities.
|
||||
*
|
||||
* <p>Choosing a prime is <tt>O(log 300)</tt> (binary search in a list
|
||||
* of 300 ints). Memory requirements: 1 KB static memory.
|
||||
*
|
||||
* @author wolfgang.hoschek@cern.ch
|
||||
* @version 1.0, 09/24/99
|
||||
*/
|
||||
public final class PrimeFinder {
|
||||
/**
|
||||
* The largest prime this class can generate; currently equal to
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*/
|
||||
public static final int largestPrime = Integer.MAX_VALUE; //yes, it is prime.
|
||||
|
||||
/**
|
||||
* The prime number list consists of 11 chunks.
|
||||
*
|
||||
* Each chunk contains prime numbers.
|
||||
*
|
||||
* A chunk starts with a prime P1. The next element is a prime
|
||||
* P2. P2 is the smallest prime for which holds: P2 >= 2*P1.
|
||||
*
|
||||
* The next element is P3, for which the same holds with respect
|
||||
* to P2, and so on.
|
||||
*
|
||||
* Chunks are chosen such that for any desired capacity >= 1000
|
||||
* the list includes a prime number <= desired capacity * 1.11.
|
||||
*
|
||||
* Therefore, primes can be retrieved which are quite close to any
|
||||
* desired capacity, which in turn avoids wasting memory.
|
||||
*
|
||||
* For example, the list includes
|
||||
* 1039,1117,1201,1277,1361,1439,1523,1597,1759,1907,2081.
|
||||
*
|
||||
* So if you need a prime >= 1040, you will find a prime <=
|
||||
* 1040*1.11=1154.
|
||||
*
|
||||
* Chunks are chosen such that they are optimized for a hashtable
|
||||
* growthfactor of 2.0;
|
||||
*
|
||||
* If your hashtable has such a growthfactor then, after initially
|
||||
* "rounding to a prime" upon hashtable construction, it will
|
||||
* later expand to prime capacities such that there exist no
|
||||
* better primes.
|
||||
*
|
||||
* In total these are about 32*10=320 numbers -> 1 KB of static
|
||||
* memory needed.
|
||||
*
|
||||
* If you are stingy, then delete every second or fourth chunk.
|
||||
*/
|
||||
|
||||
private static final int[] primeCapacities = {
|
||||
//chunk #0
|
||||
largestPrime,
|
||||
|
||||
//chunk #1
|
||||
5,11,23,47,97,197,397,797,1597,3203,6421,12853,25717,51437,102877,205759,
|
||||
411527,823117,1646237,3292489,6584983,13169977,26339969,52679969,105359939,
|
||||
210719881,421439783,842879579,1685759167,
|
||||
|
||||
//chunk #2
|
||||
433,877,1759,3527,7057,14143,28289,56591,113189,226379,452759,905551,1811107,
|
||||
3622219,7244441,14488931,28977863,57955739,115911563,231823147,463646329,927292699,
|
||||
1854585413,
|
||||
|
||||
//chunk #3
|
||||
953,1907,3821,7643,15287,30577,61169,122347,244703,489407,978821,1957651,3915341,
|
||||
7830701,15661423,31322867,62645741,125291483,250582987,501165979,1002331963,
|
||||
2004663929,
|
||||
|
||||
//chunk #4
|
||||
1039,2081,4177,8363,16729,33461,66923,133853,267713,535481,1070981,2141977,4283963,
|
||||
8567929,17135863,34271747,68543509,137087021,274174111,548348231,1096696463,
|
||||
|
||||
//chunk #5
|
||||
31,67,137,277,557,1117,2237,4481,8963,17929,35863,71741,143483,286973,573953,
|
||||
1147921,2295859,4591721,9183457,18366923,36733847,73467739,146935499,293871013,
|
||||
587742049,1175484103,
|
||||
|
||||
//chunk #6
|
||||
599,1201,2411,4831,9677,19373,38747,77509,155027,310081,620171,1240361,2480729,
|
||||
4961459,9922933,19845871,39691759,79383533,158767069,317534141,635068283,1270136683,
|
||||
|
||||
//chunk #7
|
||||
311,631,1277,2557,5119,10243,20507,41017,82037,164089,328213,656429,1312867,
|
||||
2625761,5251529,10503061,21006137,42012281,84024581,168049163,336098327,672196673,
|
||||
1344393353,
|
||||
|
||||
//chunk #8
|
||||
3,7,17,37,79,163,331,673,1361,2729,5471,10949,21911,43853,87719,175447,350899,
|
||||
701819,1403641,2807303,5614657,11229331,22458671,44917381,89834777,179669557,
|
||||
359339171,718678369,1437356741,
|
||||
|
||||
//chunk #9
|
||||
43,89,179,359,719,1439,2879,5779,11579,23159,46327,92657,185323,370661,741337,
|
||||
1482707,2965421,5930887,11861791,23723597,47447201,94894427,189788857,379577741,
|
||||
759155483,1518310967,
|
||||
|
||||
//chunk #10
|
||||
379,761,1523,3049,6101,12203,24407,48817,97649,195311,390647,781301,1562611,
|
||||
3125257,6250537,12501169,25002389,50004791,100009607,200019221,400038451,800076929,
|
||||
1600153859
|
||||
};
|
||||
|
||||
static { //initializer
|
||||
// The above prime numbers are formatted for human readability.
|
||||
// To find numbers fast, we sort them once and for all.
|
||||
|
||||
Arrays.sort(primeCapacities);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prime number which is <code>>= desiredCapacity</code>
|
||||
* and very close to <code>desiredCapacity</code> (within 11% if
|
||||
* <code>desiredCapacity >= 1000</code>).
|
||||
*
|
||||
* @param desiredCapacity the capacity desired by the user.
|
||||
* @return the capacity which should be used for a hashtable.
|
||||
*/
|
||||
public static final int nextPrime(int desiredCapacity) {
|
||||
int i = Arrays.binarySearch(primeCapacities, desiredCapacity);
|
||||
if (i<0) {
|
||||
// desired capacity not found, choose next prime greater
|
||||
// than desired capacity
|
||||
i = -i -1; // remember the semantics of binarySearch...
|
||||
}
|
||||
return primeCapacities[i];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,334 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.impl.hash;
|
||||
|
||||
import gnu.trove.procedure.TByteProcedure;
|
||||
import gnu.trove.impl.HashFunctions;
|
||||
import gnu.trove.impl.Constants;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* An open addressed hashing implementation for byte primitives.
|
||||
*
|
||||
* Created: Sun Nov 4 08:56:06 2001
|
||||
*
|
||||
* @author Eric D. Friedman, Rob Eden, Jeff Randall
|
||||
* @version $Id: _E_Hash.template,v 1.1.2.6 2009/11/07 03:36:44 robeden Exp $
|
||||
*/
|
||||
abstract public class TByteHash extends TPrimitiveHash {
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/** the set of bytes */
|
||||
public transient byte[] _set;
|
||||
|
||||
/**
|
||||
* value that represents null
|
||||
*
|
||||
* NOTE: should not be modified after the Hash is created, but is
|
||||
* not final because of Externalization
|
||||
*
|
||||
*/
|
||||
protected byte no_entry_value;
|
||||
|
||||
protected boolean consumeFreeSlot;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHash</code> instance with the default
|
||||
* capacity and load factor.
|
||||
*/
|
||||
public TByteHash() {
|
||||
super();
|
||||
no_entry_value = Constants.DEFAULT_BYTE_NO_ENTRY_VALUE;
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHash</code> instance whose capacity
|
||||
* is the next highest prime above <tt>initialCapacity + 1</tt>
|
||||
* unless that value is already prime.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
*/
|
||||
public TByteHash( int initialCapacity ) {
|
||||
super( initialCapacity );
|
||||
no_entry_value = Constants.DEFAULT_BYTE_NO_ENTRY_VALUE;
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHash</code> instance with a prime
|
||||
* value at or near the specified capacity and load factor.
|
||||
*
|
||||
* @param initialCapacity used to find a prime capacity for the table.
|
||||
* @param loadFactor used to calculate the threshold over which
|
||||
* rehashing takes place.
|
||||
*/
|
||||
public TByteHash( int initialCapacity, float loadFactor ) {
|
||||
super(initialCapacity, loadFactor);
|
||||
no_entry_value = Constants.DEFAULT_BYTE_NO_ENTRY_VALUE;
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHash</code> instance with a prime
|
||||
* value at or near the specified capacity and load factor.
|
||||
*
|
||||
* @param initialCapacity used to find a prime capacity for the table.
|
||||
* @param loadFactor used to calculate the threshold over which
|
||||
* rehashing takes place.
|
||||
* @param no_entry_value value that represents null
|
||||
*/
|
||||
public TByteHash( int initialCapacity, float loadFactor, byte no_entry_value ) {
|
||||
super(initialCapacity, loadFactor);
|
||||
this.no_entry_value = no_entry_value;
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value that is used to represent null. The default
|
||||
* value is generally zero, but can be changed during construction
|
||||
* of the collection.
|
||||
*
|
||||
* @return the value that represents null
|
||||
*/
|
||||
public byte getNoEntryValue() {
|
||||
return no_entry_value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initializes the hashtable to a prime capacity which is at least
|
||||
* <tt>initialCapacity + 1</tt>.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
* @return the actual capacity chosen
|
||||
*/
|
||||
protected int setUp( int initialCapacity ) {
|
||||
int capacity;
|
||||
|
||||
capacity = super.setUp( initialCapacity );
|
||||
_set = new byte[capacity];
|
||||
return capacity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Searches the set for <tt>val</tt>
|
||||
*
|
||||
* @param val an <code>byte</code> value
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean contains( byte val ) {
|
||||
return index(val) >= 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes <tt>procedure</tt> for each element in the set.
|
||||
*
|
||||
* @param procedure a <code>TObjectProcedure</code> value
|
||||
* @return false if the loop over the set terminated because
|
||||
* the procedure returned false for some value.
|
||||
*/
|
||||
public boolean forEach( TByteProcedure procedure ) {
|
||||
byte[] states = _states;
|
||||
byte[] set = _set;
|
||||
for ( int i = set.length; i-- > 0; ) {
|
||||
if ( states[i] == FULL && ! procedure.execute( set[i] ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Releases the element currently stored at <tt>index</tt>.
|
||||
*
|
||||
* @param index an <code>int</code> value
|
||||
*/
|
||||
protected void removeAt( int index ) {
|
||||
_set[index] = no_entry_value;
|
||||
super.removeAt( index );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Locates the index of <tt>val</tt>.
|
||||
*
|
||||
* @param val an <code>byte</code> value
|
||||
* @return the index of <tt>val</tt> or -1 if it isn't in the set.
|
||||
*/
|
||||
protected int index( byte val ) {
|
||||
int hash, index, length;
|
||||
|
||||
final byte[] states = _states;
|
||||
final byte[] set = _set;
|
||||
length = states.length;
|
||||
hash = HashFunctions.hash( val ) & 0x7fffffff;
|
||||
index = hash % length;
|
||||
byte state = states[index];
|
||||
|
||||
if (state == FREE)
|
||||
return -1;
|
||||
|
||||
if (state == FULL && set[index] == val)
|
||||
return index;
|
||||
|
||||
return indexRehashed(val, index, hash, state);
|
||||
}
|
||||
|
||||
int indexRehashed(byte key, int index, int hash, byte state) {
|
||||
// see Knuth, p. 529
|
||||
int length = _set.length;
|
||||
int probe = 1 + (hash % (length - 2));
|
||||
final int loopIndex = index;
|
||||
|
||||
do {
|
||||
index -= probe;
|
||||
if (index < 0) {
|
||||
index += length;
|
||||
}
|
||||
state = _states[index];
|
||||
//
|
||||
if (state == FREE)
|
||||
return -1;
|
||||
|
||||
//
|
||||
if (key == _set[index])
|
||||
return index;
|
||||
} while (index != loopIndex);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locates the index at which <tt>val</tt> can be inserted. if
|
||||
* there is already a value equal()ing <tt>val</tt> in the set,
|
||||
* returns that value as a negative integer.
|
||||
*
|
||||
* @param val an <code>byte</code> value
|
||||
* @return an <code>int</code> value
|
||||
*/
|
||||
protected int insertKey( byte val ) {
|
||||
int hash, index;
|
||||
|
||||
hash = HashFunctions.hash(val) & 0x7fffffff;
|
||||
index = hash % _states.length;
|
||||
byte state = _states[index];
|
||||
|
||||
consumeFreeSlot = false;
|
||||
|
||||
if (state == FREE) {
|
||||
consumeFreeSlot = true;
|
||||
insertKeyAt(index, val);
|
||||
|
||||
return index; // empty, all done
|
||||
}
|
||||
|
||||
if (state == FULL && _set[index] == val) {
|
||||
return -index - 1; // already stored
|
||||
}
|
||||
|
||||
// already FULL or REMOVED, must probe
|
||||
return insertKeyRehash(val, index, hash, state);
|
||||
}
|
||||
|
||||
int insertKeyRehash(byte val, int index, int hash, byte state) {
|
||||
// compute the double hash
|
||||
final int length = _set.length;
|
||||
int probe = 1 + (hash % (length - 2));
|
||||
final int loopIndex = index;
|
||||
int firstRemoved = -1;
|
||||
|
||||
/**
|
||||
* Look until FREE slot or we start to loop
|
||||
*/
|
||||
do {
|
||||
// Identify first removed slot
|
||||
if (state == REMOVED && firstRemoved == -1)
|
||||
firstRemoved = index;
|
||||
|
||||
index -= probe;
|
||||
if (index < 0) {
|
||||
index += length;
|
||||
}
|
||||
state = _states[index];
|
||||
|
||||
// A FREE slot stops the search
|
||||
if (state == FREE) {
|
||||
if (firstRemoved != -1) {
|
||||
insertKeyAt(firstRemoved, val);
|
||||
return firstRemoved;
|
||||
} else {
|
||||
consumeFreeSlot = true;
|
||||
insertKeyAt(index, val);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
if (state == FULL && _set[index] == val) {
|
||||
return -index - 1;
|
||||
}
|
||||
|
||||
// Detect loop
|
||||
} while (index != loopIndex);
|
||||
|
||||
// We inspected all reachable slots and did not find a FREE one
|
||||
// If we found a REMOVED slot we return the first one found
|
||||
if (firstRemoved != -1) {
|
||||
insertKeyAt(firstRemoved, val);
|
||||
return firstRemoved;
|
||||
}
|
||||
|
||||
// Can a resizing strategy be found that resizes the set?
|
||||
throw new IllegalStateException("No free or removed slots available. Key set full?!!");
|
||||
}
|
||||
|
||||
void insertKeyAt(int index, byte val) {
|
||||
_set[index] = val; // insert value
|
||||
_states[index] = FULL;
|
||||
}
|
||||
|
||||
} // TByteHash
|
|
@ -0,0 +1,428 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.impl.hash;
|
||||
|
||||
import gnu.trove.impl.Constants;
|
||||
import gnu.trove.impl.HashFunctions;
|
||||
import gnu.trove.impl.PrimeFinder;
|
||||
|
||||
import java.io.Externalizable;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base class for hashtables that use open addressing to resolve
|
||||
* collisions.
|
||||
*
|
||||
* Created: Wed Nov 28 21:11:16 2001
|
||||
*
|
||||
* @author Eric D. Friedman
|
||||
* @author Rob Eden (auto-compaction)
|
||||
* @author Jeff Randall
|
||||
*
|
||||
* @version $Id: THash.java,v 1.1.2.4 2010/03/02 00:55:34 robeden Exp $
|
||||
*/
|
||||
abstract public class THash implements Externalizable {
|
||||
static final long serialVersionUID = -1792948471915530295L;
|
||||
|
||||
/** the load above which rehashing occurs. */
|
||||
protected static final float DEFAULT_LOAD_FACTOR = Constants.DEFAULT_LOAD_FACTOR;
|
||||
|
||||
/**
|
||||
* the default initial capacity for the hash table. This is one
|
||||
* less than a prime value because one is added to it when
|
||||
* searching for a prime capacity to account for the free slot
|
||||
* required by open addressing. Thus, the real default capacity is
|
||||
* 11.
|
||||
*/
|
||||
protected static final int DEFAULT_CAPACITY = Constants.DEFAULT_CAPACITY;
|
||||
|
||||
|
||||
/** the current number of occupied slots in the hash. */
|
||||
protected transient int _size;
|
||||
|
||||
/** the current number of free slots in the hash. */
|
||||
protected transient int _free;
|
||||
|
||||
/**
|
||||
* Determines how full the internal table can become before
|
||||
* rehashing is required. This must be a value in the range: 0.0 <
|
||||
* loadFactor < 1.0. The default value is 0.5, which is about as
|
||||
* large as you can get in open addressing without hurting
|
||||
* performance. Cf. Knuth, Volume 3., Chapter 6.
|
||||
*/
|
||||
protected float _loadFactor;
|
||||
|
||||
/**
|
||||
* The maximum number of elements allowed without allocating more
|
||||
* space.
|
||||
*/
|
||||
protected int _maxSize;
|
||||
|
||||
|
||||
/** The number of removes that should be performed before an auto-compaction occurs. */
|
||||
protected int _autoCompactRemovesRemaining;
|
||||
|
||||
/**
|
||||
* The auto-compaction factor for the table.
|
||||
*
|
||||
* @see #setAutoCompactionFactor
|
||||
*/
|
||||
protected float _autoCompactionFactor;
|
||||
|
||||
/** @see #tempDisableAutoCompaction */
|
||||
protected transient boolean _autoCompactTemporaryDisable = false;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>THash</code> instance with the default
|
||||
* capacity and load factor.
|
||||
*/
|
||||
public THash() {
|
||||
this( DEFAULT_CAPACITY, DEFAULT_LOAD_FACTOR );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>THash</code> instance with a prime capacity
|
||||
* at or near the specified capacity and with the default load
|
||||
* factor.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
*/
|
||||
public THash( int initialCapacity ) {
|
||||
this( initialCapacity, DEFAULT_LOAD_FACTOR );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>THash</code> instance with a prime capacity
|
||||
* at or near the minimum needed to hold <tt>initialCapacity</tt>
|
||||
* elements with load factor <tt>loadFactor</tt> without triggering
|
||||
* a rehash.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
* @param loadFactor a <code>float</code> value
|
||||
*/
|
||||
public THash( int initialCapacity, float loadFactor ) {
|
||||
super();
|
||||
_loadFactor = loadFactor;
|
||||
|
||||
// Through testing, the load factor (especially the default load factor) has been
|
||||
// found to be a pretty good starting auto-compaction factor.
|
||||
_autoCompactionFactor = loadFactor;
|
||||
|
||||
setUp( HashFunctions.fastCeil( initialCapacity / loadFactor ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tells whether this set is currently holding any elements.
|
||||
*
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return 0 == _size;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of distinct elements in this collection.
|
||||
*
|
||||
* @return an <code>int</code> value
|
||||
*/
|
||||
public int size() {
|
||||
return _size;
|
||||
}
|
||||
|
||||
|
||||
/** @return the current physical capacity of the hash table. */
|
||||
abstract public int capacity();
|
||||
|
||||
|
||||
/**
|
||||
* Ensure that this hashtable has sufficient capacity to hold
|
||||
* <tt>desiredCapacity<tt> <b>additional</b> elements without
|
||||
* requiring a rehash. This is a tuning method you can call
|
||||
* before doing a large insert.
|
||||
*
|
||||
* @param desiredCapacity an <code>int</code> value
|
||||
*/
|
||||
public void ensureCapacity( int desiredCapacity ) {
|
||||
if ( desiredCapacity > ( _maxSize - size() ) ) {
|
||||
rehash( PrimeFinder.nextPrime( Math.max( size() + 1,
|
||||
HashFunctions.fastCeil( ( desiredCapacity + size() ) / _loadFactor ) + 1 ) ) );
|
||||
computeMaxSize( capacity() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compresses the hashtable to the minimum prime size (as defined
|
||||
* by PrimeFinder) that will hold all of the elements currently in
|
||||
* the table. If you have done a lot of <tt>remove</tt>
|
||||
* operations and plan to do a lot of queries or insertions or
|
||||
* iteration, it is a good idea to invoke this method. Doing so
|
||||
* will accomplish two things:
|
||||
* <p/>
|
||||
* <ol>
|
||||
* <li> You'll free memory allocated to the table but no
|
||||
* longer needed because of the remove()s.</li>
|
||||
* <p/>
|
||||
* <li> You'll get better query/insert/iterator performance
|
||||
* because there won't be any <tt>REMOVED</tt> slots to skip
|
||||
* over when probing for indices in the table.</li>
|
||||
* </ol>
|
||||
*/
|
||||
public void compact() {
|
||||
// need at least one free spot for open addressing
|
||||
rehash( PrimeFinder.nextPrime( Math.max( _size + 1,
|
||||
HashFunctions.fastCeil( size() / _loadFactor ) + 1 ) ) );
|
||||
computeMaxSize( capacity() );
|
||||
|
||||
// If auto-compaction is enabled, re-determine the compaction interval
|
||||
if ( _autoCompactionFactor != 0 ) {
|
||||
computeNextAutoCompactionAmount( size() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The auto-compaction factor controls whether and when a table performs a
|
||||
* {@link #compact} automatically after a certain number of remove operations.
|
||||
* If the value is non-zero, the number of removes that need to occur for
|
||||
* auto-compaction is the size of table at the time of the previous compaction
|
||||
* (or the initial capacity) multiplied by this factor.
|
||||
* <p/>
|
||||
* Setting this value to zero will disable auto-compaction.
|
||||
*
|
||||
* @param factor a <tt>float</tt> that indicates the auto-compaction factor
|
||||
*/
|
||||
public void setAutoCompactionFactor( float factor ) {
|
||||
if ( factor < 0 ) {
|
||||
throw new IllegalArgumentException( "Factor must be >= 0: " + factor );
|
||||
}
|
||||
|
||||
_autoCompactionFactor = factor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see #setAutoCompactionFactor
|
||||
*
|
||||
* @return a <<tt>float</tt> that represents the auto-compaction factor.
|
||||
*/
|
||||
public float getAutoCompactionFactor() {
|
||||
return _autoCompactionFactor;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This simply calls {@link #compact compact}. It is included for
|
||||
* symmetry with other collection classes. Note that the name of this
|
||||
* method is somewhat misleading (which is why we prefer
|
||||
* <tt>compact</tt>) as the load factor may require capacity above
|
||||
* and beyond the size of this collection.
|
||||
*
|
||||
* @see #compact
|
||||
*/
|
||||
public final void trimToSize() {
|
||||
compact();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete the record at <tt>index</tt>. Reduces the size of the
|
||||
* collection by one.
|
||||
*
|
||||
* @param index an <code>int</code> value
|
||||
*/
|
||||
protected void removeAt( int index ) {
|
||||
_size--;
|
||||
|
||||
// If auto-compaction is enabled, see if we need to compact
|
||||
if ( _autoCompactionFactor != 0 ) {
|
||||
_autoCompactRemovesRemaining--;
|
||||
|
||||
if ( !_autoCompactTemporaryDisable && _autoCompactRemovesRemaining <= 0 ) {
|
||||
// Do the compact
|
||||
// NOTE: this will cause the next compaction interval to be calculated
|
||||
compact();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** Empties the collection. */
|
||||
public void clear() {
|
||||
_size = 0;
|
||||
_free = capacity();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initializes the hashtable to a prime capacity which is at least
|
||||
* <tt>initialCapacity + 1</tt>.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
* @return the actual capacity chosen
|
||||
*/
|
||||
protected int setUp( int initialCapacity ) {
|
||||
int capacity;
|
||||
|
||||
capacity = PrimeFinder.nextPrime( initialCapacity );
|
||||
computeMaxSize( capacity );
|
||||
computeNextAutoCompactionAmount( initialCapacity );
|
||||
|
||||
return capacity;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Rehashes the set.
|
||||
*
|
||||
* @param newCapacity an <code>int</code> value
|
||||
*/
|
||||
protected abstract void rehash( int newCapacity );
|
||||
|
||||
|
||||
/**
|
||||
* Temporarily disables auto-compaction. MUST be followed by calling
|
||||
* {@link #reenableAutoCompaction}.
|
||||
*/
|
||||
public void tempDisableAutoCompaction() {
|
||||
_autoCompactTemporaryDisable = true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Re-enable auto-compaction after it was disabled via
|
||||
* {@link #tempDisableAutoCompaction()}.
|
||||
*
|
||||
* @param check_for_compaction True if compaction should be performed if needed
|
||||
* before returning. If false, no compaction will be
|
||||
* performed.
|
||||
*/
|
||||
public void reenableAutoCompaction( boolean check_for_compaction ) {
|
||||
_autoCompactTemporaryDisable = false;
|
||||
|
||||
if ( check_for_compaction && _autoCompactRemovesRemaining <= 0 &&
|
||||
_autoCompactionFactor != 0 ) {
|
||||
|
||||
// Do the compact
|
||||
// NOTE: this will cause the next compaction interval to be calculated
|
||||
compact();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the values of maxSize. There will always be at least
|
||||
* one free slot required.
|
||||
*
|
||||
* @param capacity an <code>int</code> value
|
||||
*/
|
||||
protected void computeMaxSize( int capacity ) {
|
||||
// need at least one free slot for open addressing
|
||||
_maxSize = Math.min( capacity - 1, (int) ( capacity * _loadFactor ) );
|
||||
_free = capacity - _size; // reset the free element count
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the number of removes that need to happen before the next auto-compaction
|
||||
* will occur.
|
||||
*
|
||||
* @param size an <tt>int</tt> that sets the auto-compaction limit.
|
||||
*/
|
||||
protected void computeNextAutoCompactionAmount( int size ) {
|
||||
if ( _autoCompactionFactor != 0 ) {
|
||||
// NOTE: doing the round ourselves has been found to be faster than using
|
||||
// Math.round.
|
||||
_autoCompactRemovesRemaining =
|
||||
(int) ( ( size * _autoCompactionFactor ) + 0.5f );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* After an insert, this hook is called to adjust the size/free
|
||||
* values of the set and to perform rehashing if necessary.
|
||||
*
|
||||
* @param usedFreeSlot the slot
|
||||
*/
|
||||
protected final void postInsertHook( boolean usedFreeSlot ) {
|
||||
if ( usedFreeSlot ) {
|
||||
_free--;
|
||||
}
|
||||
|
||||
// rehash whenever we exhaust the available space in the table
|
||||
if ( ++_size > _maxSize || _free == 0 ) {
|
||||
// choose a new capacity suited to the new state of the table
|
||||
// if we've grown beyond our maximum size, double capacity;
|
||||
// if we've exhausted the free spots, rehash to the same capacity,
|
||||
// which will free up any stale removed slots for reuse.
|
||||
int newCapacity = _size > _maxSize ? PrimeFinder.nextPrime( capacity() << 1 ) : capacity();
|
||||
rehash( newCapacity );
|
||||
computeMaxSize( capacity() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected int calculateGrownCapacity() {
|
||||
return capacity() << 1;
|
||||
}
|
||||
|
||||
|
||||
public void writeExternal( ObjectOutput out ) throws IOException {
|
||||
// VERSION
|
||||
out.writeByte( 0 );
|
||||
|
||||
// LOAD FACTOR
|
||||
out.writeFloat( _loadFactor );
|
||||
|
||||
// AUTO COMPACTION LOAD FACTOR
|
||||
out.writeFloat( _autoCompactionFactor );
|
||||
}
|
||||
|
||||
|
||||
public void readExternal( ObjectInput in )
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
// VERSION
|
||||
in.readByte();
|
||||
|
||||
// LOAD FACTOR
|
||||
float old_factor = _loadFactor;
|
||||
_loadFactor = in.readFloat();
|
||||
|
||||
// AUTO COMPACTION LOAD FACTOR
|
||||
_autoCompactionFactor = in.readFloat();
|
||||
|
||||
// If we change the laod factor from the default, re-setup
|
||||
if ( old_factor != _loadFactor ) {
|
||||
setUp( (int) Math.ceil( DEFAULT_CAPACITY / _loadFactor ) );
|
||||
}
|
||||
}
|
||||
}// THash
|
|
@ -0,0 +1,143 @@
|
|||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.impl.hash;
|
||||
|
||||
import gnu.trove.iterator.TPrimitiveIterator;
|
||||
|
||||
import java.util.ConcurrentModificationException;
|
||||
import java.util.NoSuchElementException;
|
||||
|
||||
|
||||
/**
|
||||
* Implements all iterator functions for the hashed object set.
|
||||
* Subclasses may override objectAtIndex to vary the object
|
||||
* returned by calls to next() (e.g. for values, and Map.Entry
|
||||
* objects).
|
||||
* <p/>
|
||||
* <p> Note that iteration is fastest if you forego the calls to
|
||||
* <tt>hasNext</tt> in favor of checking the size of the structure
|
||||
* yourself and then call next() that many times:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Iterator i = collection.iterator();
|
||||
* for (int size = collection.size(); size-- > 0;) {
|
||||
* Object o = i.next();
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>You may, of course, use the hasNext(), next() idiom too if
|
||||
* you aren't in a performance critical spot.</p>
|
||||
*/
|
||||
public abstract class THashPrimitiveIterator implements TPrimitiveIterator {
|
||||
|
||||
/** the data structure this iterator traverses */
|
||||
protected final TPrimitiveHash _hash;
|
||||
/**
|
||||
* the number of elements this iterator believes are in the
|
||||
* data structure it accesses.
|
||||
*/
|
||||
protected int _expectedSize;
|
||||
/** the index used for iteration. */
|
||||
protected int _index;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a <tt>TPrimitiveIterator</tt> for the specified collection.
|
||||
*
|
||||
* @param hash the <tt>TPrimitiveHash</tt> we want to iterate over.
|
||||
*/
|
||||
public THashPrimitiveIterator( TPrimitiveHash hash ) {
|
||||
_hash = hash;
|
||||
_expectedSize = _hash.size();
|
||||
_index = _hash.capacity();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the index of the next value in the data structure
|
||||
* or a negative value if the iterator is exhausted.
|
||||
*
|
||||
* @return an <code>int</code> value
|
||||
* @throws java.util.ConcurrentModificationException
|
||||
* if the underlying collection's
|
||||
* size has been modified since the iterator was created.
|
||||
*/
|
||||
protected final int nextIndex() {
|
||||
if ( _expectedSize != _hash.size() ) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
byte[] states = _hash._states;
|
||||
int i = _index;
|
||||
while ( i-- > 0 && ( states[i] != TPrimitiveHash.FULL ) ) {
|
||||
;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the iterator can be advanced past its current
|
||||
* location.
|
||||
*
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean hasNext() {
|
||||
return nextIndex() >= 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes the last entry returned by the iterator.
|
||||
* Invoking this method more than once for a single entry
|
||||
* will leave the underlying data structure in a confused
|
||||
* state.
|
||||
*/
|
||||
public void remove() {
|
||||
if (_expectedSize != _hash.size()) {
|
||||
throw new ConcurrentModificationException();
|
||||
}
|
||||
|
||||
// Disable auto compaction during the remove. This is a workaround for bug 1642768.
|
||||
try {
|
||||
_hash.tempDisableAutoCompaction();
|
||||
_hash.removeAt(_index);
|
||||
}
|
||||
finally {
|
||||
_hash.reenableAutoCompaction( false );
|
||||
}
|
||||
|
||||
_expectedSize--;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the internal <tt>index</tt> so that the `next' object
|
||||
* can be returned.
|
||||
*/
|
||||
protected final void moveToNextIndex() {
|
||||
// doing the assignment && < 0 in one line shaves
|
||||
// 3 opcodes...
|
||||
if ( ( _index = nextIndex() ) < 0 ) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // TPrimitiveIterator
|
|
@ -0,0 +1,136 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.impl.hash;
|
||||
|
||||
import gnu.trove.impl.HashFunctions;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The base class for hashtables of primitive values. Since there is
|
||||
* no notion of object equality for primitives, it isn't possible to
|
||||
* use a `REMOVED' object to track deletions in an open-addressed table.
|
||||
* So, we have to resort to using a parallel `bookkeeping' array of bytes,
|
||||
* in which flags can be set to indicate that a particular slot in the
|
||||
* hash table is FREE, FULL, or REMOVED.
|
||||
*
|
||||
* @author Eric D. Friedman, Rob Eden, Jeff Randall
|
||||
* @version $Id: TPrimitiveHash.java,v 1.1.2.6 2010/03/01 23:39:07 robeden Exp $
|
||||
*/
|
||||
abstract public class TPrimitiveHash extends THash {
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* flags indicating whether each position in the hash is
|
||||
* FREE, FULL, or REMOVED
|
||||
*/
|
||||
public transient byte[] _states;
|
||||
|
||||
/* constants used for state flags */
|
||||
|
||||
/** flag indicating that a slot in the hashtable is available */
|
||||
public static final byte FREE = 0;
|
||||
|
||||
/** flag indicating that a slot in the hashtable is occupied */
|
||||
public static final byte FULL = 1;
|
||||
|
||||
/**
|
||||
* flag indicating that the value of a slot in the hashtable
|
||||
* was deleted
|
||||
*/
|
||||
public static final byte REMOVED = 2;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>THash</code> instance with the default
|
||||
* capacity and load factor.
|
||||
*/
|
||||
public TPrimitiveHash() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TPrimitiveHash</code> instance with a prime
|
||||
* capacity at or near the specified capacity and with the default
|
||||
* load factor.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
*/
|
||||
public TPrimitiveHash( int initialCapacity ) {
|
||||
this( initialCapacity, DEFAULT_LOAD_FACTOR );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TPrimitiveHash</code> instance with a prime
|
||||
* capacity at or near the minimum needed to hold
|
||||
* <tt>initialCapacity<tt> elements with load factor
|
||||
* <tt>loadFactor</tt> without triggering a rehash.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
* @param loadFactor a <code>float</code> value
|
||||
*/
|
||||
public TPrimitiveHash( int initialCapacity, float loadFactor ) {
|
||||
super();
|
||||
initialCapacity = Math.max( 1, initialCapacity );
|
||||
_loadFactor = loadFactor;
|
||||
setUp( HashFunctions.fastCeil( initialCapacity / loadFactor ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the capacity of the hash table. This is the true
|
||||
* physical capacity, without adjusting for the load factor.
|
||||
*
|
||||
* @return the physical capacity of the hash table.
|
||||
*/
|
||||
public int capacity() {
|
||||
return _states.length;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Delete the record at <tt>index</tt>.
|
||||
*
|
||||
* @param index an <code>int</code> value
|
||||
*/
|
||||
protected void removeAt( int index ) {
|
||||
_states[index] = REMOVED;
|
||||
super.removeAt( index );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* initializes the hashtable to a prime capacity which is at least
|
||||
* <tt>initialCapacity + 1</tt>.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
* @return the actual capacity chosen
|
||||
*/
|
||||
protected int setUp( int initialCapacity ) {
|
||||
int capacity;
|
||||
|
||||
capacity = super.setUp( initialCapacity );
|
||||
_states = new byte[capacity];
|
||||
return capacity;
|
||||
}
|
||||
} // TPrimitiveHash
|
|
@ -0,0 +1,38 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.iterator;
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Iterator for byte collections.
|
||||
*/
|
||||
public interface TByteIterator extends TIterator {
|
||||
/**
|
||||
* Advances the iterator to the next element in the underlying collection
|
||||
* and returns it.
|
||||
*
|
||||
* @return the next byte in the collection
|
||||
* @exception NoSuchElementException if the iterator is already exhausted
|
||||
*/
|
||||
public byte next();
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
package gnu.trove.iterator;
|
||||
|
||||
/**
|
||||
* Common interface for all iterators used in Trove.
|
||||
*/
|
||||
public interface TIterator {
|
||||
/**
|
||||
* Returns true if the iterator can be advanced past its current location.
|
||||
*
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean hasNext();
|
||||
|
||||
/**
|
||||
* Removes the last entry returned by the iterator. The result of invoking this method
|
||||
* more than once for a single entry is undefined and can leave the underlying data
|
||||
* structure in a confused state.
|
||||
*/
|
||||
public void remove();
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.iterator;
|
||||
|
||||
/**
|
||||
* Implements all iterator functions for the hashed object set.
|
||||
* Subclasses may override objectAtIndex to vary the object
|
||||
* returned by calls to next() (e.g. for values, and Map.Entry
|
||||
* objects).
|
||||
* <p/>
|
||||
* <p> Note that iteration is fastest if you forego the calls to
|
||||
* <tt>hasNext</tt> in favor of checking the size of the structure
|
||||
* yourself and then call next() that many times:
|
||||
* <p/>
|
||||
* <pre>
|
||||
* Iterator i = collection.iterator();
|
||||
* for (int size = collection.size(); size-- > 0;) {
|
||||
* Object o = i.next();
|
||||
* }
|
||||
* </pre>
|
||||
* <p/>
|
||||
* <p>You may, of course, use the hasNext(), next() idiom too if
|
||||
* you aren't in a performance critical spot.</p>
|
||||
*/
|
||||
public interface TPrimitiveIterator extends TIterator {
|
||||
/**
|
||||
* Returns true if the iterator can be advanced past its current
|
||||
* location.
|
||||
*
|
||||
* @return a <code>boolean</code> value
|
||||
*/
|
||||
public boolean hasNext();
|
||||
|
||||
|
||||
/**
|
||||
* Removes the last entry returned by the iterator.
|
||||
* Invoking this method more than once for a single entry
|
||||
* will leave the underlying data structure in a confused
|
||||
* state.
|
||||
*/
|
||||
public void remove();
|
||||
|
||||
} // TPrimitiveIterator
|
|
@ -0,0 +1,41 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.procedure;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* Interface for procedures with one byte parameter.
|
||||
*/
|
||||
public interface TByteProcedure {
|
||||
/**
|
||||
* Executes this procedure. A false return value indicates that
|
||||
* the application executing this procedure should not invoke this
|
||||
* procedure again.
|
||||
*
|
||||
* @param value a value of type <code>byte</code>
|
||||
* @return true if additional invocations of the procedure are
|
||||
* allowed.
|
||||
*/
|
||||
public boolean execute( byte value );
|
||||
}
|
|
@ -0,0 +1,319 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.set;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
import gnu.trove.iterator.TByteIterator;
|
||||
import gnu.trove.procedure.TByteProcedure;
|
||||
import gnu.trove.TByteCollection;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* An implementation of the <tt>Set</tt> interface that uses an
|
||||
* open-addressed hash table to store its contents.
|
||||
*
|
||||
* Created: Sat Nov 3 10:38:17 2001
|
||||
*
|
||||
* @author Eric D. Friedman, Rob Eden, Jeff Randall
|
||||
* @version $Id: _E_Set.template,v 1.1.2.5 2009/09/15 02:38:31 upholderoftruth Exp $
|
||||
*/
|
||||
|
||||
public interface TByteSet extends TByteCollection {
|
||||
|
||||
|
||||
/**
|
||||
* Returns the value that is used to represent null. The default
|
||||
* value is generally zero, but can be changed during construction
|
||||
* of the collection.
|
||||
*
|
||||
* @return the value that represents null
|
||||
*/
|
||||
byte getNoEntryValue();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of elements in this set (its cardinality). If this
|
||||
* set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
|
||||
* <tt>Integer.MAX_VALUE</tt>.
|
||||
*
|
||||
* @return the number of elements in this set (its cardinality)
|
||||
*/
|
||||
int size();
|
||||
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains no elements.
|
||||
*
|
||||
* @return <tt>true</tt> if this set contains no elements
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
|
||||
/**
|
||||
* Returns <tt>true</tt> if this set contains the specified element.
|
||||
*
|
||||
* @param entry an <code>byte</code> value
|
||||
* @return true if the set contains the specified element.
|
||||
*/
|
||||
boolean contains( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Creates an iterator over the values of the set. The iterator
|
||||
* supports element deletion.
|
||||
*
|
||||
* @return an <code>TByteIterator</code> value
|
||||
*/
|
||||
TByteIterator iterator();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array containing all of the elements in this set.
|
||||
* If this set makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the
|
||||
* elements in the same order.
|
||||
*
|
||||
* <p>The returned array will be "safe" in that no references to it
|
||||
* are maintained by this set. (In other words, this method must
|
||||
* allocate a new array even if this set is backed by an array).
|
||||
* The caller is thus free to modify the returned array.
|
||||
*
|
||||
* <p>This method acts as bridge between array-based and collection-based
|
||||
* APIs.
|
||||
*
|
||||
* @return an array containing all the elements in this set
|
||||
*/
|
||||
byte[] toArray();
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array containing elements in this set.
|
||||
*
|
||||
* <p>If this set fits in the specified array with room to spare
|
||||
* (i.e., the array has more elements than this set), the element in
|
||||
* the array immediately following the end of the set is set to
|
||||
* <tt>{@link #getNoEntryValue()}</tt>. (This is useful in determining
|
||||
* the length of this set <i>only</i> if the caller knows that this
|
||||
* set does not contain any elements representing null.)
|
||||
*
|
||||
* <p>If the native array is smaller than the set size,
|
||||
* the array will be filled with elements in Iterator order
|
||||
* until it is full and exclude the remainder.
|
||||
*
|
||||
* <p>If this set makes any guarantees as to what order its elements
|
||||
* are returned by its iterator, this method must return the elements
|
||||
* in the same order.
|
||||
*
|
||||
* @param dest the array into which the elements of this set are to be
|
||||
* stored.
|
||||
* @return an <tt>byte[]</tt> containing all the elements in this set
|
||||
* @throws NullPointerException if the specified array is null
|
||||
*/
|
||||
byte[] toArray( byte[] dest );
|
||||
|
||||
|
||||
/**
|
||||
* Inserts a value into the set.
|
||||
*
|
||||
* @param entry a <code>byte</code> value
|
||||
* @return true if the set was modified by the add operation
|
||||
*/
|
||||
boolean add( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Removes <tt>entry</tt> from the set.
|
||||
*
|
||||
* @param entry an <code>byte</code> value
|
||||
* @return true if the set was modified by the remove operation.
|
||||
*/
|
||||
boolean remove( byte entry );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the set to determine if all of the elements in
|
||||
* <tt>collection</tt> are present.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if all elements were present in the set.
|
||||
*/
|
||||
boolean containsAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the set to determine if all of the elements in
|
||||
* <tt>TByteCollection</tt> are present.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if all elements were present in the set.
|
||||
*/
|
||||
boolean containsAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Tests the set to determine if all of the elements in
|
||||
* <tt>array</tt> are present.
|
||||
*
|
||||
* @param array as <code>array</code> of byte primitives.
|
||||
* @return true if all elements were present in the set.
|
||||
*/
|
||||
boolean containsAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in <tt>collection</tt> to the set.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the set was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( Collection<? extends Byte> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the <tt>TByteCollection</tt> to the set.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the set was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Adds all of the elements in the <tt>array</tt> to the set.
|
||||
*
|
||||
* @param array a <code>array</code> of byte primitives.
|
||||
* @return true if the set was modified by the add all operation.
|
||||
*/
|
||||
boolean addAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the set which are not contained in
|
||||
* <tt>collection</tt>.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the set was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the set which are not contained in
|
||||
* <tt>TByteCollection</tt>.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the set was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes any values in the set which are not contained in
|
||||
* <tt>array</tt>.
|
||||
*
|
||||
* @param array an <code>array</code> of byte primitives.
|
||||
* @return true if the set was modified by the retain all operation
|
||||
*/
|
||||
boolean retainAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>collection</tt> from the set.
|
||||
*
|
||||
* @param collection a <code>Collection</code> value
|
||||
* @return true if the set was modified by the remove all operation.
|
||||
*/
|
||||
boolean removeAll( Collection<?> collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>TByteCollection</tt> from the set.
|
||||
*
|
||||
* @param collection a <code>TByteCollection</code> value
|
||||
* @return true if the set was modified by the remove all operation.
|
||||
*/
|
||||
boolean removeAll( TByteCollection collection );
|
||||
|
||||
|
||||
/**
|
||||
* Removes all of the elements in <tt>array</tt> from the set.
|
||||
*
|
||||
* @param array an <code>array</code> of byte primitives.
|
||||
* @return true if the set was modified by the remove all operation.
|
||||
*/
|
||||
public boolean removeAll( byte[] array );
|
||||
|
||||
|
||||
/**
|
||||
* Empties the set.
|
||||
*/
|
||||
void clear();
|
||||
|
||||
|
||||
/**
|
||||
* Executes <tt>procedure</tt> for each element in the set.
|
||||
*
|
||||
* @param procedure a <code>TByteProcedure</code> value
|
||||
* @return false if the loop over the set terminated because
|
||||
* the procedure returned false for some value.
|
||||
*/
|
||||
boolean forEach( TByteProcedure procedure );
|
||||
|
||||
|
||||
// Comparison and hashing
|
||||
|
||||
/**
|
||||
* Compares the specified object with this set for equality. Returns
|
||||
* <tt>true</tt> if the specified object is also a set, the two sets
|
||||
* have the same size, and every member of the specified set is
|
||||
* contained in this set (or equivalently, every member of this set is
|
||||
* contained in the specified set). This definition ensures that the
|
||||
* equals method works properly across different implementations of the
|
||||
* set interface.
|
||||
*
|
||||
* @param o object to be compared for equality with this set
|
||||
* @return <tt>true</tt> if the specified object is equal to this set
|
||||
*/
|
||||
boolean equals( Object o );
|
||||
|
||||
|
||||
/**
|
||||
* Returns the hash code value for this set. The hash code of a set is
|
||||
* defined to be the sum of the hash codes of the elements in the set.
|
||||
* This ensures that <tt>s1.equals(s2)</tt> implies that
|
||||
* <tt>s1.hashCode()==s2.hashCode()</tt> for any two sets <tt>s1</tt>
|
||||
* and <tt>s2</tt>, as required by the general contract of
|
||||
* {@link Object#hashCode}.
|
||||
*
|
||||
* @return the hash code value for this set
|
||||
* @see Object#equals(Object)
|
||||
* @see Set#equals(Object)
|
||||
*/
|
||||
int hashCode();
|
||||
|
||||
|
||||
} // THashSet
|
|
@ -0,0 +1,545 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (c) 2001, Eric D. Friedman All Rights Reserved.
|
||||
// Copyright (c) 2009, Rob Eden All Rights Reserved.
|
||||
// Copyright (c) 2009, Jeff Randall All Rights Reserved.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this program; if not, write to the Free Software
|
||||
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
package gnu.trove.set.hash;
|
||||
|
||||
import gnu.trove.set.TByteSet;
|
||||
import gnu.trove.iterator.TByteIterator;
|
||||
import gnu.trove.impl.*;
|
||||
import gnu.trove.impl.hash.*;
|
||||
import gnu.trove.TByteCollection;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.Externalizable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
// THIS IS A GENERATED CLASS. DO NOT HAND EDIT! //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
* An open addressed set implementation for byte primitives.
|
||||
*
|
||||
* @author Eric D. Friedman
|
||||
* @author Rob Eden
|
||||
* @author Jeff Randall
|
||||
*/
|
||||
|
||||
public class TByteHashSet extends TByteHash implements TByteSet, Externalizable {
|
||||
static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance with the default
|
||||
* capacity and load factor.
|
||||
*/
|
||||
public TByteHashSet() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance with a prime
|
||||
* capacity equal to or greater than <tt>initialCapacity</tt> and
|
||||
* with the default load factor.
|
||||
*
|
||||
* @param initialCapacity an <code>int</code> value
|
||||
*/
|
||||
public TByteHashSet( int initialCapacity ) {
|
||||
super( initialCapacity );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TIntHash</code> instance with a prime
|
||||
* value at or near the specified capacity and load factor.
|
||||
*
|
||||
* @param initialCapacity used to find a prime capacity for the table.
|
||||
* @param load_factor used to calculate the threshold over which
|
||||
* rehashing takes place.
|
||||
*/
|
||||
public TByteHashSet( int initialCapacity, float load_factor ) {
|
||||
super( initialCapacity, load_factor );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance with a prime
|
||||
* capacity equal to or greater than <tt>initial_capacity</tt> and
|
||||
* with the specified load factor.
|
||||
*
|
||||
* @param initial_capacity an <code>int</code> value
|
||||
* @param load_factor a <code>float</code> value
|
||||
* @param no_entry_value a <code>byte</code> value that represents null.
|
||||
*/
|
||||
public TByteHashSet( int initial_capacity, float load_factor,
|
||||
byte no_entry_value ) {
|
||||
super( initial_capacity, load_factor, no_entry_value );
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance that is a copy
|
||||
* of the existing Collection.
|
||||
*
|
||||
* @param collection a <tt>Collection</tt> that will be duplicated.
|
||||
*/
|
||||
public TByteHashSet( Collection<? extends Byte> collection ) {
|
||||
this( Math.max( collection.size(), DEFAULT_CAPACITY ) );
|
||||
addAll( collection );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance that is a copy
|
||||
* of the existing set.
|
||||
*
|
||||
* @param collection a <tt>TByteSet</tt> that will be duplicated.
|
||||
*/
|
||||
public TByteHashSet( TByteCollection collection ) {
|
||||
this( Math.max( collection.size(), DEFAULT_CAPACITY ) );
|
||||
if ( collection instanceof TByteHashSet ) {
|
||||
TByteHashSet hashset = ( TByteHashSet ) collection;
|
||||
this._loadFactor = hashset._loadFactor;
|
||||
this.no_entry_value = hashset.no_entry_value;
|
||||
//noinspection RedundantCast
|
||||
if ( this.no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, this.no_entry_value );
|
||||
}
|
||||
setUp( (int) Math.ceil( DEFAULT_CAPACITY / _loadFactor ) );
|
||||
}
|
||||
addAll( collection );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new <code>TByteHashSet</code> instance containing the
|
||||
* elements of <tt>array</tt>.
|
||||
*
|
||||
* @param array an array of <code>byte</code> primitives
|
||||
*/
|
||||
public TByteHashSet( byte[] array ) {
|
||||
this( Math.max( array.length, DEFAULT_CAPACITY ) );
|
||||
addAll( array );
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public TByteIterator iterator() {
|
||||
return new TByteHashIterator( this );
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public byte[] toArray() {
|
||||
byte[] result = new byte[ size() ];
|
||||
byte[] set = _set;
|
||||
byte[] states = _states;
|
||||
|
||||
for ( int i = states.length, j = 0; i-- > 0; ) {
|
||||
if ( states[i] == FULL ) {
|
||||
result[j++] = set[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public byte[] toArray( byte[] dest ) {
|
||||
byte[] set = _set;
|
||||
byte[] states = _states;
|
||||
|
||||
for ( int i = states.length, j = 0; i-- > 0; ) {
|
||||
if ( states[i] == FULL ) {
|
||||
dest[j++] = set[i];
|
||||
}
|
||||
}
|
||||
|
||||
if ( dest.length > _size ) {
|
||||
dest[_size] = no_entry_value;
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean add( byte val ) {
|
||||
int index = insertKey(val);
|
||||
|
||||
if ( index < 0 ) {
|
||||
return false; // already present in set, nothing to add
|
||||
}
|
||||
|
||||
postInsertHook( consumeFreeSlot );
|
||||
|
||||
return true; // yes, we added something
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean remove( byte val ) {
|
||||
int index = index(val);
|
||||
if ( index >= 0 ) {
|
||||
removeAt( index );
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean containsAll( Collection<?> collection ) {
|
||||
for ( Object element : collection ) {
|
||||
if ( element instanceof Byte ) {
|
||||
byte c = ( ( Byte ) element ).byteValue();
|
||||
if ( ! contains( c ) ) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean containsAll( TByteCollection collection ) {
|
||||
TByteIterator iter = collection.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
byte element = iter.next();
|
||||
if ( ! contains( element ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean containsAll( byte[] array ) {
|
||||
for ( int i = array.length; i-- > 0; ) {
|
||||
if ( ! contains( array[i] ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean addAll( Collection<? extends Byte> collection ) {
|
||||
boolean changed = false;
|
||||
for ( Byte element : collection ) {
|
||||
byte e = element.byteValue();
|
||||
if ( add( e ) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean addAll( TByteCollection collection ) {
|
||||
boolean changed = false;
|
||||
TByteIterator iter = collection.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
byte element = iter.next();
|
||||
if ( add( element ) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean addAll( byte[] array ) {
|
||||
boolean changed = false;
|
||||
for ( int i = array.length; i-- > 0; ) {
|
||||
if ( add( array[i] ) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean retainAll( Collection<?> collection ) {
|
||||
boolean modified = false;
|
||||
TByteIterator iter = iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
if ( ! collection.contains( Byte.valueOf ( iter.next() ) ) ) {
|
||||
iter.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean retainAll( TByteCollection collection ) {
|
||||
if ( this == collection ) {
|
||||
return false;
|
||||
}
|
||||
boolean modified = false;
|
||||
TByteIterator iter = iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
if ( ! collection.contains( iter.next() ) ) {
|
||||
iter.remove();
|
||||
modified = true;
|
||||
}
|
||||
}
|
||||
return modified;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean retainAll( byte[] array ) {
|
||||
boolean changed = false;
|
||||
Arrays.sort( array );
|
||||
byte[] set = _set;
|
||||
byte[] states = _states;
|
||||
|
||||
for ( int i = set.length; i-- > 0; ) {
|
||||
if ( states[i] == FULL && ( Arrays.binarySearch( array, set[i] ) < 0) ) {
|
||||
removeAt( i );
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean removeAll( Collection<?> collection ) {
|
||||
boolean changed = false;
|
||||
for ( Object element : collection ) {
|
||||
if ( element instanceof Byte ) {
|
||||
byte c = ( ( Byte ) element ).byteValue();
|
||||
if ( remove( c ) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean removeAll( TByteCollection collection ) {
|
||||
boolean changed = false;
|
||||
TByteIterator iter = collection.iterator();
|
||||
while ( iter.hasNext() ) {
|
||||
byte element = iter.next();
|
||||
if ( remove( element ) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean removeAll( byte[] array ) {
|
||||
boolean changed = false;
|
||||
for ( int i = array.length; i-- > 0; ) {
|
||||
if ( remove(array[i]) ) {
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void clear() {
|
||||
super.clear();
|
||||
byte[] set = _set;
|
||||
byte[] states = _states;
|
||||
|
||||
for ( int i = set.length; i-- > 0; ) {
|
||||
set[i] = no_entry_value;
|
||||
states[i] = FREE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
protected void rehash( int newCapacity ) {
|
||||
int oldCapacity = _set.length;
|
||||
|
||||
byte oldSet[] = _set;
|
||||
byte oldStates[] = _states;
|
||||
|
||||
_set = new byte[newCapacity];
|
||||
_states = new byte[newCapacity];
|
||||
|
||||
for ( int i = oldCapacity; i-- > 0; ) {
|
||||
if( oldStates[i] == FULL ) {
|
||||
byte o = oldSet[i];
|
||||
insertKey(o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public boolean equals( Object other ) {
|
||||
if ( ! ( other instanceof TByteSet ) ) {
|
||||
return false;
|
||||
}
|
||||
TByteSet that = ( TByteSet ) other;
|
||||
if ( that.size() != this.size() ) {
|
||||
return false;
|
||||
}
|
||||
for ( int i = _states.length; i-- > 0; ) {
|
||||
if ( _states[i] == FULL ) {
|
||||
if ( ! that.contains( _set[i] ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public int hashCode() {
|
||||
int hashcode = 0;
|
||||
for ( int i = _states.length; i-- > 0; ) {
|
||||
if ( _states[i] == FULL ) {
|
||||
hashcode += HashFunctions.hash( _set[i] );
|
||||
}
|
||||
}
|
||||
return hashcode;
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public String toString() {
|
||||
StringBuilder buffy = new StringBuilder( _size * 2 + 2 );
|
||||
buffy.append("{");
|
||||
for ( int i = _states.length, j = 1; i-- > 0; ) {
|
||||
if ( _states[i] == FULL ) {
|
||||
buffy.append( _set[i] );
|
||||
if ( j++ < _size ) {
|
||||
buffy.append( "," );
|
||||
}
|
||||
}
|
||||
}
|
||||
buffy.append("}");
|
||||
return buffy.toString();
|
||||
}
|
||||
|
||||
|
||||
class TByteHashIterator extends THashPrimitiveIterator implements TByteIterator {
|
||||
|
||||
/** the collection on which the iterator operates */
|
||||
private final TByteHash _hash;
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public TByteHashIterator( TByteHash hash ) {
|
||||
super( hash );
|
||||
this._hash = hash;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public byte next() {
|
||||
moveToNextIndex();
|
||||
return _hash._set[_index];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void writeExternal( ObjectOutput out ) throws IOException {
|
||||
|
||||
// VERSION
|
||||
out.writeByte( 1 );
|
||||
|
||||
// SUPER
|
||||
super.writeExternal( out );
|
||||
|
||||
// NUMBER OF ENTRIES
|
||||
out.writeInt( _size );
|
||||
|
||||
// LOAD FACTOR -- Added version 1
|
||||
out.writeFloat( _loadFactor );
|
||||
|
||||
// NO ENTRY VALUE -- Added version 1
|
||||
out.writeByte( no_entry_value );
|
||||
|
||||
// ENTRIES
|
||||
for ( int i = _states.length; i-- > 0; ) {
|
||||
if ( _states[i] == FULL ) {
|
||||
out.writeByte( _set[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public void readExternal( ObjectInput in )
|
||||
throws IOException, ClassNotFoundException {
|
||||
|
||||
// VERSION
|
||||
int version = in.readByte();
|
||||
|
||||
// SUPER
|
||||
super.readExternal( in );
|
||||
|
||||
// NUMBER OF ENTRIES
|
||||
int size = in.readInt();
|
||||
|
||||
if ( version >= 1 ) {
|
||||
// LOAD FACTOR
|
||||
_loadFactor = in.readFloat();
|
||||
|
||||
// NO ENTRY VALUE
|
||||
no_entry_value = in.readByte();
|
||||
//noinspection RedundantCast
|
||||
if ( no_entry_value != ( byte ) 0 ) {
|
||||
Arrays.fill( _set, no_entry_value );
|
||||
}
|
||||
}
|
||||
|
||||
// ENTRIES
|
||||
setUp( size );
|
||||
while ( size-- > 0 ) {
|
||||
byte val = in.readByte();
|
||||
add( val );
|
||||
}
|
||||
}
|
||||
} // TIntHashSet
|
|
@ -0,0 +1,29 @@
|
|||
package lishid.orebfuscator.utils;
|
||||
|
||||
public class BlockCoords {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int index;
|
||||
BlockCoords(int x, int y, int z)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
BlockCoords(int index, int x, int y, int z)
|
||||
{
|
||||
this.index = index;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
public static boolean Equals(BlockCoords a, BlockCoords b)
|
||||
{
|
||||
if(a == null || b == null)
|
||||
return false;
|
||||
return a.x == b.x && a.y == b.y && a.z == b.z;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,6 @@
|
|||
package lishid.orebfuscator;
|
||||
package lishid.orebfuscator.utils;
|
||||
|
||||
import gnu.trove.set.hash.TByteHashSet;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
@ -8,10 +10,10 @@ import org.bukkit.util.config.Configuration;
|
|||
|
||||
public class OrebfuscatorConfig {
|
||||
private static Configuration config;
|
||||
private static byte[] TransparentBlocks = {};
|
||||
private static byte[] ObfuscateBlocks = {};
|
||||
private static byte[] DarknessObfuscateBlocks = {};
|
||||
private static byte[] LightEmissionBlocks = {};
|
||||
private static TByteHashSet TransparentBlocks = new TByteHashSet();
|
||||
private static TByteHashSet ObfuscateBlocks = new TByteHashSet();
|
||||
private static TByteHashSet DarknessObfuscateBlocks = new TByteHashSet();
|
||||
private static TByteHashSet LightEmissionBlocks = new TByteHashSet();
|
||||
private static byte[] RandomBlocks = {};
|
||||
private static final Random randomGenerator = new Random();
|
||||
private static int EngineMode;
|
||||
|
@ -104,10 +106,8 @@ public class OrebfuscatorConfig {
|
|||
if (id == 0) return true;
|
||||
if (id == -127) return false;
|
||||
|
||||
for (byte i : TransparentBlocks) {
|
||||
if (id == i)
|
||||
return true;
|
||||
}
|
||||
if(TransparentBlocks.contains(id))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -115,28 +115,22 @@ public class OrebfuscatorConfig {
|
|||
{
|
||||
if (id == 1) return true;
|
||||
|
||||
for (byte i : ObfuscateBlocks) {
|
||||
if (id == i)
|
||||
return true;
|
||||
}
|
||||
if(ObfuscateBlocks.contains(id))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean isDarknessObfuscated(byte id)
|
||||
{
|
||||
for (byte i : DarknessObfuscateBlocks) {
|
||||
if (id == i)
|
||||
return true;
|
||||
}
|
||||
if(DarknessObfuscateBlocks.contains(id))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean emitsLight(byte id)
|
||||
{
|
||||
for (byte i : LightEmissionBlocks) {
|
||||
if (id == i)
|
||||
return true;
|
||||
}
|
||||
if(LightEmissionBlocks.contains(id))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -262,6 +256,16 @@ public class OrebfuscatorConfig {
|
|||
return byteArray;
|
||||
}
|
||||
|
||||
private static TByteHashSet IntListToTByteHashSet(List<Integer> list)
|
||||
{
|
||||
TByteHashSet bytes = new TByteHashSet();
|
||||
for (int i=0; i < list.size(); i++)
|
||||
{
|
||||
bytes.add((byte)(int)list.get(i));
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static void Load(Configuration config)
|
||||
{
|
||||
OrebfuscatorConfig.config = config;
|
||||
|
@ -288,10 +292,10 @@ public class OrebfuscatorConfig {
|
|||
NoObfuscationForOps = GetBoolean("Booleans.NoObfuscationForOps", true);
|
||||
NoObfuscationForPermission = GetBoolean("Booleans.NoObfuscationForPermission", true);
|
||||
Enabled = GetBoolean("Booleans.Enabled", true);
|
||||
TransparentBlocks = IntListToByteArray(GetIntList("Lists.TransparentBlocks", Arrays.asList(new Integer[]{6,8,9,10,11,18,20,26,27,28,30,31,32,34,37,38,39,40,44,50,51,52,53,54,55,59,63,64,65,66,67,68,69,70,71,72,75,76,77,78,79,81,83,85,90,92,93,94,96,101,102,104,105,106,107,108,109,111,113,114,115})));
|
||||
ObfuscateBlocks = IntListToByteArray(GetIntList("Lists.ObfuscateBlocks", Arrays.asList(new Integer[]{14,15,16,21,54,56,73,74})));
|
||||
DarknessObfuscateBlocks = IntListToByteArray(GetIntList("Lists.DarknessObfuscateBlocks", Arrays.asList(new Integer[]{48,52})));
|
||||
LightEmissionBlocks = IntListToByteArray(GetIntList("Lists.LightEmissionBlocks", Arrays.asList(new Integer[]{10,11,50,51,62,74,76,89,90,91,94})));
|
||||
TransparentBlocks = IntListToTByteHashSet(GetIntList("Lists.TransparentBlocks", Arrays.asList(new Integer[]{6,8,9,10,11,18,20,26,27,28,30,31,32,34,37,38,39,40,44,50,51,52,53,54,55,59,63,64,65,66,67,68,69,70,71,72,75,76,77,78,79,81,83,85,90,92,93,94,96,101,102,104,105,106,107,108,109,111,113,114,115})));
|
||||
ObfuscateBlocks = IntListToTByteHashSet(GetIntList("Lists.ObfuscateBlocks", Arrays.asList(new Integer[]{14,15,16,21,54,56,73,74})));
|
||||
DarknessObfuscateBlocks = IntListToTByteHashSet(GetIntList("Lists.DarknessObfuscateBlocks", Arrays.asList(new Integer[]{48,52})));
|
||||
LightEmissionBlocks = IntListToTByteHashSet(GetIntList("Lists.LightEmissionBlocks", Arrays.asList(new Integer[]{10,11,50,51,62,74,76,89,90,91,94})));
|
||||
RandomBlocks = IntListToByteArray(GetIntList("Lists.RandomBlocks", Arrays.asList(new Integer[]{14,15,16,21,56,73})));
|
||||
config.save();
|
||||
}
|
Loading…
Reference in New Issue