From 3a3efb8117e3e059f942a31d6434062d684eb60d Mon Sep 17 00:00:00 2001 From: MattBDev <4009945+MattBDev@users.noreply.github.com> Date: Thu, 25 Jul 2019 14:58:59 -0400 Subject: [PATCH] Updated a class, minor command tweaks, and formatting --- .../boydti/fawe/command/AnvilCommands.java | 7 +- .../brush/visualization/VisualExtent.java | 8 +- .../brush/visualization/VisualQueue.java | 3 +- .../fawe/object/collection/SparseBitSet.java | 2463 +++++++++-------- .../object/pattern/AbstractExtentPattern.java | 3 +- .../general/plot/FaweLocalBlockQueue.java | 1 - .../general/plot/FaweSchematicHandler.java | 3 +- .../fawe/regions/general/plot/MoveTo512.java | 31 - .../general/plot/PlotRegionFilter.java | 6 +- .../regions/general/plot/PlotSetBiome.java | 2 - .../general/plot/PlotSquaredFeature.java | 2 +- .../com/boydti/fawe/util/TextureUtil.java | 133 +- .../platform/AbstractPlayerActor.java | 61 +- .../world/snapshot/SnapshotRepository.java | 18 +- 14 files changed, 1508 insertions(+), 1233 deletions(-) diff --git a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java index db14faf32..77b304243 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/command/AnvilCommands.java @@ -110,7 +110,7 @@ public class AnvilCommands { @Command( name = "replaceall", aliases = {"rea", "repall"}, - desc = "Replace all blocks in the selection with another", + desc = "Replace all blocks in the selection with another" ) @CommandPermissions("worldedit.anvil.replaceall") public void replaceAll(Player player, String folder, @@ -221,8 +221,7 @@ public class AnvilCommands { aliases = {"deloldreg" }, desc = "Delete regions which haven't been accessed in a certain amount of time", descFooter = "You can use seconds (s), minutes (m), hours (h), days (d), weeks (w), years (y)\n" + - "(months are not a unit of time)\n" + - "E.g. 8h5m12s\n" + "(months are not a unit of time) E.g. 8h5m12s\n" ) @CommandPermissions("worldedit.anvil.deletealloldregions") public void deleteAllOldRegions(Player player, String folder, String time) throws WorldEditException { @@ -300,7 +299,7 @@ public class AnvilCommands { desc = "Replace all blocks in the selection with another" ) @CommandPermissions("worldedit.anvil.replaceall") - public void replaceAllPattern(Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, final Pattern to, @Switch(name = 'd', desc = "TODO") boolean useData, @Switch(name = 'm', desc = "TODO") boolean useMap) throws WorldEditException { + public void replaceAllPattern(Player player, String folder, @Arg(name = "from", desc = "String", def = "") String from, Pattern to, @Switch(name = 'd', desc = "TODO") boolean useData, @Switch(name = 'm', desc = "TODO") boolean useMap) throws WorldEditException { // MCAFilterCounter filter; TODO NOT IMPLEMENTED // if (useMap) { // if (to instanceof RandomPattern) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java index 1a9355db6..4419b2218 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualExtent.java @@ -26,15 +26,15 @@ public class VisualExtent extends AbstractDelegateExtent { this.queue = queue; } + public VisualChunk getChunk(int cx, int cz) { + return chunks.get(MathMan.pairInt(cx, cz)); + } + @Override public boolean setBlock(BlockVector3 location, BlockStateHolder block) throws WorldEditException { return setBlock(location.getBlockX(), location.getBlockY(), location.getBlockZ(), block); } - public VisualChunk getChunk(int cx, int cz) { - return chunks.get(MathMan.pairInt(cx, cz)); - } - @Override public boolean setBlock(int x, int y, int z, BlockStateHolder block) throws WorldEditException { BlockStateHolder previous = super.getBlock(x, y, z); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java index 8d4cec5e2..de569c5b2 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/brush/visualization/VisualQueue.java @@ -16,8 +16,7 @@ public class VisualQueue extends SingleThreadIntervalQueue { @Override public void operate(FawePlayer fp) { - LocalSession session = WorldEdit.getInstance().getSessionManager() - .get(fp.toWorldEditPlayer()); + LocalSession session = WorldEdit.getInstance().getSessionManager().get(fp.toWorldEditPlayer()); Player player = fp.getPlayer(); Tool tool = session.getTool(player); if (tool instanceof BrushTool) { diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java index 91935f821..bd0961857 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/collection/SparseBitSet.java @@ -1,53 +1,58 @@ +// CHECKSTYLE:OFF package com.boydti.fawe.object.collection; +/*- This software is the work of Paladin Software International, Incorporated, + * based upon previous work done for and by Sun Microsystems, Inc. */ + import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /** - * This class implements a set of bits that grows as needed. Each bit of the - * bit set represents a boolean value. The values of a - * SparseBitSet are indexed by nonnegative integers. - * Individual indexed values may be examined, set, cleared, or modified by - * logical operations. One SparseBitSet or logical value may be - * used to modify the contents of (another) SparseBitSet through - * logical AND, logical inclusive OR, logical exclusive - * OR, and And NOT operations over all or part of the bit sets. - *

- * All values in a bit set initially have the value false. - *

- * Every bit set has a current size, which is the number of bits of space - * nominally in use by the bit set from the first set bit to just after - * the last set bit. The length of the bit set effectively tells the position - * available after the last bit of the SparseBitSet. - *

- * The maximum cardinality of a SparseBitSet is - * Integer.MAX_VALUE, which means the bits of a - * SparseBitSet are labelled - * 0 .. Integer.MAX_VALUE − 1. - * After the last set bit of a SparseBitSet, any attempt to find - * a subsequent bit (getNextSetBit()), will return an value of −1. - * If an attempt is made to use getNextClearBit(), and all the bits are - * set from the starting postion of the search to the bit labelled - * Integer.MAX_VALUE − 1, then similarly −1 - * will be returned. - *

- * Unless otherwise noted, passing a null parameter to any of the methods in - * a SparseBitSet will result in a - * NullPointerException. - *

- * A SparseBitSet is not safe for multithreaded use without - * external synchronization. - * @see source - * @author Bruce K. Haddon - * @author Arthur van Hoff - * @author Michael McCloskey - * @author Martin Buchholz - * @version 1.0, 2009-03-17 - * @since 1.6 + * This class implements a set of bits that grows as needed. Each bit of the + * bit set represents a boolean value. The values of a + * SparseBitSet are indexed by non-negative integers. + * Individual indexed values may be examined, set, cleared, or modified by + * logical operations. One SparseBitSet or logical value may be + * used to modify the contents of (another) SparseBitSet through + * logical AND, logical inclusive OR, logical exclusive + * OR, and And NOT operations over all or part of the bit sets. + *

+ * All values in a bit set initially have the value false. + *

+ * Every bit set has a current size, which is the number of bits of space + * nominally in use by the bit set from the first set bit to just after + * the last set bit. The length of the bit set effectively tells the position + * available after the last bit of the SparseBitSet. + *

+ * The maximum cardinality of a SparseBitSet is + * Integer.MAX_VALUE, which means the bits of a + * SparseBitSet are labelled + * 0 .. Integer.MAX_VALUE − 1. + * After the last set bit of a SparseBitSet, any attempt to find + * a subsequent bit (nextSetBit()), will return an value of −1. + * If an attempt is made to use nextClearBit(), and all the bits are + * set from the starting position of the search to the bit labelled + * Integer.MAX_VALUE − 1, then similarly −1 + * will be returned. + *

+ * Unless otherwise noted, passing a null parameter to any of the methods in + * a SparseBitSet will result in a + * NullPointerException. + *

+ * A SparseBitSet is not safe for multi-threaded use without + * external synchronization. + * + * @author Bruce K. Haddon + * @author Arthur van Hoff + * @author Michael McCloskey + * @author Martin Buchholz + * @version 1.0, 2009-03-17 + * @since 1.6 */ -public final class SparseBitSet implements Cloneable, Serializable { +public class SparseBitSet implements Cloneable, Serializable +{ /* My apologies for listing all the additional authors, but concepts, code, and even comments have been re-used in this class definition from code in the JDK that was written and/or maintained by these people. I owe a debt, @@ -94,7 +99,7 @@ public final class SparseBitSet implements Cloneable, Serializable { bits (setting, flipping, clearing, etc.) do not attempt to normalize the set, in the interests of speed. However, when a set is scanned as the resultant set of some operation, then, in most cases, the set will be - normalized--the exception being level2 areas that are not completely scanned + normalized--the exception being level2 areas that are not completly scanned in a particular pass. The sizes of the blocks and areas has been the result of some investigation @@ -105,33 +110,31 @@ public final class SparseBitSet implements Cloneable, Serializable { values appear to be a fair compromise. */ /** - * This value controls for format of the toString() output. - * + * This value controls for format of the toString() output. * @see #toStringCompaction(int) */ protected transient int compactionCount; /** - * The compaction count default. + * The compaction count default. */ static int compactionCountDefault = 2; // Note: this is not final! /** - * The storage for this SparseBitSet. The ith bit is stored in a word - * represented by a long value, and is at bit position i % 64 - * within that word (where bit position 0 refers to the least significant bit - * and 63 refers to the most significant bit). - *

- * The words are organized into blocks, and the blocks are accessed by two - * additional levels of array indexing. + * The storage for this SparseBitSet. The ith bit is stored in a word + * represented by a long value, and is at bit position i % 64 + * within that word (where bit position 0 refers to the least significant bit + * and 63 refers to the most significant bit). + *

+ * The words are organized into blocks, and the blocks are accessed by two + * additional levels of array indexing. */ protected transient long[][][] bits; /** - * For the current size of the bits array, this is the maximum possible - * length of the bit set, i.e., the index of the last possible bit, plus one. - * Note: this not the value returned by length(). - * + * For the current size of the bits array, this is the maximum possible + * length of the bit set, i.e., the index of the last possible bit, plus one. + * Note: this not the value returned by length(). * @see #resize(int) * @see #length() */ @@ -141,96 +144,110 @@ public final class SparseBitSet implements Cloneable, Serializable { // The critical parameters. These are set up so that the compiler may // pre-compute all the values as compile-time constants. //============================================================================== + /** - * The number of bits in a long value. + * The number of bits in a long value. */ protected static final int LENGTH4 = Long.SIZE; /** - * The number of bits in a positive integer, and the size of permitted index - * of a bit in the bit set. + * The number of bits in a positive integer, and the size of permitted index + * of a bit in the bit set. */ protected static final int INDEX_SIZE = Integer.SIZE - 1; /** - * The label (index) of a bit in the bit set is essentially broken into - * 4 "levels". Respectively (from the least significant end), level4, the - * address within word, the address within a level3 block, the address within - * a level2 area, and the level1 address of that area within the set. - *

- * LEVEL4 is the number of bits of the level4 address (number of bits need - * to address the bits in a long) + * The label (index) of a bit in the bit set is essentially broken into + * 4 "levels". Respectively (from the least significant end), level4, the + * address within word, the address within a level3 block, the address within + * a level2 area, and the level1 address of that area within the set. + * + * LEVEL4 is the number of bits of the level4 address (number of bits need + * to address the bits in a long) */ protected static final int LEVEL4 = 6; /** - * LEVEL3 is the number of bits of the level3 address. + * LEVEL3 is the number of bits of the level3 address. */ protected static final int LEVEL3 = 5; // Do not change! /** - * LEVEL2 is the number of bits of the level2 address. + * LEVEL2 is the number of bits of the level2 address. */ protected static final int LEVEL2 = 5; // Do not change! /** - * LEVEL1 is the number of bits of the level1 address. + * LEVEL1 is the number of bits of the level1 address. */ protected static final int LEVEL1 = INDEX_SIZE - LEVEL2 - LEVEL3 - LEVEL4; /** - * MAX_LENGTH1 is the maximum number of entries in the level1 set array. + * MAX_LENGTH1 is the maximum number of entries in the level1 set array. */ protected static final int MAX_LENGTH1 = 1 << LEVEL1; /** - * LENGTH2 is the number of entries in the any level2 area. + * LENGTH2 is the number of entries in the any level2 area. */ protected static final int LENGTH2 = 1 << LEVEL2; /** - * LENGTH3 is the number of entries in the any level3 block. + * LENGTH3 is the number of entries in the any level3 block. */ protected static final int LENGTH3 = 1 << LEVEL3; /** - * The shift to create the word index. (I.e., move it to the right end) + * The shift to create the word index. (I.e., move it to the right end) */ protected static final int SHIFT3 = LEVEL4; /** - * MASK3 is the mask to extract the LEVEL3 address from a word index - * (after shifting by SHIFT3). + * MASK3 is the mask to extract the LEVEL3 address from a word index + * (after shifting by SHIFT3). */ protected static final int MASK3 = LENGTH3 - 1; /** - * SHIFT2 is the shift to bring the level2 address (from the word index) to - * the right end (i.e., after shifting by SHIFT3). + * SHIFT2 is the shift to bring the level2 address (from the word index) to + * the right end (i.e., after shifting by SHIFT3). */ protected static final int SHIFT2 = LEVEL3; /** - * UNIT is the greatest number of bits that can be held in one level1 entry. - * That is, bits per word by words per level3 block by blocks per level2 area. + * UNIT is the greatest number of bits that can be held in one level1 entry. + * That is, bits per word by words per level3 block by blocks per level2 area. */ - protected static final int UNIT = LENGTH2 * LENGTH3 * LENGTH4; /** - * MASK2 is the mask to extract the LEVEL2 address from a word index - * (after shifting by SHIFT3 and SHIFT2). + * MASK2 is the mask to extract the LEVEL2 address from a word index + * (after shifting by SHIFT3 and SHIFT2). */ protected static final int MASK2 = LENGTH2 - 1; /** - * SHIFT1 is the shift to bring the level1 address (from the word index) to - * the right end (i.e., after shifting by SHIFT3). + * SHIFT1 is the shift to bring the level1 address (from the word index) to + * the right end (i.e., after shifting by SHIFT3). */ protected static final int SHIFT1 = LEVEL2 + LEVEL3; /** - * Holds reference to the cache of statistics values computed by the - * UpdateStrategy - * + * LENGTH2_SIZE is maximum index of a LEVEL2 page. + */ + protected static final int LENGTH2_SIZE = LENGTH2 - 1; + + /** + * LENGTH3_SIZE is maximum index of a LEVEL3 page. + */ + protected static final int LENGTH3_SIZE = LENGTH3 - 1; + + /** + * LENGTH4_SIZE is maximum index of a bit in a LEVEL4 word. + */ + protected static final int LENGTH4_SIZE = LENGTH4 - 1; + + /** + * Holds reference to the cache of statistics values computed by the + * UpdateStrategy * @see SparseBitSet.Cache * @see SparseBitSet.UpdateStrategy */ @@ -239,28 +256,22 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================= // Stack structures used for recycling blocks //============================================================================= - // private static final int STACK_SIZE = 1000; - - // private static final long[][] stack = new long[STACK_SIZE][LENGTH3]; - - // private static int stackIndex = 0; /** - * A spare level 3 block is kept for use when scanning. When a target block - * is needed, and there is not already one in the bit set, the spare is - * provided. If non-zero values are placed into this block, it is moved to the - * resulting set, and a new spare is acquired. Note: a new spare needs to - * be allocated when the set is cloned (so that the spare is not shared - * between two sets). + * A spare level 3 block is kept for use when scanning. When a target block + * is needed, and there is not already one in the bit set, the spare is + * provided. If non-zero values are placed into this block, it is moved to the + * resulting set, and a new spare is acquired. Note: a new spare needs to + * be allocated when the set is cloned (so that the spare is not shared + * between two sets). */ protected transient long[] spare; - /** - * An empty level 3 block is kept for use when scanning. When a source block - * is needed, and there is not already one in the corresponding bit set, the - * ZERO_BLOCK is used (as a read-only block). It is a source of zero values - * so that code does not have to test for a null level3 block. This is a - * static block shared everywhere. + /** An empty level 3 block is kept for use when scanning. When a source block + * is needed, and there is not already one in the corresponding bit set, the + * ZERO_BLOCK is used (as a read-only block). It is a source of zero values + * so that code does not have to test for a null level3 block. This is a + * static block shared everywhere. */ static final long[] ZERO_BLOCK = new long[LENGTH3]; @@ -321,28 +332,29 @@ public final class SparseBitSet implements Cloneable, Serializable { gets smart enough to try to do the apparent optimisation! */ /** - * Constructor for a new (sparse) bit set. All bits initially are effectively - * false. This is a internal constructor that collects all the - * needed actions to initialise the bit set. - *

- * The capacity is taken to be a suggestion for a size of the bit set, - * in bits. An appropiate table size (a power of two) is then determined and - * used. The size will be grown as needed to accomodate any bits addressed - * during the use of the bit set. + * Constructor for a new (sparse) bit set. All bits initially are effectively + * false. This is a internal constructor that collects all the + * needed actions to initialise the bit set. + *

+ * The capacity is taken to be a suggestion for a size of the bit set, + * in bits. An appropiate table size (a power of two) is then determined and + * used. The size will be grown as needed to accomodate any bits addressed + * during the use of the bit set. * - * @param capacity a size in terms of bits - * @param compactionCount the compactionCount to be inherited (for - * internal generation) - * @throws NegativeArraySizeException if the specified initial size - * is negative - * @since 1.6 + * @param capacity a size in terms of bits + * @param compactionCount the compactionCount to be inherited (for + * internal generation) + * @exception NegativeArraySizeException if the specified initial size + * is negative + * @since 1.6 */ protected SparseBitSet(int capacity, int compactionCount) - throws NegativeArraySizeException { + throws NegativeArraySizeException + { /* Array size is computed based on this being a capacity given in bits. */ if (capacity < 0) // capacity can't be negative -- could only come from throw new NegativeArraySizeException( // an erroneous user given - "(requested capacity=" + capacity + ") < 0"); // nbits value + "(requested capacity=" + capacity + ") < 0"); // nbits value resize(capacity - 1); // Resize takes last usable index this.compactionCount = compactionCount; /* Ensure there is a spare level 3 block for the use of the set scanner.*/ @@ -351,49 +363,52 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Constructs an empty bit set with the default initial size. - * Initially all bits are effectively false. + * Constructs an empty bit set with the default initial size. + * Initially all bits are effectively false. * - * @since 1.6 + * @since 1.6 */ - public SparseBitSet() { + public SparseBitSet() + { /* By requesting 1 bit, will actually get UNIT number of bits. */ this(1, compactionCountDefault); } /** - * Creates a bit set whose initial size is large enough to efficiently - * represent bits with indices in the range 0 through - * at least nbits-1. Initially all bits are effectively - * false. - *

- * No guarantees are given for how large or small the actual object will be. - * The setting of bits above the given range is permitted (and will perhaps - * eventually cause resizing). + * Creates a bit set whose initial size is large enough to efficiently + * represent bits with indices in the range 0 through + * at least nbits-1. Initially all bits are effectively + * false. + *

+ * No guarantees are given for how large or small the actual object will be. + * The setting of bits above the given range is permitted (and will perhaps + * eventually cause resizing). * - * @param nbits the initial provisional length of the SparseBitSet - * @throws java.lang.NegativeArraySizeException if the specified initial - * length is negative - * @see #SparseBitSet() - * @since 1.6 + * @param nbits the initial provisional length of the SparseBitSet + * @throws java.lang.NegativeArraySizeException if the specified initial + * length is negative + * @see #SparseBitSet() + * @since 1.6 */ - public SparseBitSet(int nbits) throws NegativeArraySizeException { + public SparseBitSet(int nbits) throws NegativeArraySizeException + { this(nbits, compactionCountDefault); } /** - * Performs a logical AND of the addressed target bit with the argument - * value. This bit set is modified so that the addressed bit has the value - * true if and only if it both initially had the value - * true and the argument value is also true. + * Performs a logical AND of the addressed target bit with the argument + * value. This bit set is modified so that the addressed bit has the value + * true if and only if it both initially had the value + * true and the argument value is also true. * - * @param i a bit index - * @param value a boolean value to AND with that bit - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i a bit index + * @param value a boolean value to AND with that bit + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void and(int i, boolean value) throws IndexOutOfBoundsException { + public void and(int i, boolean value) throws IndexOutOfBoundsException + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); if (!value) @@ -401,72 +416,75 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Performs a logical AND of this target bit set with the argument bit - * set within the given range of bits. Within the range, this bit set is - * modified so that each bit in it has the value true if and only - * if it both initially had the value true and the corresponding - * bit in the bit set argument also had the value true. Outside - * the range, this set is not changed. + * Performs a logical AND of this target bit set with the argument bit + * set within the given range of bits. Within the range, this bit set is + * modified so that each bit in it has the value true if and only + * if it both initially had the value true and the corresponding + * bit in the bit set argument also had the value true. Outside + * the range, this set is not changed. * - * @param i index of the first bit to be included in the operation - * @param j index after the last bit to included in the operation - * @param b a SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to be included in the operation + * @param j index after the last bit to included in the operation + * @param b a SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ - - public void and(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException { + public void and(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException + { setScanner(i, j, b, andStrategy); } /** - * Performs a logical AND of this target bit set with the argument bit - * set. This bit set is modified so that each bit in it has the value - * true if and only if it both initially had the value - * true and the corresponding bit in the bit set argument also - * had the value true. + * Performs a logical AND of this target bit set with the argument bit + * set. This bit set is modified so that each bit in it has the value + * true if and only if it both initially had the value + * true and the corresponding bit in the bit set argument also + * had the value true. * - * @param b a SparseBitSet - * @since 1.6 + * @param b a SparseBitSet + * @since 1.6 */ - public void and(SparseBitSet b) { + public void and(SparseBitSet b) + { nullify(Math.min(bits.length, b.bits.length)); // Optimisation setScanner(0, Math.min(bitsLength, b.bitsLength), b, andStrategy); } /** - * Performs a logical AND of the two given SparseBitSets. - * The returned SparseBitSet is created so that each bit in it - * has the value true if and only if both the given sets - * initially had the corresponding bits true, otherwise - * false. + * Performs a logical AND of the two given SparseBitSets. + * The returned SparseBitSet is created so that each bit in it + * has the value true if and only if both the given sets + * initially had the corresponding bits true, otherwise + * false. * - * @param a a SparseBitSet - * @param b another SparseBitSet - * @return a new SparseBitSet representing the AND of the two sets - * @since 1.6 + * @param a a SparseBitSet + * @param b another SparseBitSet + * @return a new SparseBitSet representing the AND of the two sets + * @since 1.6 */ - public static SparseBitSet and(SparseBitSet a, SparseBitSet b) { + public static SparseBitSet and(SparseBitSet a, SparseBitSet b) + { final SparseBitSet result = a.clone(); result.and(b); return result; } /** - * Performs a logical AndNOT of the addressed target bit with the - * argument value. This bit set is modified so that the addressed bit has the - * value true if and only if it both initially had the value - * true and the argument value is false. + * Performs a logical AndNOT of the addressed target bit with the + * argument value. This bit set is modified so that the addressed bit has the + * value true if and only if it both initially had the value + * true and the argument value is false. * - * @param i a bit index - * @param value a boolean value to AndNOT with that bit - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i a bit index + * @param value a boolean value to AndNOT with that bit + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void andNot(int i, boolean value) { + public void andNot(int i, boolean value) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); if (value) @@ -474,85 +492,97 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Performs a logical AndNOT of this target bit set with the argument - * bit set within the given range of bits. Within the range, this bit set is - * modified so that each bit in it has the value true if and only - * if it both initially had the value true and the corresponding - * bit in the bit set argument has the value false. Outside - * the range, this set is not changed. + * Performs a logical AndNOT of this target bit set with the argument + * bit set within the given range of bits. Within the range, this bit set is + * modified so that each bit in it has the value true if and only + * if it both initially had the value true and the corresponding + * bit in the bit set argument has the value false. Outside + * the range, this set is not changed. * - * @param i index of the first bit to be included in the operation - * @param j index after the last bit to included in the operation - * @param b the SparseBitSet with which to mask this SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to be included in the operation + * @param j index after the last bit to included in the operation + * @param b the SparseBitSet with which to mask this SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ public void andNot(int i, int j, SparseBitSet b) - throws IndexOutOfBoundsException { + throws IndexOutOfBoundsException + { setScanner(i, j, b, andNotStrategy); } /** - * Performs a logical AndNOT of this target bit set with the argument - * bit set. This bit set is modified so that each bit in it has the value - * true if and only if it both initially had the value - * true and the corresponding bit in the bit set argument has - * the value false. + * Performs a logical AndNOT of this target bit set with the argument + * bit set. This bit set is modified so that each bit in it has the value + * true if and only if it both initially had the value + * true and the corresponding bit in the bit set argument has + * the value false. * - * @param b the SparseBitSet with which to mask this SparseBitSet - * @since 1.6 + * @param b the SparseBitSet with which to mask this SparseBitSet + * @since 1.6 */ - public void andNot(SparseBitSet b) { + public void andNot(SparseBitSet b) + { setScanner(0, Math.min(bitsLength, b.bitsLength), b, andNotStrategy); } /** - * Creates a bit set from thie first SparseBitSet whose - * corresponding bits are cleared by the set bits of the second - * SparseBitSet. The resulting bit set is created so that a bit - * in it has the value true if and only if the corresponding bit - * in the SparseBitSet of the first is set, and that same - * corresponding bit is not set in the SparseBitSet of the second - * argument. + * Creates a bit set from thie first SparseBitSet whose + * corresponding bits are cleared by the set bits of the second + * SparseBitSet. The resulting bit set is created so that a bit + * in it has the value true if and only if the corresponding bit + * in the SparseBitSet of the first is set, and that same + * corresponding bit is not set in the SparseBitSet of the second + * argument. * - * @param a a SparseBitSet - * @param b another SparseBitSet - * @return a new SparseBitSet representing the AndNOT of the - * two sets - * @since 1.6 + * @param a a SparseBitSet + * @param b another SparseBitSet + * @return a new SparseBitSet representing the AndNOT of the + * two sets + * @since 1.6 */ - public static SparseBitSet andNot(SparseBitSet a, SparseBitSet b) { + public static SparseBitSet andNot(SparseBitSet a, SparseBitSet b) + { final SparseBitSet result = a.clone(); result.andNot(b); return result; } /** - * Returns the number of bits set to true in this - * SparseBitSet. + * Returns the number of bits set to true in this + * SparseBitSet. * - * @return the number of bits set to true in this SparseBitSet - * @since 1.6 + * @return the number of bits set to true in this SparseBitSet + * @since 1.6 */ - public int cardinality() { + public int cardinality() + { statisticsUpdate(); // Update size, cardinality and length values return cache.cardinality; } - public void clear(int i) { + /** + * Sets the bit at the specified index to false. + * + * @param i a bit index. + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE. + * @since 1.6 + */ + public void clear(int i) + { /* In the interests of speed, no check is made here on whether the level3 block goes to all zero. This may be found and corrected in some later operation. */ if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); - if (i > bitsLength) + if (i >= bitsLength) return; final int w = i >> SHIFT3; long[][] a2; - int ws1 = w >> SHIFT1; - if (bits.length <= ws1 || (a2 = bits[ws1]) == null) + if ((a2 = bits[w >> SHIFT1]) == null) return; long[] a3; if ((a3 = a2[(w >> SHIFT2) & MASK2]) == null) @@ -562,50 +592,54 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Sets the bits from the specified i (inclusive) to the - * specified j (exclusive) to false. + * Sets the bits from the specified i (inclusive) to the + * specified j (exclusive) to false. * - * @param i index of the first bit to be cleared - * @param j index after the last bit to be cleared - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to be cleared + * @param j index after the last bit to be cleared + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ - public void clear(int i, int j) throws IndexOutOfBoundsException { + public void clear(int i, int j) throws IndexOutOfBoundsException + { setScanner(i, j, null, clearStrategy); } /** - * Sets all of the bits in this SparseBitSet to - * false. + * Sets all of the bits in this SparseBitSet to + * false. * - * @since 1.6 + * @since 1.6 */ - public void clear() { + public void clear() + { /* This simply resets to null all the entries in the set. */ nullify(0); } /** - * Cloning this SparseBitSet produces a new - * SparseBitSet that is equal() to it. The clone of the - * bit set is another bit set that has exactly the same bits set to - * true as this bit set. - *

- * Note: the actual space allocated to the clone tries to minimise the actual - * amount of storage allocated to hold the bits, while still trying to - * keep access to the bits being a rapid as possible. Since the space - * allocated to a SparseBitSet is not normally decreased, - * replacing a bit set by its clone may be a way of both managing memory - * consumption and improving the rapidity of access. + * Cloning this SparseBitSet produces a new + * SparseBitSet that is equal() to it. The clone of the + * bit set is another bit set that has exactly the same bits set to + * true as this bit set. + *

+ * Note: the actual space allocated to the clone tries to minimise the actual + * amount of storage allocated to hold the bits, while still trying to + * keep access to the bits being a rapid as possible. Since the space + * allocated to a SparseBitSet is not normally decreased, + * replacing a bit set by its clone may be a way of both managing memory + * consumption and improving the rapidity of access. * - * @return a clone of this SparseBitSet - * @since 1.6 + * @return a clone of this SparseBitSet + * @since 1.6 */ @Override - public SparseBitSet clone() { - try { + public SparseBitSet clone() + { + try + { final SparseBitSet result = (SparseBitSet) super.clone(); /* Clear out the shallow copy of the set array (which contains just copies of the references from this set), and then replace these @@ -617,10 +651,13 @@ public final class SparseBitSet implements Cloneable, Serializable { are linked to their parent object) (Not all visitors actually use this link to their containing object, but they are reset here just in case of future changes). */ - result.constructorHelper(); // also creates the copyStrategy - result.setScanner(0, bitsLength, this, result.copyStrategy); + result.constructorHelper(); + result.equalsStrategy = null; + result.setScanner(0, bitsLength, this, copyStrategy); return result; - } catch (CloneNotSupportedException ex) { + } + catch (CloneNotSupportedException ex) + { /* This code has not been unit tested. Inspection offers hope that is will work, but it likely never to be used. */ throw new InternalError(ex.getMessage()); @@ -628,21 +665,22 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Compares this object against the specified object. The result is - * true if and only if the argument is not null - * and is a SparseBitSet object that has exactly the same bits - * set to true as this bit set. That is, for every nonnegative - * i indexing a bit in the set, - *

((SparseBitSet)obj).get(i) == this.get(i)
- * must be true. + * Compares this object against the specified object. The result is + * true if and only if the argument is not null + * and is a SparseBitSet object that has exactly the same bits + * set to true as this bit set. That is, for every nonnegative + * i indexing a bit in the set, + *
((SparseBitSet)obj).get(i) == this.get(i)
+ * must be true. * - * @param obj the Object with which to compare - * @return true if the objects are equivalent; - * false otherwise. - * @since 1.6 + * @param obj the Object with which to compare + * @return true if the objects are equivalent; + * false otherwise. + * @since 1.6 */ @Override - public boolean equals(Object obj) { + public boolean equals(Object obj) + { /* Sanity and quick checks. */ if (!(obj instanceof SparseBitSet)) return false; @@ -651,19 +689,23 @@ public final class SparseBitSet implements Cloneable, Serializable { return true; // Identity /* Do the real work. */ + if (equalsStrategy == null) + equalsStrategy = new EqualsStrategy(); + setScanner(0, Math.max(bitsLength, b.bitsLength), b, equalsStrategy); return equalsStrategy.result; } /** - * Sets the bit at the specified index to the complement of its current value. + * Sets the bit at the specified index to the complement of its current value. * - * @param i the index of the bit to flip - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i the index of the bit to flip + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void flip(int i) { + public void flip(int i) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); final int w = i >> SHIFT3; @@ -683,34 +725,36 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Sets each bit from the specified i (inclusive) to the - * specified j (exclusive) to the complement of its current - * value. + * Sets each bit from the specified i (inclusive) to the + * specified j (exclusive) to the complement of its current + * value. * - * @param i index of the first bit to flip - * @param j index after the last bit to flip - * @throws IndexOutOfBoundsException if i is negative or is - * equal to Integer.MAX_VALUE, or j is negative, or - * i is larger than j - * @since 1.6 + * @param i index of the first bit to flip + * @param j index after the last bit to flip + * @exception IndexOutOfBoundsException if i is negative or is + * equal to Integer.MAX_VALUE, or j is negative, or + * i is larger than j + * @since 1.6 */ - public void flip(int i, int j) throws IndexOutOfBoundsException { + public void flip(int i, int j) throws IndexOutOfBoundsException + { setScanner(i, j, null, flipStrategy); } /** - * Returns the value of the bit with the specified index. The value is - * true if the bit with the index i is currently set - * in this SparseBitSet; otherwise, the result is - * false. + * Returns the value of the bit with the specified index. The value is + * true if the bit with the index i is currently set + * in this SparseBitSet; otherwise, the result is + * false. * - * @param i the bit index - * @return the boolean value of the bit with the specified index. - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i the bit index + * @return the boolean value of the bit with the specified index. + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public boolean get(int i) { + public boolean get(int i) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); final int w = i >> SHIFT3; @@ -718,44 +762,45 @@ public final class SparseBitSet implements Cloneable, Serializable { long[][] a2; long[] a3; return i < bitsLength && (a2 = bits[w >> SHIFT1]) != null - && (a3 = a2[(w >> SHIFT2) & MASK2]) != null - && ((a3[w & MASK3] & (1L << i)) != 0); + && (a3 = a2[(w >> SHIFT2) & MASK2]) != null + && ((a3[w & MASK3] & (1L << i)) != 0); } /** - * Returns a new SparseBitSet composed of bits from this - * SparseBitSet from i (inclusive) to j - * (exclusive). + * Returns a new SparseBitSet composed of bits from this + * SparseBitSet from i (inclusive) to j + * (exclusive). * - * @param i index of the first bit to include - * @param j index after the last bit to include - * @return a new SparseBitSet from a range of this SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or is - * equal to Integer.MAX_VALUE, or j is negative, or - * i is larger than j - * @since 1.6 + * @param i index of the first bit to include + * @param j index after the last bit to include + * @return a new SparseBitSet from a range of this SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or is + * equal to Integer.MAX_VALUE, or j is negative, or + * i is larger than j + * @since 1.6 */ - public SparseBitSet get(int i, int j) throws IndexOutOfBoundsException { + public SparseBitSet get(int i, int j) throws IndexOutOfBoundsException + { final SparseBitSet result = new SparseBitSet(j, compactionCount); - result.setScanner(i, j, this, result.copyStrategy); + result.setScanner(i, j, this, copyStrategy); return result; } /** - * Returns a hash code value for this bit set. The hash code depends only on - * which bits have been set within this SparseBitSet. The - * algorithm used to compute it may be described as follows. - *

- * Suppose the bits in the SparseBitSet were to be stored in an - * array of long integers called, say, bits, in such - * a manner that bit i is set in the SparseBitSet - * (for nonnegative values of i) if and only if the expression - *

+     *  Returns a hash code value for this bit set. The hash code depends only on
+     *  which bits have been set within this SparseBitSet. The
+     *  algorithm used to compute it may be described as follows.
+     *  

+ * Suppose the bits in the SparseBitSet were to be stored in an + * array of long integers called, say, bits, in such + * a manner that bit i is set in the SparseBitSet + * (for nonnegative values of i) if and only if the expression + *

      *  ((i>>6) < bits.length) && ((bits[i>>6] & (1L << (bit & 0x3F))) != 0)
      *  
- * is true. Then the following definition of the hashCode method - * would be a correct implementation of the actual algorithm: - *
+     *  is true. Then the following definition of the hashCode method
+     *  would be a correct implementation of the actual algorithm:
+     *  
      *  public int hashCode()
      *  {
      *      long hash = 1234L;
@@ -763,91 +808,97 @@ public final class SparseBitSet implements Cloneable, Serializable {
      *          hash ^= bits[i] * (i + 1);
      *      return (int)((h >> 32) ^ h);
      *  }
- * Note that the hash code values change if the set of bits is altered. + * Note that the hash code values change if the set of bits is altered. * - * @return a hash code value for this bit set - * @see Object#equals(Object) - * @see java.util.Hashtable - * @since 1.6 + * @return a hash code value for this bit set + * @since 1.6 + * @see Object#equals(Object) + * @see java.util.Hashtable */ @Override - public int hashCode() { + public int hashCode() + { statisticsUpdate(); return cache.hash; } /** - * Returns true if the specified SparseBitSet has any bits - * within the given range i (inclusive) to j - * (exclusive) set to true that are also set to true - * in the same range of this SparseBitSet. + * Returns true if the specified SparseBitSet has any bits + * within the given range i (inclusive) to j + * (exclusive) set to true that are also set to true + * in the same range of this SparseBitSet. * - * @param i index of the first bit to include - * @param j index after the last bit to include - * @param b the SparseBitSet with which to intersect - * @return the boolean indicating whether this SparseBitSet intersects the - * specified SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to include + * @param j index after the last bit to include + * @param b the SparseBitSet with which to intersect + * @return the boolean indicating whether this SparseBitSet intersects the + * specified SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ public boolean intersects(int i, int j, SparseBitSet b) - throws IndexOutOfBoundsException { + throws IndexOutOfBoundsException + { setScanner(i, j, b, intersectsStrategy); return intersectsStrategy.result; } /** - * Returns true if the specified SparseBitSet has any bits set to - * true that are also set to true in this - * SparseBitSet. + * Returns true if the specified SparseBitSet has any bits set to + * true that are also set to true in this + * SparseBitSet. * - * @param b a SparseBitSet with which to intersect - * @return boolean indicating whether this SparseBitSet intersects the - * specified SparseBitSet - * @since 1.6 + * @param b a SparseBitSet with which to intersect + * @return boolean indicating whether this SparseBitSet intersects the + * specified SparseBitSet + * @since 1.6 */ - public boolean intersects(SparseBitSet b) { + public boolean intersects(SparseBitSet b) + { setScanner(0, Math.max(bitsLength, b.bitsLength), b, intersectsStrategy); return intersectsStrategy.result; } /** - * Returns true if this SparseBitSet contains no bits that are - * set to true. + * Returns true if this SparseBitSet contains no bits that are + * set to true. * - * @return the boolean indicating whether this SparseBitSet is empty - * @since 1.6 + * @return the boolean indicating whether this SparseBitSet is empty + * @since 1.6 */ - public boolean isEmpty() { + public boolean isEmpty() + { statisticsUpdate(); return cache.cardinality == 0; } /** - * Returns the "logical length" of this SparseBitSet: the index - * of the highest set bit in the SparseBitSet plus one. Returns - * zero if the SparseBitSet contains no set bits. + * Returns the "logical length" of this SparseBitSet: the index + * of the highest set bit in the SparseBitSet plus one. Returns + * zero if the SparseBitSet contains no set bits. * - * @return the logical length of this SparseBitSet - * @since 1.6 + * @return the logical length of this SparseBitSet + * @since 1.6 */ - public int length() { + public int length() + { statisticsUpdate(); return cache.length; } /** - * Returns the index of the first bit that is set to false that - * occurs on or after the specified starting index. + * Returns the index of the first bit that is set to false that + * occurs on or after the specified starting index. * - * @param i the index to start checking from (inclusive) - * @return the index of the next clear bit, or -1 if there is no such bit - * @throws IndexOutOfBoundsException if the specified index is negative - * @since 1.6 + * @param i the index to start checking from (inclusive) + * @return the index of the next clear bit, or -1 if there is no such bit + * @exception IndexOutOfBoundsException if the specified index is negative + * @since 1.6 */ - public int nextClearBit(int i) { + public int nextClearBit(int i) + { /* The index of this method is permitted to be Integer.MAX_VALUE, as this is needed to make this method work together with the method nextSetBit()--as might happen if a search for the next clear bit is @@ -872,8 +923,9 @@ public final class SparseBitSet implements Cloneable, Serializable { (including the nominated beginning bit itself). The first check is whether the starting bit is within the structure at all. */ if (w1 < aLength && (a2 = bits[w1]) != null - && (a3 = a2[w2]) != null - && ((nword = ~a3[w3] & (~0L << i))) == 0L) { + && (a3 = a2[w2]) != null + && ((nword = ~a3[w3] & (~0L << i))) == 0L) + { /* So now start a search though the rest of the entries for a null area or block, or a clear bit (a set bit in the complemented value). */ @@ -881,44 +933,49 @@ public final class SparseBitSet implements Cloneable, Serializable { w3 = w & MASK3; w2 = (w >> SHIFT2) & MASK2; w1 = w >> SHIFT1; - loop: - for (; w1 != aLength; ++w1) { - if ((a2 = bits[w1]) != null) - for (; w2 != LENGTH2; ++w2) { - if ((a3 = a2[w2]) != null) - for (; w3 != LENGTH3; ++w3) - if ((nword = ~a3[w3]) != 0) - break loop; - w3 = 0; - } + nword = ~0L; + loop: for (; w1 != aLength; ++w1) + { + if ((a2 = bits[w1]) == null) + break; + for (; w2 != LENGTH2; ++w2) + { + if ((a3 = a2[w2]) == null) + break loop; + for (; w3 != LENGTH3; ++w3) + if ((nword = ~a3[w3]) != 0) + break loop; + w3 = 0; + } w2 = w3 = 0; } } final int result = (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) - + Long.numberOfTrailingZeros(nword); + + Long.numberOfTrailingZeros(nword); return (result == Integer.MAX_VALUE ? -1 : result); } /** - * Returns the index of the first bit that is set to true that - * occurs on or after the specified starting index. If no such it exists then - * -1 is returned. - *

- * To iterate over the true bits in a SparseBitSet - * sbs, use the following loop: - *

- *

+     *  Returns the index of the first bit that is set to true that
+     *  occurs on or after the specified starting index. If no such it exists then
+     *  -1 is returned.
+     *  

+ * To iterate over the true bits in a SparseBitSet + * sbs, use the following loop: + * + *

      *  for( int i = sbbits.nextSetBit(0); i >= 0; i = sbbits.nextSetBit(i+1) )
      *  {
      *      // operate on index i here
      *  }
* - * @param i the index to start checking from (inclusive) - * @return the index of the next set bit - * @throws IndexOutOfBoundsException if the specified index is negative - * @since 1.6 + * @param i the index to start checking from (inclusive) + * @return the index of the next set bit + * @exception IndexOutOfBoundsException if the specified index is negative + * @since 1.6 */ - public int nextSetBit(int i) { + public int nextSetBit(int i) + { /* The index value (i) of this method is permitted to be Integer.MAX_VALUE, as this is needed to make the loop defined above work: just in case the bit labelled Integer.MAX_VALUE-1 is set. This case is not optimised: @@ -942,17 +999,19 @@ public final class SparseBitSet implements Cloneable, Serializable { (including the nominated beginning bit itself). The first check is whether the starting bit is within the structure at all. */ if (w1 < aLength && ((a2 = bits[w1]) == null - || (a3 = a2[w2]) == null - || ((word = a3[w3] & (~0L << i)) == 0L))) { + || (a3 = a2[w2]) == null + || ((word = a3[w3] & (~0L << i)) == 0L))) + { /* So now start a search though the rest of the entries for a bit. */ ++w; w3 = w & MASK3; w2 = (w >> SHIFT2) & MASK2; w1 = w >> SHIFT1; - major: - for (; w1 != aLength; ++w1) { + major: for (; w1 != aLength; ++w1) + { if ((a2 = bits[w1]) != null) - for (; w2 != LENGTH2; ++w2) { + for (; w2 != LENGTH2; ++w2) + { if ((a3 = a2[w2]) != null) for (; w3 != LENGTH3; ++w3) if ((word = a3[w3]) != 0) @@ -963,23 +1022,162 @@ public final class SparseBitSet implements Cloneable, Serializable { } } return (w1 >= aLength ? -1 - : (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + : (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + Long.numberOfTrailingZeros(word)); } /** - * Performs a logical OR of the addressed target bit with the - * argument value. This bit set is modified so that the addressed bit has the - * value true if and only if it both initially had the value - * true or the argument value is true. + * Returns the index of the nearest bit that is set to {@code false} + * that occurs on or before the specified starting index. + * If no such bit exists, or if {@code -1} is given as the + * starting index, then {@code -1} is returned. * - * @param i a bit index - * @param value a boolean value to OR with that bit - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i the index to start checking from (inclusive) + * @return the index of the previous clear bit, or {@code -1} if there + * is no such bit + * @throws IndexOutOfBoundsException if the specified index is less + * than {@code -1} + * @since 1.2 + * @see java.util.BitSet#previousClearBit */ - public void or(int i, boolean value) { + public int previousClearBit(int i) + { + if (i < 0) + { + if (i == -1) + return -1; + throw new IndexOutOfBoundsException("i=" + i); + } + + final long[][][] bits = this.bits; + final int aSize = bits.length - 1; + + int w = i >> SHIFT3; + int w3 = w & MASK3; + int w2 = (w >> SHIFT2) & MASK2; + int w1 = w >> SHIFT1; + if (w1 > aSize) + return i; + w1 = Math.min(w1, aSize); + int w4 = i % LENGTH4; + + long word; + long[][] a2; + long[] a3; + + for (; w1 >= 0; --w1) + { + if ((a2 = bits[w1]) == null) + return (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + w4; + for (; w2 >= 0; --w2) + { + if ((a3 = a2[w2]) == null) + return (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + w4; + for (; w3 >= 0; --w3) + { + if ((word = a3[w3]) == 0) + return (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + w4; + for (int bitIdx = w4; bitIdx >= 0; --bitIdx) + { + if ((word & (1L << bitIdx)) == 0) + return (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + bitIdx; + } + w4 = LENGTH4_SIZE; + } + w3 = LENGTH3_SIZE; + } + w2 = LENGTH2_SIZE; + } + return -1; + } + + /** + * Returns the index of the nearest bit that is set to {@code true} + * that occurs on or before the specified starting index. + * If no such bit exists, or if {@code -1} is given as the + * starting index, then {@code -1} is returned. + * + * @param i the index to start checking from (inclusive) + * @return the index of the previous set bit, or {@code -1} if there + * is no such bit + * @throws IndexOutOfBoundsException if the specified index is less + * than {@code -1} + * @since 1.2 + * @see java.util.BitSet#previousSetBit + */ + public int previousSetBit(int i) + { + if (i < 0) + { + if (i == -1) + return -1; + throw new IndexOutOfBoundsException("i=" + i); + } + + final long[][][] bits = this.bits; + final int aSize = bits.length - 1; + + /* This is the word from which the search begins. */ + final int w = i >> SHIFT3; + int w1 = w >> SHIFT1; + int w2, w3, w4; + /* But if its off the end of the array, start from the very end. */ + if (w1 > aSize) + { + w1 = aSize; + w2 = LENGTH2_SIZE; + w3 = LENGTH3_SIZE; + w4 = LENGTH4_SIZE; + } + else + { + w2 = (w >> SHIFT2) & MASK2; + w3 = w & MASK3; + w4 = i % LENGTH4; + } + long word; + long[][] a2; + long[] a3; + for (; w1 >= 0; --w1) + { + if ((a2 = bits[w1]) != null) + for (; w2 >= 0; --w2) + { + if ((a3 = a2[w2]) != null) + for (; w3 >= 0; --w3) + { + if ((word = a3[w3]) != 0) + for (int bitIdx = w4; bitIdx >= 0; --bitIdx) + { + if ((word & (1L << bitIdx)) != 0) + return (((w1 << SHIFT1) + (w2 << SHIFT2) + w3) << SHIFT3) + bitIdx; + } + w4 = LENGTH4_SIZE; + } + w3 = LENGTH3_SIZE; + w4 = LENGTH4_SIZE; + } + w2 = LENGTH2_SIZE; + w3 = LENGTH3_SIZE; + w4 = LENGTH4_SIZE; + } + return -1; + } + + /** + * Performs a logical OR of the addressed target bit with the + * argument value. This bit set is modified so that the addressed bit has the + * value true if and only if it both initially had the value + * true or the argument value is true. + * + * @param i a bit index + * @param value a boolean value to OR with that bit + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 + */ + public void or(int i, boolean value) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); if (value) @@ -987,67 +1185,71 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Performs a logical OR of the addressed target bit with the - * argument value within the given range. This bit set is modified so that - * within the range a bit in it has the value true if and only if - * it either already had the value true or the corresponding bit - * in the bit set argument has the value true. Outside the range - * this set is not changed. + * Performs a logical OR of the addressed target bit with the + * argument value within the given range. This bit set is modified so that + * within the range a bit in it has the value true if and only if + * it either already had the value true or the corresponding bit + * in the bit set argument has the value true. Outside the range + * this set is not changed. * - * @param i index of the first bit to be included in the operation - * @param j index after the last bit to included in the operation - * @param b the SparseBitSet with which to perform the OR - * operation with this SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to be included in the operation + * @param j index after the last bit to included in the operation + * @param b the SparseBitSet with which to perform the OR + * operation with this SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ - public void or(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException { + public void or(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException + { setScanner(i, j, b, orStrategy); } /** - * Performs a logical OR of this bit set with the bit set argument. - * This bit set is modified so that a bit in it has the value true - * if and only if it either already had the value true or the - * corresponding bit in the bit set argument has the value true. + * Performs a logical OR of this bit set with the bit set argument. + * This bit set is modified so that a bit in it has the value true + * if and only if it either already had the value true or the + * corresponding bit in the bit set argument has the value true. * - * @param b the SparseBitSet with which to perform the OR - * operation with this SparseBitSet - * @since 1.6 + * @param b the SparseBitSet with which to perform the OR + * operation with this SparseBitSet + * @since 1.6 */ - public void or(SparseBitSet b) { + public void or(SparseBitSet b) + { setScanner(0, b.bitsLength, b, orStrategy); } /** - * Performs a logical OR of the two given SparseBitSets. - * The returned SparseBitSet is created so that a bit in it has - * the value true if and only if it either had the value - * true in the set given by the first arguemetn or had the value - * true in the second argument, otherwise false. + * Performs a logical OR of the two given SparseBitSets. + * The returned SparseBitSet is created so that a bit in it has + * the value true if and only if it either had the value + * true in the set given by the first arguemetn or had the value + * true in the second argument, otherwise false. * - * @param a a SparseBitSet - * @param b another SparseBitSet - * @return new SparseBitSet representing the OR of the two sets - * @since 1.6 + * @param a a SparseBitSet + * @param b another SparseBitSet + * @return new SparseBitSet representing the OR of the two sets + * @since 1.6 */ - public static SparseBitSet or(SparseBitSet a, SparseBitSet b) { + public static SparseBitSet or(SparseBitSet a, SparseBitSet b) + { final SparseBitSet result = a.clone(); result.or(b); return result; } /** - * Sets the bit at the specified index. + * Sets the bit at the specified index. * - * @param i a bit index - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i a bit index + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void set(int i) { + public void set(int i) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); final int w = i >> SHIFT3; @@ -1067,15 +1269,16 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Sets the bit at the specified index to the specified value. + * Sets the bit at the specified index to the specified value. * - * @param i a bit index - * @param value a boolean value to set - * @throws IndexOutOfBoundsException if the specified index is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i a bit index + * @param value a boolean value to set + * @exception IndexOutOfBoundsException if the specified index is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void set(int i, boolean value) { + public void set(int i, boolean value) + { if (value) set(i); else @@ -1083,33 +1286,35 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Sets the bits from the specified i (inclusive) to the specified - * j (exclusive) to true. + * Sets the bits from the specified i (inclusive) to the specified + * j (exclusive) to true. * - * @param i index of the first bit to be set - * @param j index after the last bit to be se - * @throws IndexOutOfBoundsException if i is negative or is - * equal to Integer.MAX_INT, or j is negative, or - * i is larger than j. - * @since 1.6 + * @param i index of the first bit to be set + * @param j index after the last bit to be se + * @exception IndexOutOfBoundsException if i is negative or is + * equal to Integer.MAX_INT, or j is negative, or + * i is larger than j. + * @since 1.6 */ - public void set(int i, int j) throws IndexOutOfBoundsException { + public void set(int i, int j) throws IndexOutOfBoundsException + { setScanner(i, j, null, setStrategy); } /** - * Sets the bits from the specified i (inclusive) to the specified - * j (exclusive) to the specified value. + * Sets the bits from the specified i (inclusive) to the specified + * j (exclusive) to the specified value. * - * @param i index of the first bit to be set - * @param j index after the last bit to be set - * @param value to which to set the selected bits - * @throws IndexOutOfBoundsException if i is negative or is - * equal to Integer.MAX_VALUE, or j is negative, or - * i is larger than j - * @since 1.6 + * @param i index of the first bit to be set + * @param j index after the last bit to be set + * @param value to which to set the selected bits + * @exception IndexOutOfBoundsException if i is negative or is + * equal to Integer.MAX_VALUE, or j is negative, or + * i is larger than j + * @since 1.6 */ - public void set(int i, int j, boolean value) { + public void set(int i, int j, boolean value) + { if (value) set(i, j); else @@ -1117,48 +1322,51 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Returns the number of bits of space nominally in use by this - * SparseBitSet to represent bit values. The count of bits in - * the set is the (label of the last set bit) + 1 - (the label of the first - * set bit). + * Returns the number of bits of space nominally in use by this + * SparseBitSet to represent bit values. The count of bits in + * the set is the (label of the last set bit) + 1 - (the label of the first + * set bit). * - * @return the number of bits (true and false) nominally in this bit set - * at this moment - * @since 1.6 + * @return the number of bits (true and false) nominally in this bit set + * at this moment + * @since 1.6 */ - public int size() { + public int size() + { statisticsUpdate(); return cache.size; } /** - * Convenience method for statistics if the individual results are not needed. + * Convenience method for statistics if the individual results are not needed. * - * @return a String detailing the statistics of the bit set - * @see #statistics(String[]) - * @since 1.6 + * @return a String detailing the statistics of the bit set + * @see #statistics(String[]) + * @since 1.6 */ - public String statistics() { + public String statistics() + { return statistics(null); } /** - * Determine, and create a String with the bit set statistics. The statistics - * include: Size, Length, Cardinality, Total words (i.e., the total - * number of 64-bit "words"), Set array length (i.e., the number of - * references that can be held by the top level array, Level2 areas in use, - * Level3 blocks in use,, Level2 pool size, Level3 pool size, and the - * Compaction count. - *

- * This method is intended for diagnostic use (as it is relatively expensive - * in time), but can be useful in understanding an application's use of a - * SparseBitSet. + * Determine, and create a String with the bit set statistics. The statistics + * include: Size, Length, Cardinality, Total words (i.e., the total + * number of 64-bit "words"), Set array length (i.e., the number of + * references that can be held by the top level array, Level2 areas in use, + * Level3 blocks in use,, Level2 pool size, Level3 pool size, and the + * Compaction count. + *

+ * This method is intended for diagnostic use (as it is relatively expensive + * in time), but can be useful in understanding an application's use of a + * SparseBitSet. * - * @param values an array for the individual results (if not null) - * @return a String detailing the statistics of the bit set - * @since 1.6 + * @param values an array for the individual results (if not null) + * @return a String detailing the statistics of the bit set + * @since 1.6 */ - public String statistics(String[] values) { + public String statistics(String[] values) + { statisticsUpdate(); // Ensure statistics are up-to-date String[] v = new String[Statistics.values().length]; @@ -1171,26 +1379,27 @@ public final class SparseBitSet implements Cloneable, Serializable { v[Statistics.Total_words.ordinal()] = Integer.toString(cache.count); v[Statistics.Set_array_length.ordinal()] = Integer.toString(bits.length); v[Statistics.Set_array_max_length.ordinal()] = - Integer.toString(MAX_LENGTH1); + Integer.toString(MAX_LENGTH1); v[Statistics.Level2_areas.ordinal()] = Integer.toString(cache.a2Count); v[Statistics.Level2_area_length.ordinal()] = Integer.toString(LENGTH2); v[Statistics.Level3_blocks.ordinal()] = Integer.toString(cache.a3Count); v[Statistics.Level3_block_length.ordinal()] = Integer.toString(LENGTH3); v[Statistics.Compaction_count_value.ordinal()] = - Integer.toString(compactionCount); + Integer.toString(compactionCount); /* Determine the longest label, so that the equal signs may be lined-up. */ int longestLabel = 0; for (Statistics s : Statistics.values()) longestLabel = - Math.max(longestLabel, s.name().length()); + Math.max(longestLabel, s.name().length()); /* Build a String that has for each statistic, the name of the statistic, padding, and equals sign, and the value. The "Load_factor_value", "Average_length_value", and "Average_chain_length" are printed as floating point values. */ final StringBuilder result = new StringBuilder(); - for (Statistics s : Statistics.values()) { + for (Statistics s : Statistics.values()) + { result.append(s.name()); // The name of the statistic for (int i = 0; i != longestLabel - s.name().length(); ++i) result.append(' '); // Fill out the field @@ -1203,7 +1412,8 @@ public final class SparseBitSet implements Cloneable, Serializable { if (result.charAt(i) == '_') result.setCharAt(i, ' '); - if (values != null) { + if (values != null) + { final int len = Math.min(values.length, v.length); System.arraycopy(v, 0, values, 0, len); } @@ -1211,54 +1421,57 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Returns a string representation of this bit set. For every index for which - * this SparseBitSet contains a bit in the set state, the decimal - * representation of that index is included in the result. Such indices are - * listed in order from lowest to highest. If there is a subsequence of set - * bits longer than the value given by toStringCompaction, the subsequence - * is represented by the value for the first and the last values, with ".." - * between them. The individual bits, or the representation of sub-sequences - * are separated by ", " (a comma and a space) and surrounded by braces, - * resulting in a compact string showing (a variant of) the usual mathematical - * notation for a set of integers. - *
- * Example (with the default value of 2 for subsequences): - *

+     *  Returns a string representation of this bit set. For every index for which
+     *  this SparseBitSet contains a bit in the set state, the decimal
+     *  representation of that index is included in the result. Such indices are
+     *  listed in order from lowest to highest. If there is a subsequence of set
+     *  bits longer than the value given by toStringCompaction, the subsequence
+     *  is represented by the value for the first and the last values, with ".."
+     *  between them. The individual bits, or the representation of sub-sequences
+     *  are separated by ", " (a comma and a space) and surrounded by braces,
+     *  resulting in a compact string showing (a variant of) the usual mathematical
+     *  notation for a set of integers.
+     *  
+ * Example (with the default value of 2 for subsequences): + *
      *      SparseBitSet drPepper = new SparseBitSet();
      *  
- * Now drPepper.toString() returns "{}". - *
- *
+     *  Now drPepper.toString() returns "{}".
+     *  
+ *
      *      drPepper.set(2);
      *  
- * Now drPepper.toString() returns "{2}". - *
- *
+     *  Now drPepper.toString() returns "{2}".
+     *  
+ *
      *      drPepper.set(3, 4);
      *      drPepper.set(10);
      *  
- * Now drPepper.toString() returns "{2..4, 10}". - *
- * This method is intended for diagnostic use (as it is relatively expensive - * in time), but can be useful in interpreting problems in an application's use - * of a SparseBitSet. + * Now drPepper.toString() returns "{2..4, 10}". + *
+ * This method is intended for diagnostic use (as it is relatively expensive + * in time), but can be useful in interpreting problems in an application's use + * of a SparseBitSet. * - * @return a String representation of this SparseBitSet - * @see #toStringCompaction(int length) - * @since 1.6 + * @return a String representation of this SparseBitSet + * @see #toStringCompaction(int length) + * @since 1.6 */ @Override - public String toString() { + public String toString() + { final StringBuilder p = new StringBuilder(200); p.append('{'); int i = nextSetBit(0); /* Loop so long as there is another bit to append to the String. */ - while (i >= 0) { + while (i >= 0) + { /* Append that next bit */ p.append(i); /* Find the position of the next bit to show. */ int j = nextSetBit(i + 1); - if (compactionCount > 0) { + if (compactionCount > 0) + { /* Give up if there is no next bit to show. */ if (j < 0) break; @@ -1269,7 +1482,8 @@ public final class SparseBitSet implements Cloneable, Serializable { last = (last < 0 ? Integer.MAX_VALUE : last); /* If the subsequence is more than the specified bits long, then collapse the subsequence into one entry in the String. */ - if (i + compactionCount < last) { + if (i + compactionCount < last) + { p.append("..").append(last - 1); /* Having accounted for a subsequence of bits that are all set, recompute the label of the next bit to show. */ @@ -1288,38 +1502,39 @@ public final class SparseBitSet implements Cloneable, Serializable { return p.toString(); } - /** - * Sequences of set bits longer than this value are shown by - * {@link #toString()} as a "sub-sequence," in the form a..b. - * Setting this value to zero causes each set bit to be listed individually. - * The default default value is 2 (which means sequences of three or more - * bits set are shown as a subsequence, and all other set bits are listed - * individually). - *

- * Note: this value will be passed to SparseBitSets that - * may be created within or as a result of the operations on this bit set, - * or, for static methods, from the value belonging to the first parameter. + /** Sequences of set bits longer than this value are shown by + * {@link #toString()} as a "sub-sequence," in the form a..b. + * Setting this value to zero causes each set bit to be listed individually. + * The default default value is 2 (which means sequences of three or more + * bits set are shown as a subsequence, and all other set bits are listed + * individually). + *

+ * Note: this value will be passed to SparseBitSets that + * may be created within or as a result of the operations on this bit set, + * or, for static methods, from the value belonging to the first parameter. * - * @param count the maximum count of a run of bits that are shown as + * @param count the maximum count of a run of bits that are shown as * individual entries in a toString() conversion. * If 0, all bits are shown individually. - * @see #toString() - * @since 1.6 + * @since 1.6 + * @see #toString() */ - public void toStringCompaction(int count) { + public void toStringCompaction(int count) + { compactionCount = count; } /** - * If change is true, the current value of the - * toStringCompaction() value is made the default value for all - * SparseBitSets created from this point onward in this JVM. + * If change is true, the current value of the + * toStringCompaction() value is made the default value for all + * SparseBitSets created from this point onward in this JVM. * - * @param change if true, change the default value - * @since 1.6 + * @param change if true, change the default value + * @since 1.6 */ - public void toStringCompaction(boolean change) { - /* This is an assignment to a static value: the integer value assignement + public void toStringCompaction(boolean change) + { + /* This is an assignment to a static value: the integer value assignment is atomic, so there will not be a partial store. If multiple invocations are made from multiple threads, there is a race condition that cannot be resolved by synchronization. */ @@ -1328,24 +1543,25 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Performs a logical XOR of the addressed target bit with the - * argument value. This bit set is modified so that the addressed bit has the - * value true if and only one of the following statements holds: - *

    - *
  • The addressed bit initially had the value true, and the - * value of the argument is false. - *
  • The bit initially had the value false, and the - * value of the argument is true. + * Performs a logical XOR of the addressed target bit with the + * argument value. This bit set is modified so that the addressed bit has the + * value true if and only one of the following statements holds: + *
      + *
    • The addressed bit initially had the value true, and the + * value of the argument is false. + *
    • The bit initially had the value false, and the + * value of the argument is true. *
    * - * @param i a bit index - * @param value a boolean value to XOR with that bit - * @throws java.lang.IndexOutOfBoundsException if the specified index - * is negative - * or equal to Integer.MAX_VALUE - * @since 1.6 + * @param i a bit index + * @param value a boolean value to XOR with that bit + * @exception java.lang.IndexOutOfBoundsException if the specified index + * is negative + * or equal to Integer.MAX_VALUE + * @since 1.6 */ - public void xor(int i, boolean value) { + public void xor(int i, boolean value) + { if ((i + 1) < 1) throw new IndexOutOfBoundsException("i=" + i); if (value) @@ -1353,68 +1569,71 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Performs a logical XOR of this bit set with the bit set argument - * within the given range. This resulting bit set is computed so that a bit - * within the range in it has the value true if and only if one - * of the following statements holds: - *
      - *
    • The bit initially had the value true, and the - * corresponding bit in the argument set has the value false. - *
    • The bit initially had the value false, and the - * corresponding bit in the argument set has the value true. + * Performs a logical XOR of this bit set with the bit set argument + * within the given range. This resulting bit set is computed so that a bit + * within the range in it has the value true if and only if one + * of the following statements holds: + *
        + *
      • The bit initially had the value true, and the + * corresponding bit in the argument set has the value false. + *
      • The bit initially had the value false, and the + * corresponding bit in the argument set has the value true. *
      - * Outside the range this set is not changed. + * Outside the range this set is not changed. * - * @param i index of the first bit to be included in the operation - * @param j index after the last bit to included in the operation - * @param b the SparseBitSet with which to perform the XOR - * operation with this SparseBitSet - * @throws IndexOutOfBoundsException if i is negative or - * equal to Integer.MAX_VALUE, or j is negative, - * or i is larger than j - * @since 1.6 + * @param i index of the first bit to be included in the operation + * @param j index after the last bit to included in the operation + * @param b the SparseBitSet with which to perform the XOR + * operation with this SparseBitSet + * @exception IndexOutOfBoundsException if i is negative or + * equal to Integer.MAX_VALUE, or j is negative, + * or i is larger than j + * @since 1.6 */ - public void xor(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException { + public void xor(int i, int j, SparseBitSet b) throws IndexOutOfBoundsException + { setScanner(i, j, b, xorStrategy); } /** - * Performs a logical XOR of this bit set with the bit set argument. - * This resulting bit set is computed so that a bit in it has the value - * true if and only if one of the following statements holds: - *
        - *
      • The bit initially had the value true, and the - * corresponding bit in the argument set has the value false. - *
      • The bit initially had the value false, and the - * corresponding bit in the argument set has the value true. + * Performs a logical XOR of this bit set with the bit set argument. + * This resulting bit set is computed so that a bit in it has the value + * true if and only if one of the following statements holds: + *
          + *
        • The bit initially had the value true, and the + * corresponding bit in the argument set has the value false. + *
        • The bit initially had the value false, and the + * corresponding bit in the argument set has the value true. *
        * - * @param b the SparseBitSet with which to perform the XOR - * operation with thisSparseBitSet - * @since 1.6 + * @param b the SparseBitSet with which to perform the XOR + * operation with thisSparseBitSet + * @since 1.6 */ - public void xor(SparseBitSet b) { + public void xor(SparseBitSet b) + { setScanner(0, b.bitsLength, b, xorStrategy); } /** * Performs a logical XOR of the two given SparseBitSets. - * The resulting bit set is created so that a bit in it has the value - * true if and only if one of the following statements holds: - *
          - *
        • A bit in the first argument has the value true, and the - * corresponding bit in the second argument has the value - * false.
        • - *
        • A bit in the first argument has the value false, and the - * corresponding bit in the second argument has the value - * true.
        + * The resulting bit set is created so that a bit in it has the value + * true if and only if one of the following statements holds: + *
          + *
        • A bit in the first argument has the value true, and the + * corresponding bit in the second argument has the value + * false.
        • + *
        • A bit in the first argument has the value false, and the + * corresponding bit in the second argument has the value + * true.
        * - * @param a a SparseBitSet - * @param b another SparseBitSet - * @return a new SparseBitSet representing the XOR of the two sets - * @since 1.6 + * @param a a SparseBitSet + * @param b another SparseBitSet + * @return a new SparseBitSet representing the XOR of the two sets + * @since 1.6 */ - public static SparseBitSet xor(SparseBitSet a, SparseBitSet b) { + public static SparseBitSet xor(SparseBitSet a, SparseBitSet b) + { final SparseBitSet result = a.clone(); result.xor(b); return result; @@ -1425,60 +1644,54 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================== /** - * Throw the exception to indicate a range error. The String - * constructed reports all the possible errors in one message. + * Throw the exception to indicate a range error. The String + * constructed reports all the possible errors in one message. * - * @param i lower bound for a operation - * @param j upper bound for a operation - * @throws IndexOutOfBoundsException indicating the range is not valid - * @since 1.6 + * @param i lower bound for a operation + * @param j upper bound for a operation + * @exception IndexOutOfBoundsException indicating the range is not valid + * @since 1.6 */ - protected static final void throwIndexOutOfBoundsException(int i, int j) - throws IndexOutOfBoundsException { + protected static void throwIndexOutOfBoundsException(int i, int j) + throws IndexOutOfBoundsException + { String s = ""; if (i < 0) s += "(i=" + i + ") < 0"; if (i == Integer.MAX_VALUE) s += "(i=" + i + ")"; if (j < 0) - s += (s.length() == 0 ? "" : ", ") + "(j=" + j + ") < 0"; + s += (s.isEmpty() ? "" : ", ") + "(j=" + j + ") < 0"; if (i > j) - s += (s.length() == 0 ? "" : ", ") + "(i=" + i + ") > (j=" + j + ")"; + s += (s.isEmpty() ? "" : ", ") + "(i=" + i + ") > (j=" + j + ")"; throw new IndexOutOfBoundsException(s); } /** - * Intializes all the additional objects required for correct operation. + * Intializes all the additional objects required for correct operation. * - * @since 1.6 + * @since 1.6 */ - protected final void constructorHelper() { + protected final void constructorHelper() + { spare = new long[LENGTH3]; cache = new Cache(); - andStrategy = new AndStrategy(); - andNotStrategy = new AndNotStrategy(); - clearStrategy = new ClearStrategy(); - equalsStrategy = new EqualsStrategy(); - flipStrategy = new FlipStrategy(); - copyStrategy = new CopyStrategy(); - intersectsStrategy = new IntersectsStrategy(); - orStrategy = new OrStrategy(); - setStrategy = new SetStrategy(); updateStrategy = new UpdateStrategy(); - xorStrategy = new XorStrategy(); } /** - * Clear out a part of the set array with nulls, from the given start to the - * end of the array. If the given parameter is beyond the end of the bits - * array, nothing is changed. + * Clear out a part of the set array with nulls, from the given start to the + * end of the array. If the given parameter is beyond the end of the bits + * array, nothing is changed. * - * @param start word index at which to start (inclusive) - * @since 1.6 + * @param start word index at which to start (inclusive) + * @since 1.6 */ - protected final void nullify(int start) { + protected final void nullify(int start) + { final int aLength = bits.length; - if (start < aLength) { + if (start < aLength) + { for (int w = start; w != aLength; ++w) bits[w] = null; cache.hash = 0; // Invalidate size, etc., values @@ -1486,17 +1699,18 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * Resize the bit array. Moves the entries in the the bits array of this - * SparseBitSet into an array whose size (which may be larger or smaller) is - * the given bit size (i.e., includes the bit whose index is one less - * that the given value). If the new array is smaller, the excess entries in - * the set array are discarded. If the new array is bigger, it is filled with - * nulls. + * Resize the bit array. Moves the entries in the the bits array of this + * SparseBitSet into an array whose size (which may be larger or smaller) is + * the given bit size (i.e., includes the bit whose index is one less + * that the given value). If the new array is smaller, the excess entries in + * the set array are discarded. If the new array is bigger, it is filled with + * nulls. * - * @param index the desired address to be included in the set - * @since 1.6 + * @param index the desired address to be included in the set + * @since 1.6 */ - protected final void resize(int index) { + protected final void resize(int index) + { /* Find an array size that is a power of two that is as least as large enough to contain the index requested. */ final int w1 = (index >> SHIFT3) >> SHIFT1; @@ -1509,39 +1723,42 @@ public final class SparseBitSet implements Cloneable, Serializable { newSize = MAX_LENGTH1; final int aLength1 = (bits != null ? bits.length : 0); - if (newSize != aLength1) { // only if the size needs to be changed + if (newSize != aLength1 || bits == null) + { // only if the size needs to be changed final long[][][] temp = new long[newSize][][]; // Get the new array - if (aLength1 != 0) { + if (aLength1 != 0) + { /* If it exists, copy old array to the new array. */ System.arraycopy(bits, 0, temp, 0, Math.min(aLength1, newSize)); nullify(0); // Don't leave unused pointers around. */ } bits = temp; // Set new array as the set array bitsLength = // Index of last possible bit, plus one. - (newSize == MAX_LENGTH1 ? Integer.MAX_VALUE : newSize * UNIT); + (newSize == MAX_LENGTH1 ? Integer.MAX_VALUE : newSize * UNIT); } } /** - * Scans over the bit set (and a second bit set if part of the operation) are - * all performed by this method. The properties and the operation executed - * are defined by a given strategy, which must be derived from the - * AbstractStrategy. The strategy defines how to operate on a - * single word, and on whole words that may or may not constitute a full - * block of words. + * Scans over the bit set (and a second bit set if part of the operation) are + * all performed by this method. The properties and the operation executed + * are defined by a given strategy, which must be derived from the + * AbstractStrategy. The strategy defines how to operate on a + * single word, and on whole words that may or may not constitute a full + * block of words. * - * @param i the bit (inclusive) at which to start the scan - * @param j the bit (exclusive) at which to stop the scan - * @param b a SparseBitSet, if needed, the second SparseBitSet in the - * operation - * @param op the AbstractStrategy class defining the operation to be - * executed - * @throws IndexOutOfBoundsException - * @see AbstractStrategy - * @since 1.6 + * @param i the bit (inclusive) at which to start the scan + * @param j the bit (exclusive) at which to stop the scan + * @param b a SparseBitSet, if needed, the second SparseBitSet in the + * operation + * @param op the AbstractStrategy class defining the operation to be + * executed + * @exception IndexOutOfBoundsException + * @since 1.6 + * @see AbstractStrategy */ protected final void setScanner(int i, int j, SparseBitSet b, - AbstractStrategy op) throws IndexOutOfBoundsException { + AbstractStrategy op) throws IndexOutOfBoundsException + { /* This method has been assessed as having a McCabe cyclomatic complexity of 47 (i.e., impossibly high). However, given that this method incorporates all the set scanning logic for all methods @@ -1555,7 +1772,9 @@ public final class SparseBitSet implements Cloneable, Serializable { /* Do whatever the strategy needs to get started, and do whatever initial checking is needed--fail here if needed before much else is done. */ - op.start(b); + if (op.start(b)) + cache.hash = 0; + if (j < i || (i + 1) < 1) throwIndexOutOfBoundsException(i, j); if (i == j) @@ -1604,27 +1823,32 @@ public final class SparseBitSet implements Cloneable, Serializable { /* The first level2 is cannot be judged empty if not being scanned from the beginning. */ boolean a2IsEmpty = u2 == 0; // Presumption - while (i < j) { + while (i < j) + { /* Determine if there is a level2 area in both the a and the b set, and if so, set the references to these areas. */ long[][] a2 = null; boolean haveA2 = u1 < aLength1 && (a2 = a1[u1]) != null; long[][] b2 = null; final boolean haveB2 = u1 < bLength1 - && b1 != null && (b2 = b1[u1]) != null; + && b1 != null && (b2 = b1[u1]) != null; /* Handling of level 2 empty areas: determined by the properties of the strategy. It is necessary to actually visit the first and last blocks of a scan, since not all of the block might participate in the operation, hence making decision based on just the references to the blocks could be wrong. */ if ((!haveA2 && !haveB2 && f_op_f_eq_f - || !haveA2 && f_op_x_eq_f || !haveB2 && x_op_f_eq_f) - && notFirstBlock && u1 != v1) {//nested if! + || !haveA2 && f_op_x_eq_f || !haveB2 && x_op_f_eq_f) + && notFirstBlock && u1 != v1) + {//nested if! if (u1 < aLength1) a1[u1] = null; - } else { - final int limit2 = (u1 != v1 ? LENGTH2 : v2 + 1); - while (u2 != limit2) { + } + else + { + final int limit2 = (u1 == v1 ? v2 + 1 : LENGTH2); + while (u2 != limit2) + { /* Similar logic applied here as for the level2 blocks. The initial and final block must be examined. In other cases, it may be possible to make a decision based on @@ -1639,13 +1863,15 @@ public final class SparseBitSet implements Cloneable, Serializable { /* Handling of level 3 empty areas: determined by the properties of the strategy. */ if ((!haveA3 && !haveB3 && f_op_f_eq_f - || !haveA3 && f_op_x_eq_f || !haveB3 && x_op_f_eq_f) - && notFirstBlock && notLastBlock) { + || !haveA3 && f_op_x_eq_f || !haveB3 && x_op_f_eq_f) + && notFirstBlock && notLastBlock) + { /* Do not need level3 block, so remove it, and move on. */ if (haveA2) a2[u2] = null; - u3 = 0; - } else { + } + else + { /* So what is needed is the level3 block. */ final int base3 = a3Block << SHIFT2; final int limit3 = (notLastBlock ? LENGTH3 : v3); @@ -1661,21 +1887,26 @@ public final class SparseBitSet implements Cloneable, Serializable { else isZero = op.block(base3, 0, LENGTH3, a3, b3); // Do the operation on the whole block - else { /* Partial block to process. */ - if (notFirstBlock) { + else + { /* Partial block to process. */ + if (notFirstBlock) + { /* By implication, this is the last block */ isZero = op.block(base3, 0, limit3, a3, b3); // Do the whole words isZero &= op.word(base3, limit3, a3, b3, vm); // And then the final word - } else { // u, v are correct if first block + } + else + { // u, v are correct if first block if (u == v) // Scan starts and ends in one word isZero = op.word(base3, u3, a3, b3, um & vm); - else { // Scan starts in this a3 block + else + { // Scan starts in this a3 block isZero = op.word(base3, u3, a3, b3, um); // First word isZero &= - op.block(base3, u3 + 1, limit3, a3, b3); + op.block(base3, u3 + 1, limit3, a3, b3); // Remainder of full words in block if (limit3 != LENGTH3) isZero &= op.word(base3, limit3, a3, b3, vm); @@ -1694,10 +1925,13 @@ public final class SparseBitSet implements Cloneable, Serializable { level3 block be a null (i.e., remove any a3 block ). */ if (haveA2) a2[u2] = null; - } else { + } + else + { /* If the a3 block used was the spare block, put it into current level2 area; get a new spare block. */ - if (a3 == spare) { + if (a3 == spare) + { if (i >= bitsLength) //Check that the set is large { // enough to take the new block resize(i); // Make it large enough @@ -1739,14 +1973,15 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * The entirety of the bit set is examined, and the various statistics of - * the bit set (size, length, cardinality, hashCode, etc.) are computed. Level - * arrays that are empty (i.e., all zero at level 3, all null at level 2) are - * replaced by null references, ensuring a normalized representation. + * The entirety of the bit set is examined, and the various statistics of + * the bit set (size, length, cardinality, hashCode, etc.) are computed. Level + * arrays that are empty (i.e., all zero at level 3, all null at level 2) are + * replaced by null references, ensuring a normalized representation. * - * @since 1.6 + * @since 1.6 */ - protected final void statisticsUpdate() { + protected final void statisticsUpdate() + { if (cache.hash != 0) return; setScanner(0, bitsLength, null, updateStrategy); @@ -1757,26 +1992,29 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================== /** - * Save the state of the SparseBitSet instance to a stream - * (i.e., serialize it). + * Save the state of the SparseBitSet instance to a stream + * (i.e., serialize it). * - * @param s the ObjectOutputStream to which to write the serialized object - * @throws java.io.IOException if an io error occurs - * @throws java.lang.InternalError if the SparseBitSet representation is - * inconsistent - * @serialData The default data is emitted, followed by the current - * compactionCount for the bit set, and then the - * length of the set (the position of the last bit), - * followed by the cache.count value (an int, - * the number of int->long pairs needed to describe - * the set), followed by the index (int) and word - * (long) for each int->long pair. - * The mappings need not be emitted in any particular order. This - * is followed by the hashCode for the set that can be used - * as an integrity check when the bit set is read back. - * @since 1.6 + * @param s the ObjectOutputStream to which to write the serialized object + * @exception java.io.IOException if an io error occurs + * @exception java.lang.InternalError if the SparseBitSet representation is + * inconsistent + * + * @serialData The default data is emitted, followed by the current + * compactionCount for the bit set, and then the + * length of the set (the position of the last bit), + * followed by the cache.count value (an int, + * the number of int->long pairs needed to describe + * the set), followed by the index (int) and word + * (long) for each int->long pair. + * The mappings need not be emitted in any particular order. This + * is followed by the hashCode for the set that can be used + * as an integrity check when the bit set is read back. + * + * @since 1.6 */ - private void writeObject(ObjectOutputStream s) throws IOException, InternalError { + private void writeObject(ObjectOutputStream s) throws IOException, InternalError + { statisticsUpdate(); // Update structure and stats if needed. /* Write any hidden stuff. */ s.defaultWriteObject(); @@ -1791,15 +2029,16 @@ public final class SparseBitSet implements Cloneable, Serializable { long[][] a2; long[] a3; long word; - int last = 0; for (int w1 = 0; w1 != aLength1; ++w1) if ((a2 = a1[w1]) != null) for (int w2 = 0; w2 != LENGTH2; ++w2) - if ((a3 = a2[w2]) != null) { + if ((a3 = a2[w2]) != null) + { final int base = (w1 << SHIFT1) + (w2 << SHIFT2); for (int w3 = 0; w3 != LENGTH3; ++w3) - if ((word = a3[w3]) != 0) { - s.writeInt(-last + (last = (base + w3))); + if ((word = a3[w3]) != 0) + { + s.writeInt(base + w3); s.writeLong(word); --count; } @@ -1811,22 +2050,23 @@ public final class SparseBitSet implements Cloneable, Serializable { } /** - * serialVersionUID + * serialVersionUID */ private static final long serialVersionUID = -6663013367427929992L; /** - * Reconstitute the SparseBitSet instance from a stream - * (i.e., deserialize it). + * Reconstitute the SparseBitSet instance from a stream + * (i.e., deserialize it). * - * @param s the ObjectInputStream to use - * @throws IOException if there is an io error - * @throws ClassNotFoundException if the stream contains an unidentified - * class - * @since 1.6 + * @param s the ObjectInputStream to use + * @exception IOException if there is an io error + * @exception ClassNotFoundException if the stream contains an unidentified + * class + * @since 1.6 */ private void readObject(ObjectInputStream s) throws IOException, - ClassNotFoundException { + ClassNotFoundException + { /* Read in any hidden stuff that is part of the class overhead. */ s.defaultReadObject(); compactionCount = s.readInt(); @@ -1838,9 +2078,9 @@ public final class SparseBitSet implements Cloneable, Serializable { /* Read the keys and values, them into the set array, areas, and blocks. */ long[][] a2; long[] a3; - int w = 0; - for (int n = 0; n != count; ++n) { - w += s.readInt(); + for (int n = 0; n != count; ++n) + { + final int w = s.readInt(); final int w3 = w & MASK3; final int w2 = (w >> SHIFT2) & MASK2; final int w1 = w >> SHIFT1; @@ -1867,66 +2107,66 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================= /** - * These enumeration values are used as labels for the values in the String - * created by the statistics() method. The values of the corresponding - * statistics are ints, except for the loadFactor and - * Average_chain_length values, which are floats. - *

        - * An array of Strings may be obtained containing a - * representation of each of these values. An element of such an array, say, - * values, may be accessed, for example, by: - *

        +     *  These enumeration values are used as labels for the values in the String
        +     *  created by the statistics() method. The values of the corresponding
        +     *  statistics are ints, except for the loadFactor and
        +     *  Average_chain_length values, which are floats.
        +     *  

        + * An array of Strings may be obtained containing a + * representation of each of these values. An element of such an array, say, + * values, may be accessed, for example, by: + *

              *      values[SparseBitSet.statistics.Buckets_available.ordinal()]
        * - * @see #statistics(String[]) + * @see #statistics(String[]) */ - public static enum Statistics { + public enum Statistics + { /** - * The size of the bit set, as give by the size() method. + * The size of the bit set, as give by the size() method. */ Size, // 0 /** - * The length of the bit set, as give by the length() method. + * The length of the bit set, as give by the length() method. */ Length, // 1 /** - * The cardinality of the bit set, as give by the cardinality() method. + * The cardinality of the bit set, as give by the cardinality() method. */ Cardinality, // 2 /** - * The total number of non-zero 64-bits "words" being used to hold the - * representation of the bit set. + * The total number of non-zero 64-bits "words" being used to hold the + * representation of the bit set. */ Total_words, // 3 /** - * The length of the bit set array. + * The length of the bit set array. */ Set_array_length, // 4 /** - * The maximum permitted length of the bit set array. + * The maximum permitted length of the bit set array. */ Set_array_max_length, // 5 /** - * The number of level2 areas. + * The number of level2 areas. */ Level2_areas, // 6 /** - * The length of the level2 areas. + * The length of the level2 areas. */ Level2_area_length, // 7 /** - * The total number of level3 blocks in use. + * The total number of level3 blocks in use. */ Level3_blocks, // 8 /** - * The length of the level3 blocks. + * The length of the level3 blocks. */ Level3_block_length, // 9 /** - * Is the value that determines how the toString() conversion is - * performed. - * - * @see #toStringCompaction(int) + * Is the value that determines how the toString() conversion is + * performed. + * @see #toStringCompaction(int) */ Compaction_count_value // 10 } @@ -1936,61 +2176,61 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================= /** - * This class holds the values related to various statistics kept about the - * bit set. These values are not kept continuously up-to-date. Whenever the - * values become invalid, the field hash is set to zero, indicating - * that an update is required. + * This class holds the values related to various statistics kept about the + * bit set. These values are not kept continuously up-to-date. Whenever the + * values become invalid, the field hash is set to zero, indicating + * that an update is required. * - * @see #statisticsUpdate() + * @see #statisticsUpdate() */ - protected class Cache { + protected class Cache + { /** - * hash is updated by the statisticsUpdate() method. - * If the hash value is zero, it is assumed that all - * the cached values are stale, and must be updated. + * hash is updated by the statisticsUpdate() method. + * If the hash value is zero, it is assumed that all + * the cached values are stale, and must be updated. */ - protected transient int hash; /** - * size is updated by the statisticsUpdate() method. - * If the hash value is zero, it is assumed the all the cached - * values are stale, and must be updated. + * size is updated by the statisticsUpdate() method. + * If the hash value is zero, it is assumed the all the cached + * values are stale, and must be updated. */ protected transient int size; /** - * cardinality is updated by the statisticsUpdate() method. - * If the hash value is zero, it is assumed the all the cached - * values are stale, and must be updated. + * cardinality is updated by the statisticsUpdate() method. + * If the hash value is zero, it is assumed the all the cached + * values are stale, and must be updated. */ protected transient int cardinality; /** - * length is updated by the statisticsUpdate() method. - * If the hash value is zero, it is assumed the all the cached - * values are stale, and must be updated. + * length is updated by the statisticsUpdate() method. + * If the hash value is zero, it is assumed the all the cached + * values are stale, and must be updated. */ protected transient int length; /** - * count is updated by the statisticsUpdate() method. - * If the hash value is zero, it is assumed the all the cached - * values are stale, and must be updated. + * count is updated by the statisticsUpdate() method. + * If the hash value is zero, it is assumed the all the cached + * values are stale, and must be updated. */ protected transient int count; /** - * a2Count is updated by the statisticsUpdate() - * method, and will only be correct immediately after a full update. The - * hash value is must be zero for all values to be updated. + * a2Count is updated by the statisticsUpdate() + * method, and will only be correct immediately after a full update. The + * hash value is must be zero for all values to be updated. */ protected transient int a2Count; /** - * a3Count is updated by the statisticsUpdate() method, - * and will only be correct immediately after a full update. The - * hash value is must be zero for all values to be updated. + * a3Count is updated by the statisticsUpdate() method, + * and will only be correct immediately after a full update. The + * hash value is must be zero for all values to be updated. */ protected transient int a3Count; } @@ -2000,131 +2240,131 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================= /** - * This strategy class is used by the setScanner to carry out the a variety - * of operations on this set, and usually a second set. The - * setScanner() method of the main SparseBitSet class - * essentially finds matching level3 blocks, and then calls the strategy to - * do the appropriate operation on each of the elements of the block. - *

        - * The symbolic constants control optimisation paths in the - * setScanner() method of the main SparseBitSet class. + * This strategy class is used by the setScanner to carry out the a variety + * of operations on this set, and usually a second set. The + * setScanner() method of the main SparseBitSet class + * essentially finds matching level3 blocks, and then calls the strategy to + * do the appropriate operation on each of the elements of the block. + *

        + * The symbolic constants control optimisation paths in the + * setScanner() method of the main SparseBitSet class. * - * @see SparseBitSet#setScanner(int i, int j, - * SparseBitSet b, AbstractStrategy op) + * @see SparseBitSet#setScanner(int i, int j, + * SparseBitSet b, AbstractStrategy op) */ - protected abstract class AbstractStrategy { - /** - * If the operation requires that when matching level2 areas or level3 - * blocks are null, that no action is required, then this property is - * required. Corresponds to the top-left entry in the logic diagram for the - * operation being 0. For all the defined actual logic operations ('and', - * 'andNot', 'or', and 'xor', this will be true, because for all these, - * "false" op "false" = "false". + protected abstract static class AbstractStrategy + { + /** If the operation requires that when matching level2 areas or level3 + * blocks are null, that no action is required, then this property is + * required. Corresponds to the top-left entry in the logic diagram for the + * operation being 0. For all the defined actual logic operations ('and', + * 'andNot', 'or', and 'xor', this will be true, because for all these, + * "false" op "false" = "false". */ static final int F_OP_F_EQ_F = 0x1; - /** - * If when level2 areas or level3 areas from the this set are null will - * require that area or block to remain null, irrespective of the value of - * the matching structure from the other set, then this property is required. - * Corresponds to the first row in the logic diagram being all zeros. For - * example, this is true for 'and' as well as 'andNot', and for 'clear', since - * false" & "x" = "false", and "false" &! "x" = "false". + /** If when level2 areas or level3 areas from the this set are null will + * require that area or block to remain null, irrespective of the value of + * the matching structure from the other set, then this property is required. + * Corresponds to the first row in the logic diagram being all zeros. For + * example, this is true for 'and' as well as 'andNot', and for 'clear', since + * false" & "x" = "false", and "false" &! "x" = "false". */ static final int F_OP_X_EQ_F = 0x2; - /** - * If when level2 areas or level3 areas from the other set are null will - * require the matching area or block in this set to be set to null, - * irrespective of the current values in the matching structure from the - * this, then this property is required. Corresponds to the first column - * in the logic diagram being all zero. For example, this is true for - * 'and', since "x" & "false" = "false", as well as for 'clear'. + /** If when level2 areas or level3 areas from the other set are null will + * require the matching area or block in this set to be set to null, + * irrespective of the current values in the matching structure from the + * this, then this property is required. Corresponds to the first column + * in the logic diagram being all zero. For example, this is true for + * 'and', since "x" & "false" = "false", as well as for 'clear'. */ static final int X_OP_F_EQ_F = 0x4; - /** - * If when a level3 area from the other set is null will require the - * matching area or block in this set to be left as it is, then this property - * is required. Corresponds to the first column of the logic diagram being - * equal to the left hand operand column. For example, this is true for 'or', - * 'xor', and 'andNot', since for all of these "x" op "false" = "x". + /** If when a level3 area from the other set is null will require the + * matching area or block in this set to be left as it is, then this property + * is required. Corresponds to the first column of the logic diagram being + * equal to the left hand operand column. For example, this is true for 'or', + * 'xor', and 'andNot', since for all of these "x" op "false" = "x". */ static final int X_OP_F_EQ_X = 0x8; /** - * Properties of this strategy. + * Properties of this strategy. * - * @return the int containing the bits representing the properties of - * this strategy - * @since 1.6 + * @return the int containing the bits representing the properties of + * this strategy + * @since 1.6 */ protected abstract int properties(); /** - * Instances of this class are to be serially reusable. To start a - * particular use, an instance is (re-)started by calling this method. It is - * passed the reference to the other bit set (usually to allow a check on - * whether it is null or not, so as to simplify the implementation of the - * block() method. + * Instances of this class are to be serially reusable. To start a + * particular use, an instance is (re-)started by calling this method. It is + * passed the reference to the other bit set (usually to allow a check on + * whether it is null or not, so as to simplify the implementation of the + * block() method. * - * @param b the "other" set, for whatever checking is needed. - * @since 1.6 + * @param b the "other" set, for whatever checking is needed. + * @since 1.6 + * @return true -> if the cache should be set to zero */ - protected abstract void start(SparseBitSet b); + protected abstract boolean start(SparseBitSet b); /** - * Deal with a scan that include a partial word within a level3 block. All - * that is required is that the result be stored (if needed) into the - * given a set block at the correct position, and that the operation only - * affect those bits selected by 1 bits in the mask. + * Deal with a scan that include a partial word within a level3 block. All + * that is required is that the result be stored (if needed) into the + * given a set block at the correct position, and that the operation only + * affect those bits selected by 1 bits in the mask. * - * @param base the base index of the block (to be used if needed) - * @param u3 the index of the word within block - * @param a3 the level3 block from the a set. - * @param b3 the (nominal) level3 block from the b set (not null). - * @param mask for the (partial) word - * @return true if the resulting word is zero - * @since 1.6 + * @param base the base index of the block (to be used if needed) + * @param u3 the index of the word within block + * @param a3 the level3 block from the a set. + * @param b3 the (nominal) level3 block from the b set (not null). + * @param mask for the (partial) word + * @return true if the resulting word is zero + * @since 1.6 */ - protected abstract boolean word(int base, int u3, long[] a3, long[] b3, long mask); /** - * Deals with a part of a block that consists of whole words, starting with - * the given first index, and ending with the word before the last index. - * For the words processed, the return value should indicate whether all those - * resulting words were zero, or not. + * Deals with a part of a block that consists of whole words, starting with + * the given first index, and ending with the word before the last index. + * For the words processed, the return value should indicate whether all those + * resulting words were zero, or not. * - * @param base the base index of the block (to be used if needed) - * @param u3 the index of the first word within block to process - * @param v3 the index of the last word, which may be within block - * @param a3 the level3 block from the a set. - * @param b3 the (nominal) level3 block from the b set (not null). - * @return true if the words scanned within the level3 block were all zero - * @since 1.6 + * @param base the base index of the block (to be used if needed) + * @param u3 the index of the first word within block to process + * @param v3 the index of the last word, which may be within block + * @param a3 the level3 block from the a set. + * @param b3 the (nominal) level3 block from the b set (not null). + * @return true if the words scanned within the level3 block were all zero + * @since 1.6 */ protected abstract boolean block(int base, int u3, int v3, long[] a3, long[] b3); /** - * This is called to finish the processing started by the strategy (if there - * needs to be anything done at all). + * This is called to finish the processing started by the strategy (if there + * needs to be anything done at all). * - * @param a2Count possible count of level2 areas in use - * @param a3Count possible count of level3 blocks in use - * @since 1.6 + * @param a2Count possible count of level2 areas in use + * @param a3Count possible count of level3 blocks in use + * @since 1.6 */ - protected void finish(int a2Count, int a3Count) { + protected void finish(int a2Count, int a3Count) + { } /** - * Check whether a level3 block is all zero. + * Check whether a level3 block is all zero. * - * @param a3 the block from the a set - * @return true if the values of the level3 block are all zero - * @since 1.6 + * @param a3 the block from the a set + * @return true if the values of the level3 block are all zero + * + * @since 1.6 */ - protected final boolean isZeroBlock(long[] a3) { + protected final boolean isZeroBlock(long[] a3) + { for (long word : a3) if (word != 0L) return false; @@ -2137,48 +2377,53 @@ public final class SparseBitSet implements Cloneable, Serializable { //============================================================================= /** - * And of two sets. Where the a set is zero, it remains zero (i.e., - * without entries or with zero words). Similarly, where the b set is - * zero, the a becomes zero (i.e., without entries). - *

        - * If level1 of the a set is longer than level1 of the bit set - * b, then the unmatched virtual "entries" of the b set (beyond - * the actual length of b) corresponding to these are all false, hence - * the result of the "and" operation will be to make all these entries in this - * set to become false--hence just remove them, and then scan only those - * entries that could match entries in the bit setb. This clearing of - * the remainder of the a set is accomplished by selecting both - * F_OP_X_EQ_F and X_OP_F_EQ_F. - *

        - *

        +     *  And of two sets. Where the a set is zero, it remains zero (i.e.,
        +     *  without entries or with zero words). Similarly, where the b set is
        +     *  zero, the a becomes zero (i.e., without entries).
        +     *  

        + * If level1 of the a set is longer than level1 of the bit set + * b, then the unmatched virtual "entries" of the b set (beyond + * the actual length of b) corresponding to these are all false, hence + * the result of the "and" operation will be to make all these entries in this + * set to become false--hence just remove them, and then scan only those + * entries that could match entries in the bit setb. This clearing of + * the remainder of the a set is accomplished by selecting both + * F_OP_X_EQ_F and X_OP_F_EQ_F. + * + *

              *  and| 0 1
              *    0| 0 0
              *    1| 0 1 
              */
        -    protected class AndStrategy extends AbstractStrategy {
        +    protected static class AndStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  AndStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + F_OP_X_EQ_F + X_OP_F_EQ_F;
                 }
         
                 @Override
                 //  AndStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
                         throw new NullPointerException();
        -            cache.hash = 0;
        +            return true;
                 }
         
                 @Override
                 //  AndStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] &= b3[u3] | ~mask) == 0L;
                 }
         
                 @Override
                 //  AndStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= ((a3[w3] &= b3[w3]) == 0L);
        @@ -2187,50 +2432,54 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * AndNot of two sets. Where the a set is zero, it remains zero
        -     * (i.e., without entries or with zero words). On the other hand, where the
        -     * b set is zero, the a remains unchanged.
        -     * 

        - * If level1 of the a set is longer than level1 of the bit set - * b, then the unmatched virtual "entries" of the b set (beyond - * the actual length of b) corresponding to these are all false, hence - * the result of the "and" operation will be to make all these entries in this - * set to become false--hence just remove them, and then scan only those - * entries that could match entries in the bit setb. This clearing of - * the remainder of the a set is accomplished by selecting both - * F_OP_X_EQ_F and X_OP_F_EQ_F. - *

        - *

        +     *  AndNot of two sets. Where the a set is zero, it remains zero
        +     *  (i.e., without entries or with zero words). On the other hand, where the
        +     *  b set is zero, the a remains unchanged.
        +     *  

        + * If level1 of the a set is longer than level1 of the bit set + * b, then the unmatched virtual "entries" of the b set (beyond + * the actual length of b) corresponding to these are all false, hence + * the result of the "and" operation will be to make all these entries in this + * set to become false--hence just remove them, and then scan only those + * entries that could match entries in the bit setb. This clearing of + * the remainder of the a set is accomplished by selecting both + * F_OP_X_EQ_F and X_OP_F_EQ_F. + * + *

              * andNot| 0 1
              *      0| 0 0
              *      1| 1 0 
              */
        -    protected class AndNotStrategy extends AbstractStrategy {
        +    protected static class AndNotStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  AndNotStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + F_OP_X_EQ_F + X_OP_F_EQ_X;
                 }
         
                 @Override
                 //  AndNotStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
                         throw new NullPointerException();
        -            cache.hash = 0;
        +            return true;
                 }
         
                 @Override
                 //  AndNotStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] &= ~(b3[u3] & mask)) == 0L;
                 }
         
                 @Override
                 //  AndNotStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= (a3[w3] &= ~b3[w3]) == 0L;
        @@ -2239,37 +2488,41 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Clear clears bits in the a set.
        -     * 

        + * Clear clears bits in the a set. + * *

              * clear| 0 1
              *     0| 0 0
              *     1| 0 0 
              */
        -    protected class ClearStrategy extends AbstractStrategy {
        +    protected static class ClearStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  ClearStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + F_OP_X_EQ_F;
                 }
         
                 @Override
                 //  ClearStrategy
        -        protected void start(SparseBitSet b) {
        -            cache.hash = 0;
        +        protected boolean start(SparseBitSet b)
        +        {
        +            return true;
                 }
         
                 @Override
                 //  ClearStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] &= ~mask) == 0L;
                 }
         
                 @Override
                 //  ClearStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     if (u3 != 0 || v3 != LENGTH3) //  Optimisation
                         for (int w3 = u3; w3 != v3; ++w3)
                             a3[w3] = 0L;
        @@ -2278,37 +2531,41 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Copies the needed parts of the b set to the a set.
        -     * 

        + * Copies the needed parts of the b set to the a set. + * *

              * get| 0 1
              *   0| 0 1
              *   1| 0 1 
              */
        -    protected class CopyStrategy extends AbstractStrategy {
        +    protected static class CopyStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  CopyStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + X_OP_F_EQ_F;
                 }
         
                 @Override
                 //  CopyStrategy
        -        protected void start(SparseBitSet b) {
        -            cache.hash = 0;
        +        protected boolean start(SparseBitSet b)
        +        {
        +            return true;
                 }
         
                 @Override
                 //  CopyStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] = b3[u3] & mask) == 0L;
                 }
         
                 @Override
                 //  CopyStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true;
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= (a3[w3] = b3[w3]) == 0L;
        @@ -2317,40 +2574,44 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Equals compares bits in the a set with those in the b set.
        -     * None of the values in either set are changed, although the a set
        -     * may have all zero level 3 blocks replaced by null references (and
        -     * similarly at level 2).
        -     * 

        + * Equals compares bits in the a set with those in the b set. + * None of the values in either set are changed, although the a set + * may have all zero level 3 blocks replaced by null references (and + * similarly at level 2). + * *

              * equals| 0 1
              *      0| 0 -
              *      1| - - 
              */
        -    protected class EqualsStrategy extends AbstractStrategy {
        +    protected static class EqualsStrategy extends AbstractStrategy
        +    {
                 boolean result; // Used to hold result of the comparison
         
                 @Override
                 //  EqualsStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F;
                 }
         
                 @Override
                 //  EqualsStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
        -                throw new InternalError();
        +                throw new NullPointerException();
                     result = true;
        +            return false;
                     /*  Equals does not change the content of the set, hence hash need
                         not be reset. */
                 }
         
                 @Override
                 //  EqualsStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     final long word = a3[u3];
                     result &= (word & mask) == (b3[u3] & mask);
                     return word == 0L;
        @@ -2358,10 +2619,12 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
                 @Override
                 //  EqualsStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
         
                     boolean isZero = true; //  Presumption
        -            for (int w3 = u3; w3 != v3; ++w3) {
        +            for (int w3 = u3; w3 != v3; ++w3)
        +            {
                         final long word = a3[w3];
                         result &= word == b3[w3];
                         isZero &= word == 0L;
        @@ -2371,37 +2634,41 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Flip inverts the bits of the a set within the given range.
        -     * 

        + * Flip inverts the bits of the a set within the given range. + * *

              * flip| 0 1
              *    0| 1 1
              *    1| 0 0 
              */
        -    protected class FlipStrategy extends AbstractStrategy {
        +    protected static class FlipStrategy extends AbstractStrategy
        +    {
                 @Override
                 // FlipStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return 0;
                 }
         
                 @Override
                 // FlipStrategy
        -        protected void start(SparseBitSet b) {
        -            cache.hash = 0;
        +        protected boolean start(SparseBitSet b)
        +        {
        +            return true;
                 }
         
                 @Override
                 // FlipStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] ^= mask) == 0L;
                 }
         
                 @Override
                 // FlipStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= (a3[w3] ^= ~0L) == 0L;
        @@ -2410,45 +2677,49 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Intersect has a true result if any word in the a set has a bit
        -     * in common with the b set. During the scan of the a set
        -     * blocks (and areas) that are all zero may be replaced with empty blocks
        -     * and areas (null references), but the value of the set is not changed
        -     * (which is why X_OP_F_EQ_F is not selected, since this would cause
        -     * parts of the a set to be zero-ed out).
        -     * 

        + * Intersect has a true result if any word in the a set has a bit + * in common with the b set. During the scan of the a set + * blocks (and areas) that are all zero may be replaced with empty blocks + * and areas (null references), but the value of the set is not changed + * (which is why X_OP_F_EQ_F is not selected, since this would cause + * parts of the a set to be zero-ed out). + * *

              * intersect| 0 1
              *         0| 0 0
              *         1| 1 1 
              */
        -    protected class IntersectsStrategy extends AbstractStrategy {
        +    protected static class IntersectsStrategy extends AbstractStrategy
        +    {
                 /**
        -         * The boolean result of the intersects scan Strategy is kept here.
        +         *  The boolean result of the intersects scan Strategy is kept here.
                  */
                 protected boolean result;
         
                 @Override
                 //  IntersectsStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + F_OP_X_EQ_F;
                 }
         
                 @Override
                 //  IntersectsStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
                         throw new NullPointerException();
                     result = false;
        +            return false;
                     /*  Intersect does not change the content of the set, hence hash
                         need not be reset. */
                 }
         
                 @Override
                 //  IntersectsStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     final long word = a3[u3];
                     result |= (word & b3[u3] & mask) != 0L;
                     return word == 0L;
        @@ -2456,9 +2727,11 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
                 @Override
                 //  IntersectsStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
        -            for (int w3 = u3; w3 != v3; ++w3) {
        +            for (int w3 = u3; w3 != v3; ++w3)
        +            {
                         final long word = a3[w3];
                         result |= (word & b3[w3]) != 0L;
                         isZero &= word == 0L;
        @@ -2468,43 +2741,48 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             /**
        -     * Or of two sets. Where the a set is one, it remains one. Similarly,
        -     * where the b set is one, the a becomes one. If both sets have
        -     * zeros in corresponding places, a zero results. Whole blocks or areas that
        -     * are or become zero are replaced by null arrays.
        -     * 

        - * If level1 of the a set is longer than level1 of the bit set - * b, then the unmatched entries of the a set (beyond - * the actual length of b) corresponding to these remain unchanged. * - *

        +     *  Or of two sets. Where the a set is one, it remains one. Similarly,
        +     *  where the b set is one, the a becomes one. If both sets have
        +     *  zeros in corresponding places, a zero results. Whole blocks or areas that
        +     *  are or become zero are replaced by null arrays.
        +     *  

        + * If level1 of the a set is longer than level1 of the bit set + * b, then the unmatched entries of the a set (beyond + * the actual length of b) corresponding to these remain unchanged. * + *

              *   or| 0 1
              *    0| 0 1
              *    1| 1 1 
              */
        -    protected class OrStrategy extends AbstractStrategy {
        +    protected static class OrStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  OrStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + X_OP_F_EQ_X;
                 }
         
                 @Override
                 //  OrStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
                         throw new NullPointerException();
        -            cache.hash = 0;
        +            return true;
                 }
         
                 @Override
                 //  OrStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] |= b3[u3] & mask) == 0L;
                 }
         
                 @Override
                 //  OrStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= (a3[w3] |= b3[w3]) == 0L;
        @@ -2513,40 +2791,44 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Set creates entries everywhere within the range. Hence no empty level2
        -     * areas or level3 blocks are ignored, and no empty (all zero) blocks are
        -     * returned.
        -     * 

        - *

        +     *  Set creates entries everywhere within the range. Hence no empty level2
        +     *  areas or level3 blocks are ignored, and no empty (all zero) blocks are
        +     *  returned.
        +     *
        +     *  
              * set| 0 1
              *   0| 1 1
              *   1| 1 1 
              */
        -    protected class SetStrategy extends AbstractStrategy {
        +    protected static class SetStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  SetStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return 0;
                 }
         
                 @Override
                 //  SetStrategy
        -        protected void start(SparseBitSet b) {
        -            cache.hash = 0;
        +        protected boolean start(SparseBitSet b)
        +        {
        +            return true;
                 }
         
                 @Override
                 //  SetStrategy
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     a3[u3] |= mask;
                     return false;
                 }
         
                 @Override
                 //  SetStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     for (int w3 = u3; w3 != v3; ++w3)
                         a3[w3] = ~0L;
                     return false; // set always sets bits
        @@ -2554,65 +2836,65 @@ public final class SparseBitSet implements Cloneable, Serializable {
             }
         
             //-----------------------------------------------------------------------------
        -
             /**
        -     * Update the seven statistics that are computed for each set. These are
        -     * updated by calling statisticsUpdate, which uses this strategy.
        -     * 

        - *

        +     *  Update the seven statistics that are computed for each set. These are
        +     *  updated by calling statisticsUpdate, which uses this strategy.
        +     *
        +     *  
              *  update| 0 1
              *       0| 0 0
              *       1| 1 1 
              *
              * @see SparseBitSet#statisticsUpdate()
              */
        -    protected class UpdateStrategy extends AbstractStrategy {
        +    protected class UpdateStrategy extends AbstractStrategy
        +    {
                 /**
        -         * Working space for find the size and length of the bit set. Holds the
        -         * index of the first non-empty word in the set.
        +         *  Working space for find the size and length of the bit set. Holds the
        +         *  index of the first non-empty word in the set.
                  */
                 protected transient int wMin;
         
                 /**
        -         * Working space for find the size and length of the bit set. Holds copy of
        -         * the first non-empty word in the set.
        +         *  Working space for find the size and length of the bit set. Holds copy of
        +         *  the first non-empty word in the set.
                  */
                 protected transient long wordMin;
         
                 /**
        -         * Working space for find the size and length of the bit set. Holds the
        -         * index of the last non-empty word in the set.
        +         *  Working space for find the size and length of the bit set. Holds the
        +         *  index of the last non-empty word in the set.
                  */
                 protected transient int wMax;
         
                 /**
        -         * Working space for find the size and length of the bit set. Holds a copy
        -         * of the last non-empty word in the set.
        +         *  Working space for find the size and length of the bit set. Holds a copy
        +         *  of the last non-empty word in the set.
                  */
                 protected transient long wordMax;
         
                 /**
        -         * Working space for find the hash value of the bit set. Holds the
        -         * current state of the computation of the hash value. This value is
        -         * ultimately transferred to the Cache object.
        +         *  Working space for find the hash value of the bit set. Holds the
        +         *  current state of the computation of the hash value. This value is
        +         *  ultimately transferred to the Cache object.
                  *
                  * @see SparseBitSet.Cache
                  */
                 protected transient long hash;
         
                 /**
        -         * Working space for keeping count of the number of non-zero words in the
        -         * bit set. Holds the current state of the computation of the count. This
        -         * value is ultimately transferred to the Cache object.
        +         *  Working space for keeping count of the number of non-zero words in the
        +         *  bit set. Holds the current state of the computation of the count. This
        +         *  value is ultimately transferred to the Cache object.
                  *
                  * @see SparseBitSet.Cache
                  */
                 protected transient int count;
         
                 /**
        -         * Working space for counting the number of non-zero bits in the bit set.
        -         * Holds the current state of the computation of the cardinality.This
        -         * value is ultimately transferred to the Cache object.
        +         *  Working space for counting the number of non-zero bits in the bit set.
        +         *  Holds the current state of the computation of the cardinality.This
        +         *  value is ultimately transferred to the Cache object.
                  *
                  * @see SparseBitSet.Cache
                  */
        @@ -2620,19 +2902,22 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
                 @Override
                 //  UpdateStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + F_OP_X_EQ_F;
                 }
         
                 /**
        -         * This method initializes the computations by suitably resetting cache
        -         * fields or working fields.
        +         *  This method initializes the computations by suitably resetting cache
        +         *  fields or working fields.
                  *
        -         * @param b the other SparseBitSet, for checking if needed.
        -         * @since 1.6
        +         * @param       b the other SparseBitSet, for checking if needed.
        +         *
        +         * @since       1.6
                  */
                 @Override
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     hash = 1234L; // Magic number
                     wMin = -1; // index of first non-zero word
                     wordMin = 0L; // word at that index
        @@ -2640,10 +2925,12 @@ public final class SparseBitSet implements Cloneable, Serializable {
                     wordMax = 0L; // word at that index
                     count = 0; // count of non-zero words in whole set
                     cardinality = 0; // count of non-zero bits in the whole set
        +            return false;
                 }
         
                 @Override
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     final long word = a3[u3];
                     final long word1 = word & mask;
                     if (word1 != 0L)
        @@ -2653,11 +2940,14 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
                 @Override
                 //  UpdateStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
        -            for (int w3 = 0; w3 != v3; ++w3) {
        +            for (int w3 = 0; w3 != v3; ++w3)
        +            {
                         final long word = a3[w3];
        -                if (word != 0) {
        +                if (word != 0)
        +                {
                             isZero = false;
                             compute(base + w3, word);
                         }
        @@ -2667,38 +2957,41 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
                 @Override
                 //  UpdateStrategy
        -        protected void finish(int a2Count, int a3Count) {
        +        protected void finish(int a2Count, int a3Count)
        +        {
                     cache.a2Count = a2Count;
                     cache.a3Count = a3Count;
                     cache.count = count;
                     cache.cardinality = cardinality;
                     cache.length = (wMax + 1) * LENGTH4 - Long.numberOfLeadingZeros(wordMax);
                     cache.size = cache.length - wMin * LENGTH4
        -                    - Long.numberOfTrailingZeros(wordMin);
        +                - Long.numberOfTrailingZeros(wordMin);
                     cache.hash = (int) ((hash >> Integer.SIZE) ^ hash);
                 }
         
                 /**
        -         * This method does the accumulation of the statistics. It must be called
        -         * in sequential order of the words in the set for which the statistics
        -         * are being accumulated, and only for non-null values of the second
        -         * parameter.
        -         * 

        - * Two of the values (a2Count and a3Count) are not updated here, - * but are done in the code near where this method is called. + * This method does the accumulation of the statistics. It must be called + * in sequential order of the words in the set for which the statistics + * are being accumulated, and only for non-null values of the second + * parameter. * - * @param index the word index of the word supplied - * @param word the long non-zero word from the set - * @since 1.6 + * Two of the values (a2Count and a3Count) are not updated here, + * but are done in the code near where this method is called. + * + * @param index the word index of the word supplied + * @param word the long non-zero word from the set + * @since 1.6 */ - private void compute(final int index, final long word) { + private void compute(final int index, final long word) + { /* Count the number of actual words being used. */ ++count; - /* Contine to accumulate the hash value of the set. */ + /* Continue to accumulate the hash value of the set. */ hash ^= word * (long) (index + 1); /* The first non-zero word contains the first actual bit of the set. The location of this bit is used to compute the set size. */ - if (wMin < 0) { + if (wMin < 0) + { wMin = index; wordMin = word; } @@ -2712,38 +3005,42 @@ public final class SparseBitSet implements Cloneable, Serializable { } //----------------------------------------------------------------------------- - /** - * The XOR of level3 blocks is computed. - *

        + * The XOR of level3 blocks is computed. + * *

              * xor| 0 1
              *   0| 0 1
              *   1| 1 0 
              */
        -    protected class XorStrategy extends AbstractStrategy {
        +    protected static class XorStrategy extends AbstractStrategy
        +    {
                 @Override
                 //  XorStrategy
        -        protected int properties() {
        +        protected int properties()
        +        {
                     return F_OP_F_EQ_F + X_OP_F_EQ_X;
                 }
         
                 @Override
                 //  XorStrategy
        -        protected void start(SparseBitSet b) {
        +        protected boolean start(SparseBitSet b)
        +        {
                     if (b == null)
                         throw new NullPointerException();
        -            cache.hash = 0;
        +            return true;
                 }
         
                 @Override
        -        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask) {
        +        protected boolean word(int base, int u3, long[] a3, long[] b3, long mask)
        +        {
                     return (a3[u3] ^= b3[u3] & mask) == 0;
                 }
         
                 @Override
                 //  XorStrategy
        -        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3) {
        +        protected boolean block(int base, int u3, int v3, long[] a3, long[] b3)
        +        {
                     boolean isZero = true; //  Presumption
                     for (int w3 = u3; w3 != v3; ++w3)
                         isZero &= (a3[w3] ^= b3[w3]) == 0;
        @@ -2754,47 +3051,47 @@ public final class SparseBitSet implements Cloneable, Serializable {
         
             //-----------------------------------------------------------------------------
             /**
        -     * Word and block and strategy.
        +     *  Word and block and strategy.
              */
        -    protected transient AndStrategy andStrategy;
        +    protected static final transient AndStrategy andStrategy = new AndStrategy();
             /**
        -     * Word and block andNot strategy.
        +     *  Word and block andNot strategy.
              */
        -    protected transient AndNotStrategy andNotStrategy;
        +    protected static final transient AndNotStrategy andNotStrategy = new AndNotStrategy();
             /**
        -     * Word and block clear strategy.
        +     *  Word and block clear strategy.
              */
        -    protected transient ClearStrategy clearStrategy;
        +    protected static final transient ClearStrategy clearStrategy = new ClearStrategy();
             /**
        -     * Word and block copy strategy.
        +     *  Word and block copy strategy.
              */
        -    protected transient CopyStrategy copyStrategy;
        +    protected static final transient CopyStrategy copyStrategy = new CopyStrategy();
             /**
        -     * Word and block equals strategy.
        +     *  Word and block equals strategy.
              */
             protected transient EqualsStrategy equalsStrategy;
             /**
        -     * Word and block flip strategy.
        +     *  Word and block flip strategy.
              */
        -    protected transient FlipStrategy flipStrategy;
        +    protected static final transient FlipStrategy flipStrategy = new FlipStrategy();
             /**
        -     * Word and block intersects strategy.
        +     *  Word and block intersects strategy.
              */
        -    protected transient IntersectsStrategy intersectsStrategy;
        +    protected static transient IntersectsStrategy intersectsStrategy = new IntersectsStrategy();
             /**
        -     * Word and block or strategy.
        +     *  Word and block or strategy.
              */
        -    protected transient OrStrategy orStrategy;
        +    protected static final transient OrStrategy orStrategy = new OrStrategy();
             /**
        -     * Word and block set strategy.
        +     *  Word and block set strategy.
              */
        -    protected transient SetStrategy setStrategy;
        +    protected static final transient SetStrategy setStrategy = new SetStrategy();
             /**
        -     * Word and block update strategy.
        +     *  Word and block update strategy.
              */
             protected transient UpdateStrategy updateStrategy;
             /**
        -     * Word and block xor strategy.
        +     *  Word and block xor strategy.
              */
        -    protected transient XorStrategy xorStrategy;
        +    protected static final transient XorStrategy xorStrategy = new XorStrategy();
         }
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/pattern/AbstractExtentPattern.java b/worldedit-core/src/main/java/com/boydti/fawe/object/pattern/AbstractExtentPattern.java
        index 47c63dd05..1990bb18d 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/object/pattern/AbstractExtentPattern.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/pattern/AbstractExtentPattern.java
        @@ -6,7 +6,8 @@ import com.sk89q.worldedit.extent.Extent;
         import com.sk89q.worldedit.function.pattern.AbstractPattern;
         
         public abstract class AbstractExtentPattern extends AbstractPattern {
        -    private transient final Extent extent;
        +
        +    private final transient Extent extent;
         
             public AbstractExtentPattern(Extent extent) {
                 checkNotNull(extent);
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
        index 3756975fb..02bb87d4e 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweLocalBlockQueue.java
        @@ -18,7 +18,6 @@ import com.sk89q.worldedit.world.block.BaseBlock;
         import com.sk89q.worldedit.world.block.BlockState;
         import com.sk89q.worldedit.world.registry.BiomeRegistry;
         import com.sk89q.worldedit.world.registry.LegacyMapper;
        -
         import java.util.Collection;
         
         // TODO FIXME
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
        index bfa9dd5c5..ac39c26ea 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/FaweSchematicHandler.java
        @@ -24,8 +24,6 @@ import com.sk89q.worldedit.extent.clipboard.Clipboard;
         import com.sk89q.worldedit.extent.clipboard.io.SpongeSchematicWriter;
         import com.sk89q.worldedit.math.BlockVector3;
         import com.sk89q.worldedit.regions.CuboidRegion;
        -import net.jpountz.lz4.LZ4BlockInputStream;
        -
         import java.io.BufferedOutputStream;
         import java.io.File;
         import java.io.FileNotFoundException;
        @@ -36,6 +34,7 @@ import java.net.URL;
         import java.util.Map;
         import java.util.Set;
         import java.util.UUID;
        +import net.jpountz.lz4.LZ4BlockInputStream;
         
         public class FaweSchematicHandler extends SchematicHandler {
             @Override
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java
        index ab921d992..41c211d1f 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/MoveTo512.java
        @@ -1,39 +1,8 @@
         package com.boydti.fawe.regions.general.plot;
         
        -import com.boydti.fawe.Fawe;
        -import com.boydti.fawe.example.NullFaweChunk;
        -import com.boydti.fawe.jnbt.anvil.MCAChunk;
        -import com.boydti.fawe.jnbt.anvil.MCAQueue;
        -import com.boydti.fawe.jnbt.anvil.MCAWriter;
        -import com.boydti.fawe.object.FaweChunk;
        -import com.boydti.fawe.beta.IQueueExtent;
        -import com.boydti.fawe.util.SetQueue;
        -import com.github.intellectualsites.plotsquared.commands.Command;
         import com.github.intellectualsites.plotsquared.commands.CommandDeclaration;
        -import com.github.intellectualsites.plotsquared.configuration.ConfigurationSection;
        -import com.github.intellectualsites.plotsquared.plot.PlotSquared;
         import com.github.intellectualsites.plotsquared.plot.commands.CommandCategory;
        -import com.github.intellectualsites.plotsquared.plot.commands.MainCommand;
         import com.github.intellectualsites.plotsquared.plot.commands.RequiredType;
        -import com.github.intellectualsites.plotsquared.plot.config.Captions;
        -import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
        -import com.github.intellectualsites.plotsquared.plot.database.SQLManager;
        -import com.github.intellectualsites.plotsquared.plot.generator.HybridPlotWorld;
        -import com.github.intellectualsites.plotsquared.plot.object.Location;
        -import com.github.intellectualsites.plotsquared.plot.object.Plot;
        -import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
        -import com.github.intellectualsites.plotsquared.plot.object.PlotId;
        -import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
        -import com.github.intellectualsites.plotsquared.plot.object.RunnableVal2;
        -import com.github.intellectualsites.plotsquared.plot.object.RunnableVal3;
        -import com.github.intellectualsites.plotsquared.plot.object.SetupObject;
        -import com.github.intellectualsites.plotsquared.plot.util.SetupUtils;
        -import com.github.intellectualsites.plotsquared.plot.util.WorldUtil;
        -import java.io.File;
        -import java.io.IOException;
        -import java.util.ArrayList;
        -import java.util.Arrays;
        -import java.util.Map;
         
         @CommandDeclaration(
                 command = "moveto512",
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotRegionFilter.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotRegionFilter.java
        index ffade473b..d69ce516f 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotRegionFilter.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotRegionFilter.java
        @@ -1,16 +1,14 @@
         package com.boydti.fawe.regions.general.plot;
         
        +import static com.google.common.base.Preconditions.checkNotNull;
        +
         import com.boydti.fawe.regions.general.CuboidRegionFilter;
         import com.github.intellectualsites.plotsquared.plot.object.Location;
         import com.github.intellectualsites.plotsquared.plot.object.Plot;
         import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
         import com.sk89q.worldedit.math.BlockVector2;
        -
         import java.util.ArrayList;
         
        -
        -import static com.google.common.base.Preconditions.checkNotNull;
        -
         public class PlotRegionFilter extends CuboidRegionFilter {
             private final PlotArea area;
         
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSetBiome.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSetBiome.java
        index 679204b04..36e7e6d9b 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSetBiome.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSetBiome.java
        @@ -27,10 +27,8 @@ import com.sk89q.worldedit.world.biome.BiomeType;
         import com.sk89q.worldedit.world.biome.BiomeTypes;
         import com.sk89q.worldedit.world.biome.Biomes;
         import com.sk89q.worldedit.world.registry.BiomeRegistry;
        -
         import java.util.Collection;
         import java.util.HashSet;
        -import java.util.List;
         import java.util.concurrent.ThreadLocalRandom;
         
         @CommandDeclaration(
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
        index 713bd9849..9c980a93a 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/regions/general/plot/PlotSquaredFeature.java
        @@ -13,6 +13,7 @@ import com.github.intellectualsites.plotsquared.plot.config.Settings;
         import com.github.intellectualsites.plotsquared.plot.database.DBFunc;
         import com.github.intellectualsites.plotsquared.plot.flag.Flags;
         import com.github.intellectualsites.plotsquared.plot.generator.HybridPlotManager;
        +import com.github.intellectualsites.plotsquared.plot.listener.WEManager;
         import com.github.intellectualsites.plotsquared.plot.object.Plot;
         import com.github.intellectualsites.plotsquared.plot.object.PlotArea;
         import com.github.intellectualsites.plotsquared.plot.object.PlotPlayer;
        @@ -22,7 +23,6 @@ import com.github.intellectualsites.plotsquared.plot.util.SchematicHandler;
         import com.github.intellectualsites.plotsquared.plot.util.UUIDHandler;
         import com.github.intellectualsites.plotsquared.plot.util.block.GlobalBlockQueue;
         import com.github.intellectualsites.plotsquared.plot.util.block.QueueProvider;
        -import com.github.intellectualsites.plotsquared.plot.listener.WEManager;
         import com.sk89q.worldedit.math.BlockVector3;
         import com.sk89q.worldedit.regions.CuboidRegion;
         import com.sk89q.worldedit.regions.Region;
        diff --git a/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java b/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java
        index e978949e9..ef3fa7a7a 100644
        --- a/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java
        +++ b/worldedit-core/src/main/java/com/boydti/fawe/util/TextureUtil.java
        @@ -17,8 +17,6 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
         import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
         import it.unimi.dsi.fastutil.ints.IntArraySet;
         import it.unimi.dsi.fastutil.longs.LongArrayList;
        -
        -import javax.imageio.ImageIO;
         import java.awt.image.BufferedImage;
         import java.io.File;
         import java.io.FileNotFoundException;
        @@ -41,50 +39,11 @@ import java.util.concurrent.ConcurrentHashMap;
         import java.util.regex.Pattern;
         import java.util.zip.ZipEntry;
         import java.util.zip.ZipFile;
        +import javax.imageio.ImageIO;
         
         // TODO FIXME
         public class TextureUtil implements TextureHolder {
         
        -    public static TextureUtil fromClipboard(Clipboard clipboard) throws FileNotFoundException {
        -        boolean[] ids = new boolean[BlockTypes.size()];
        -        for (BlockVector3 pt : clipboard.getRegion()) {
        -            ids[clipboard.getBlock(pt).getInternalBlockTypeId()] = true;
        -        }
        -        HashSet blocks = new HashSet<>();
        -        for (int typeId = 0; typeId < ids.length; typeId++) {
        -            if (ids[typeId]) {
        -                blocks.add(BlockTypes.get(typeId));
        -            }
        -        }
        -        return fromBlocks(blocks);
        -    }
        -
        -    public static TextureUtil fromBlocks(Set blocks) throws FileNotFoundException {
        -        return new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks);
        -    }
        -
        -    public static TextureUtil fromMask(Mask mask) throws FileNotFoundException {
        -        HashSet blocks = new HashSet<>();
        -
        -        SingleFilterBlock extent = new SingleFilterBlock();
        -        new MaskTraverser(mask).reset(extent);
        -
        -        TextureUtil tu = Fawe.get().getTextureUtil();
        -        for (int typeId : tu.getValidBlockIds()) {
        -            BlockType block = BlockTypes.get(typeId);
        -            extent.init(0, 0, 0, block.getDefaultState().toBaseBlock());
        -            if (mask.test(extent)) {
        -                blocks.add(block);
        -            }
        -        }
        -        return fromBlocks(blocks);
        -    }
        -
        -    @Override public TextureUtil getTextureUtil() {
        -        return this;
        -    }
        -
        -    private final File folder;
             private static final int[] FACTORS = new int[766];
         
             static {
        @@ -93,23 +52,21 @@ public class TextureUtil implements TextureHolder {
                 }
             }
         
        +    private final File folder;
             protected int[] blockColors = new int[BlockTypes.size()];
             protected long[] blockDistance = new long[BlockTypes.size()];
             protected long[] distances;
             protected int[] validColors;
             protected int[] validBlockIds;
        -
             protected int[] validLayerColors;
             protected int[][] validLayerBlocks;
        -
             protected int[] validMixBiomeColors;
             protected long[] validMixBiomeIds;
        -
             /**
              * https://github.com/erich666/Mineways/blob/master/Win/biomes.cpp
              */
             protected BiomeColor[] validBiomes;
        -    private BiomeColor[] biomes = new BiomeColor[] {
        +    private BiomeColor[] biomes = new BiomeColor[]{
                 //    ID    Name             Temperature, rainfall, grass, foliage colors
                 //    - note: the colors here are just placeholders, they are computed in the program
                 new BiomeColor(0, "ocean", 0.5f, 0.5f, 0x92BD59, 0x77AB2F),
        @@ -373,6 +330,7 @@ public class TextureUtil implements TextureHolder {
                 new BiomeColor(253, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
                 new BiomeColor(254, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),
                 new BiomeColor(255, "Unknown Biome", 0.8f, 0.4f, 0x92BD59, 0x77AB2F),};
        +    private BlockType[] layerBuffer = new BlockType[2];
         
             public TextureUtil() throws FileNotFoundException {
                 this(MainUtil.getFile(Fawe.imp().getDirectory(), Settings.IMP.PATHS.TEXTURES));
        @@ -386,6 +344,61 @@ public class TextureUtil implements TextureHolder {
                 }
             }
         
        +    public static TextureUtil fromClipboard(Clipboard clipboard) throws FileNotFoundException {
        +        boolean[] ids = new boolean[BlockTypes.size()];
        +        for (BlockVector3 pt : clipboard.getRegion()) {
        +            ids[clipboard.getBlock(pt).getInternalBlockTypeId()] = true;
        +        }
        +        HashSet blocks = new HashSet<>();
        +        for (int typeId = 0; typeId < ids.length; typeId++) {
        +            if (ids[typeId]) {
        +                blocks.add(BlockTypes.get(typeId));
        +            }
        +        }
        +        return fromBlocks(blocks);
        +    }
        +
        +    public static TextureUtil fromBlocks(Set blocks) throws FileNotFoundException {
        +        return new FilteredTextureUtil(Fawe.get().getTextureUtil(), blocks);
        +    }
        +
        +    public static TextureUtil fromMask(Mask mask) throws FileNotFoundException {
        +        HashSet blocks = new HashSet<>();
        +
        +        SingleFilterBlock extent = new SingleFilterBlock();
        +        new MaskTraverser(mask).reset(extent);
        +
        +        TextureUtil tu = Fawe.get().getTextureUtil();
        +        for (int typeId : tu.getValidBlockIds()) {
        +            BlockType block = BlockTypes.get(typeId);
        +            extent.init(0, 0, 0, block.getDefaultState().toBaseBlock());
        +            if (mask.test(extent)) {
        +                blocks.add(block);
        +            }
        +        }
        +        return fromBlocks(blocks);
        +    }
        +
        +    protected static int hueDistance(int red1, int green1, int blue1, int red2, int green2,
        +        int blue2) {
        +        int total1 = (red1 + green1 + blue1);
        +        int total2 = (red2 + green2 + blue2);
        +        if (total1 == 0 || total2 == 0) {
        +            return 0;
        +        }
        +        int factor1 = FACTORS[total1];
        +        int factor2 = FACTORS[total2];
        +        long r = (512 * (red1 * factor1 - red2 * factor2)) >> 10;
        +        long g = (green1 * factor1 - green2 * factor2);
        +        long b = (767 * (blue1 * factor1 - blue2 * factor2)) >> 10;
        +        return (int) ((r * r + g * g + b * b) >> 25);
        +    }
        +
        +    @Override
        +    public TextureUtil getTextureUtil() {
        +        return this;
        +    }
        +
             public BlockType getNearestBlock(int color) {
                 long min = Long.MAX_VALUE;
                 int closest = 0;
        @@ -440,8 +453,6 @@ public class TextureUtil implements TextureHolder {
                 return BlockTypes.get(closest);
             }
         
        -    private BlockType[] layerBuffer = new BlockType[2];
        -
             /**
              * Returns the block combined ids as an array
              *
        @@ -887,7 +898,7 @@ public class TextureUtil implements TextureHolder {
                             if (!hasAlpha(colorOther)) {
                                 int combinedOther = validBlockIds[j];
                                 int combinedColor = combineTransparency(color, colorOther);
        -                        colorLayerMap.put(combinedColor, new int[] {combined, combinedOther});
        +                        colorLayerMap.put(combinedColor, new int[]{combined, combinedOther});
                             }
                         }
                     }
        @@ -975,21 +986,6 @@ public class TextureUtil implements TextureHolder {
                     * hd);
             }
         
        -    protected static int hueDistance(int red1, int green1, int blue1, int red2, int green2,
        -        int blue2) {
        -        int total1 = (red1 + green1 + blue1);
        -        int total2 = (red2 + green2 + blue2);
        -        if (total1 == 0 || total2 == 0) {
        -            return 0;
        -        }
        -        int factor1 = FACTORS[total1];
        -        int factor2 = FACTORS[total2];
        -        long r = (512 * (red1 * factor1 - red2 * factor2)) >> 10;
        -        long g = (green1 * factor1 - green2 * factor2);
        -        long b = (767 * (blue1 * factor1 - blue2 * factor2)) >> 10;
        -        return (int) ((r * r + g * g + b * b) >> 25);
        -    }
        -
             public long getDistance(BufferedImage image, int c1) {
                 long totalDistSqr = 0;
                 int width = image.getWidth();
        @@ -1008,7 +1004,12 @@ public class TextureUtil implements TextureHolder {
                 return totalDistSqr / area;
             }
         
        +    public int[] getValidBlockIds() {
        +        return validBlockIds.clone();
        +    }
        +
             public static class BiomeColor {
        +
                 public int id;
                 public String name;
                 public float temperature;
        @@ -1028,8 +1029,4 @@ public class TextureUtil implements TextureHolder {
                     this.foliage = foliage;
                 }
             }
        -
        -    public int[] getValidBlockIds() {
        -        return validBlockIds.clone();
        -    }
         }
        diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
        index c070e7cdf..f8b5971b9 100644
        --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
        +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/platform/AbstractPlayerActor.java
        @@ -45,13 +45,12 @@ import com.sk89q.worldedit.world.item.ItemType;
         import com.sk89q.worldedit.world.item.ItemTypes;
         import com.sk89q.worldedit.world.registry.BlockMaterial;
         
        -import javax.annotation.Nullable;
         import java.io.File;
        +import javax.annotation.Nullable;
         
         /**
        - * An abstract implementation of both a {@link Actor} and a {@link Player}
        - * that is intended for implementations of WorldEdit to use to wrap
        - * players that make use of WorldEdit.
        + * An abstract implementation of both a {@link Actor} and a {@link Player} that is intended for
        + * implementations of WorldEdit to use to wrap players that make use of WorldEdit.
          */
         public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
         
        @@ -94,10 +93,10 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
             public boolean isHoldingPickAxe() {
                 ItemType item = getItemInHand(HandSide.MAIN_HAND).getType();
                 return item == ItemTypes.IRON_PICKAXE
        -                || item == ItemTypes.WOODEN_PICKAXE
        -                || item == ItemTypes.STONE_PICKAXE
        -                || item == ItemTypes.DIAMOND_PICKAXE
        -                || item == ItemTypes.GOLDEN_PICKAXE;
        +            || item == ItemTypes.WOODEN_PICKAXE
        +            || item == ItemTypes.STONE_PICKAXE
        +            || item == ItemTypes.DIAMOND_PICKAXE
        +            || item == ItemTypes.GOLDEN_PICKAXE;
             }
         
             @Override
        @@ -111,7 +110,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
         
                 BlockVector3 mutablePos = MutableBlockVector3.ZERO;
                 while (y <= world.getMaximumPoint().getBlockY() + 2) {
        -            if (!world.getBlock(mutablePos.setComponents(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
        +            if (!world.getBlock(mutablePos.setComponents(x, y, z)).getBlockType().getMaterial()
        +                .isMovementBlocker()) {
                         ++free;
                     } else {
                         free = 0;
        @@ -120,7 +120,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                     if (free == 2) {
                         final BlockVector3 pos = mutablePos.setComponents(x, y - 2, z);
                         final BlockStateHolder state = world.getBlock(pos);
        -                setPosition(new Location(world, Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5)));
        +                setPosition(new Location(world,
        +                    Vector3.at(x + 0.5, y - 2 + BlockTypeUtil.centralTopLimit(state), z + 0.5)));
                         return;
                     }
         
        @@ -139,7 +140,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                     final BlockVector3 pos = BlockVector3.at(x, y, z);
                     final BlockState id = world.getBlock(pos);
                     if (id.getBlockType().getMaterial().isMovementBlocker()) {
        -                setPosition(new Location(world, Vector3.at(x + 0.5, y + + BlockTypeUtil.centralTopLimit(id), z + 0.5)));
        +                setPosition(new Location(world,
        +                    Vector3.at(x + 0.5, y + +BlockTypeUtil.centralTopLimit(id), z + 0.5)));
                         return;
                     }
         
        @@ -161,7 +163,9 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                 final Extent world = pos.getExtent();
         
                 int maxY = world.getMaxY();
        -        if (y >= maxY) return false;
        +        if (y >= maxY) {
        +            return false;
        +        }
         
                 BlockMaterial initialMaterial = world.getBlock(BlockVector3.at(x, y, z)).getMaterial();
         
        @@ -172,8 +176,11 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
         
                 for (int level = y + 1; level <= maxY + 2; level++) {
                     BlockState state;
        -            if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
        -            else state = world.getBlock(BlockVector3.at(x, level, z));
        +            if (level >= maxY) {
        +                state = BlockTypes.VOID_AIR.getDefaultState();
        +            } else {
        +                state = world.getBlock(BlockVector3.at(x, level, z));
        +            }
                     BlockType type = state.getBlockType();
                     BlockMaterial material = type.getMaterial();
         
        @@ -218,14 +225,19 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                 boolean lastState = initialMaterial.isMovementBlocker() && initialMaterial.isFullCube();
         
                 int maxY = world.getMaxY();
        -        if (y <= 2) return false;
        +        if (y <= 2) {
        +            return false;
        +        }
         
                 double freeEnd = -1;
                 double height = 1.85;
                 for (int level = y + 1; level > 0; level--) {
                     BlockState state;
        -            if (level >= maxY) state = BlockTypes.VOID_AIR.getDefaultState();
        -            else state = world.getBlock(BlockVector3.at(x, level, z));
        +            if (level >= maxY) {
        +                state = BlockTypes.VOID_AIR.getDefaultState();
        +            } else {
        +                state = world.getBlock(BlockVector3.at(x, level, z));
        +            }
                     BlockType type = state.getBlockType();
                     BlockMaterial material = type.getMaterial();
         
        @@ -279,7 +291,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
         
                 while (y <= world.getMaximumPoint().getY()) {
                     // Found a ceiling!
        -            if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
        +            if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial()
        +                .isMovementBlocker()) {
                         int platformY = Math.max(initialY, y - 3 - clearance);
                         floatAt(x, platformY + 1, z, alwaysGlass);
                         return true;
        @@ -307,7 +320,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                 final Extent world = getLocation().getExtent();
         
                 while (y <= world.getMaximumPoint().getY() + 2) {
        -            if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial().isMovementBlocker()) {
        +            if (world.getBlock(BlockVector3.at(x, y, z)).getBlockType().getMaterial()
        +                .isMovementBlocker()) {
                         break; // Hit something
                     } else if (y > maxY + 1) {
                         break;
        @@ -326,7 +340,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
             public void floatAt(int x, int y, int z, boolean alwaysGlass) {
                 try {
                     BlockVector3 spot = BlockVector3.at(x, y - 1, z);
        -            if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial().isMovementBlocker()) {
        +            if (!getLocation().getExtent().getBlock(spot).getBlockType().getMaterial()
        +                .isMovementBlocker()) {
                         getLocation().getExtent().setBlock(spot, BlockTypes.GLASS.getDefaultState());
                     }
                 } catch (WorldEditException e) {
        @@ -342,7 +357,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
         
             @Override
             public Location getBlockOn() {
        -        return getLocation().setPosition(getLocation().setY(getLocation().getY() - 1).toVector().floor());
        +        return getLocation()
        +            .setPosition(getLocation().setY(getLocation().getY() - 1).toVector().floor());
             }
         
             @Override
        @@ -433,7 +449,8 @@ public abstract class AbstractPlayerActor implements Actor, Player, Cloneable {
                 boolean inFree = false;
         
                 while ((block = hitBlox.getNextBlock()) != null) {
        -            boolean free = !world.getBlock(block.toVector().toBlockPoint()).getBlockType().getMaterial().isMovementBlocker();
        +            boolean free = !world.getBlock(block.toVector().toBlockPoint()).getBlockType()
        +                .getMaterial().isMovementBlocker();
         
                     if (firstBlock) {
                         firstBlock = false;
        diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java
        index e6fe6aec7..3399cb9cd 100644
        --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java
        +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/snapshot/SnapshotRepository.java
        @@ -22,8 +22,6 @@
         package com.sk89q.worldedit.world.snapshot;
         
         import com.sk89q.worldedit.world.storage.MissingWorldException;
        -
        -import javax.annotation.Nullable;
         import java.io.File;
         import java.io.FilenameFilter;
         import java.time.ZoneOffset;
        @@ -33,6 +31,7 @@ import java.util.Calendar;
         import java.util.Collections;
         import java.util.List;
         import java.util.Locale;
        +import javax.annotation.Nullable;
         
         /**
          * A repository contains zero or more snapshots.
        @@ -67,13 +66,13 @@ public class SnapshotRepository {
             }
         
             /**
        -     * Get a list of snapshots in a directory. The newest snapshot is
        -     * near the top of the array.
        +     * Get a list of snapshots in a directory. The newest snapshot is near the top of the array.
              *
              * @param newestFirst true to get the newest first
              * @return a list of snapshots
              */
        -    public List getSnapshots(boolean newestFirst, String worldName) throws MissingWorldException {
        +    public List getSnapshots(boolean newestFirst, String worldName)
        +        throws MissingWorldException {
                 FilenameFilter filter = (dir, name) -> {
                     File f = new File(dir, name);
                     return isValidSnapshot(f);
        @@ -117,7 +116,8 @@ public class SnapshotRepository {
              * @return a snapshot or null
              */
             @Nullable
        -    public Snapshot getSnapshotAfter(ZonedDateTime date, String world) throws MissingWorldException {
        +    public Snapshot getSnapshotAfter(ZonedDateTime date, String world)
        +        throws MissingWorldException {
                 List snapshots = getSnapshots(true, world);
                 Snapshot last = null;
         
        @@ -139,7 +139,8 @@ public class SnapshotRepository {
              * @return a snapshot or null
              */
             @Nullable
        -    public Snapshot getSnapshotBefore(ZonedDateTime date, String world) throws MissingWorldException {
        +    public Snapshot getSnapshotBefore(ZonedDateTime date, String world)
        +        throws MissingWorldException {
                 List snapshots = getSnapshots(false, world);
                 Snapshot last = null;
         
        @@ -205,7 +206,8 @@ public class SnapshotRepository {
              * @return whether it is a valid snapshot
              */
             protected boolean isValidSnapshot(File file) {
        -        if (!file.getName().matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) {
        +        if (!file.getName()
        +            .matches("^[A-Za-z0-9_\\- \\./\\\\'\\$@~!%\\^\\*\\(\\)\\[\\]\\+\\{\\},\\?]+$")) {
                     return false;
                 }