--- /dev/null
+/*\r
+\r
+ Derby - Class com.ihost.cs.JBitSet\r
+\r
+ Licensed to the Apache Software Foundation (ASF) under one or more\r
+ contributor license agreements. See the NOTICE file distributed with\r
+ this work for additional information regarding copyright ownership.\r
+ The ASF licenses this file to you under the Apache License, Version 2.0\r
+ (the "License"); you may not use this file except in compliance with\r
+ the License. You may obtain a copy of the License at\r
+\r
+ http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+ Unless required by applicable law or agreed to in writing, software\r
+ distributed under the License is distributed on an "AS IS" BASIS,\r
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ See the License for the specific language governing permissions and\r
+ limitations under the License.\r
+\r
+ */\r
+\r
+package org.apache.derby.iapi.util;\r
+\r
+import org.apache.derby.iapi.services.sanity.SanityManager;\r
+\r
+import java.util.BitSet;\r
+\r
+/**\r
+ * JBitSet is a wrapper class for BitSet. It is a fixed length implementation\r
+ * which can be extended via the grow() method. It provides additional\r
+ * methods to manipulate BitSets.\r
+ * NOTE: JBitSet was driven by the (current and perceived) needs of the\r
+ * optimizer, but placed in the util package since it is not specific to\r
+ * query trees..\r
+ * NOTE: java.util.BitSet is final, so we must provide a wrapper class\r
+ * which includes a BitSet member in order to extend the functionality.\r
+ * We want to make it look like JBitSet extends BitSet, so we need to\r
+ * provide wrapper methods for all of BitSet's methods.\r
+ *\r
+ */\r
+public final class JBitSet\r
+{\r
+ /* The BitSet that we'd like to extend */\r
+ private final BitSet bitSet;\r
+ /* Cache size() of bitSet, since accessed a lot */\r
+ private int size;\r
+\r
+ /**\r
+ * Construct a JBitSet of the specified size.\r
+ *\r
+ * @param size The number of bits in the JBitSet.\r
+ */\r
+ public JBitSet(int size)\r
+ {\r
+ bitSet = new BitSet(size);\r
+ this.size = size;\r
+ }\r
+\r
+ /**\r
+ * Construct a JBitSet with the specified bitSet.\r
+ *\r
+ * @param bitSet The BitSet.\r
+ * @param size The size of bitSet.\r
+ * NOTE: We need to specify the size since the size of a\r
+ * BitSet is not guaranteed to be the same as JBitSet.size().\r
+ */\r
+ private JBitSet(BitSet bitSet, int size)\r
+ {\r
+ this.bitSet = bitSet;\r
+ this.size = size;\r
+ }\r
+\r
+ /**\r
+ * Set the BitSet to have the exact same bits set as the parameter's BitSet.\r
+ *\r
+ * @param sourceBitSet The JBitSet to copy.\r
+ */\r
+ public void setTo(JBitSet sourceBitSet)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(size == sourceBitSet.size(),\r
+ "JBitSets are expected to be the same size");\r
+ }\r
+ /* High reuse solution */\r
+ and(sourceBitSet);\r
+ or(sourceBitSet);\r
+ }\r
+\r
+ /**\r
+ * Test to see if one JBitSet contains another one of\r
+ * the same size.\r
+ *\r
+ * @param jBitSet JBitSet that we want to know if it is\r
+ * a subset of current JBitSet\r
+ *\r
+ * @return boolean Whether or not jBitSet is a subset.\r
+ */\r
+ public boolean contains(JBitSet jBitSet)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(size == jBitSet.size(),\r
+ "JBitSets are expected to be the same size");\r
+ }\r
+ for (int bitIndex = 0; bitIndex < size; bitIndex++)\r
+ {\r
+ if (jBitSet.bitSet.get(bitIndex) && ! (bitSet.get(bitIndex)))\r
+ {\r
+ return false;\r
+ }\r
+ }\r
+ return true;\r
+ }\r
+\r
+ /**\r
+ * See of a JBitSet has exactly 1 bit set.\r
+ *\r
+ * @return boolean Whether or not JBitSet has a single bit set.\r
+ */\r
+ public boolean hasSingleBitSet()\r
+ {\r
+ boolean found = false;\r
+\r
+ for (int bitIndex = 0; bitIndex < size; bitIndex++)\r
+ {\r
+ if (bitSet.get(bitIndex))\r
+ {\r
+ if (found)\r
+ {\r
+ return false;\r
+ }\r
+ else\r
+ {\r
+ found = true;\r
+ }\r
+ }\r
+ }\r
+\r
+ return found;\r
+ }\r
+\r
+ /**\r
+ * Get the first set bit (starting at index 0) from a JBitSet.\r
+ *\r
+ * @return int Index of first set bit, -1 if none set.\r
+ */\r
+ public int getFirstSetBit()\r
+ {\r
+ for (int bitIndex = 0; bitIndex < size; bitIndex++)\r
+ {\r
+ if (bitSet.get(bitIndex))\r
+ {\r
+ return bitIndex;\r
+ }\r
+ }\r
+\r
+ return -1;\r
+ }\r
+\r
+ /**\r
+ * Grow an existing JBitSet to the specified size.\r
+ *\r
+ * @param newSize The new size\r
+ *\r
+ */\r
+ public void grow(int newSize)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT(newSize > size,\r
+ "New size is expected to be larger than current size");\r
+ }\r
+\r
+ size = newSize;\r
+\r
+ }\r
+\r
+ /**\r
+ * Clear all of the bits in this JBitSet\r
+ */\r
+ public void clearAll()\r
+ {\r
+ for (int bitIndex = 0; bitIndex < size; bitIndex++)\r
+ {\r
+ if (bitSet.get(bitIndex))\r
+ {\r
+ bitSet.clear(bitIndex);\r
+ }\r
+ }\r
+ }\r
+\r
+ /* Wrapper methods for BitSet's methods */\r
+ public String toString()\r
+ {\r
+ return bitSet.toString();\r
+ }\r
+\r
+ public boolean equals(Object obj)\r
+ {\r
+ if (SanityManager.DEBUG)\r
+ {\r
+ SanityManager.ASSERT((obj instanceof JBitSet),\r
+ "obj is expected to be a JBitSet " + obj);\r
+ }\r
+ return bitSet.equals(((JBitSet) obj).bitSet);\r
+ }\r
+\r
+ public int hashCode()\r
+ {\r
+ return bitSet.hashCode();\r
+ }\r
+\r
+ public Object clone()\r
+ {\r
+ return new JBitSet((BitSet) bitSet.clone(), size);\r
+ }\r
+\r
+ public boolean get(int bitIndex)\r
+ {\r
+ return bitSet.get(bitIndex);\r
+ }\r
+\r
+ public void set(int bitIndex)\r
+ {\r
+ bitSet.set(bitIndex);\r
+ }\r
+\r
+ public void clear(int bitIndex)\r
+ {\r
+ bitSet.clear(bitIndex);\r
+ }\r
+\r
+ public void and(JBitSet set)\r
+ {\r
+ bitSet.and(set.bitSet);\r
+ }\r
+\r
+ public void or(JBitSet set)\r
+ {\r
+ bitSet.or(set.bitSet);\r
+ }\r
+\r
+ public void xor(JBitSet set)\r
+ {\r
+ bitSet.xor(set.bitSet);\r
+ }\r
+\r
+ /**\r
+ * Return the size of bitSet\r
+ *\r
+ * @return int Size of bitSet\r
+ */\r
+ public int size()\r
+ {\r
+ return size;\r
+ }\r
+}\r
+\r