001: /*
002:
003: Derby - Class com.ihost.cs.JBitSet
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.util;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import java.util.BitSet;
027:
028: /**
029: * JBitSet is a wrapper class for BitSet. It is a fixed length implementation
030: * which can be extended via the grow() method. It provides additional
031: * methods to manipulate BitSets.
032: * NOTE: JBitSet was driven by the (current and perceived) needs of the
033: * optimizer, but placed in the util package since it is not specific to
034: * query trees..
035: * NOTE: java.util.BitSet is final, so we must provide a wrapper class
036: * which includes a BitSet member in order to extend the functionality.
037: * We want to make it look like JBitSet extends BitSet, so we need to
038: * provide wrapper methods for all of BitSet's methods.
039: *
040: * @author Jerry Brenner
041: */
042: public final class JBitSet {
043: /* The BitSet that we'd like to extend */
044: private final BitSet bitSet;
045: /* Cache size() of bitSet, since accessed a lot */
046: private int size;
047:
048: /**
049: * Construct a JBitSet of the specified size.
050: *
051: * @param size The number of bits in the JBitSet.
052: */
053: public JBitSet(int size) {
054: bitSet = new BitSet(size);
055: this .size = size;
056: }
057:
058: /**
059: * Construct a JBitSet with the specified bitSet.
060: *
061: * @param bitSet The BitSet.
062: * @param size The size of bitSet.
063: * NOTE: We need to specify the size since the size of a
064: * BitSet is not guaranteed to be the same as JBitSet.size().
065: */
066: private JBitSet(BitSet bitSet, int size) {
067: this .bitSet = bitSet;
068: this .size = size;
069: }
070:
071: /**
072: * Set the BitSet to have the exact same bits set as the parameter's BitSet.
073: *
074: * @param sourceBitSet The JBitSet to copy.
075: */
076: public void setTo(JBitSet sourceBitSet) {
077: if (SanityManager.DEBUG) {
078: SanityManager.ASSERT(size == sourceBitSet.size(),
079: "JBitSets are expected to be the same size");
080: }
081: /* High reuse solution */
082: and(sourceBitSet);
083: or(sourceBitSet);
084: }
085:
086: /**
087: * Test to see if one JBitSet contains another one of
088: * the same size.
089: *
090: * @param jBitSet JBitSet that we want to know if it is
091: * a subset of current JBitSet
092: *
093: * @return boolean Whether or not jBitSet is a subset.
094: */
095: public boolean contains(JBitSet jBitSet) {
096: if (SanityManager.DEBUG) {
097: SanityManager.ASSERT(size == jBitSet.size(),
098: "JBitSets are expected to be the same size");
099: }
100: for (int bitIndex = 0; bitIndex < size; bitIndex++) {
101: if (jBitSet.bitSet.get(bitIndex) && !(bitSet.get(bitIndex))) {
102: return false;
103: }
104: }
105: return true;
106: }
107:
108: /**
109: * See of a JBitSet has exactly 1 bit set.
110: *
111: * @return boolean Whether or not JBitSet has a single bit set.
112: */
113: public boolean hasSingleBitSet() {
114: boolean found = false;
115:
116: for (int bitIndex = 0; bitIndex < size; bitIndex++) {
117: if (bitSet.get(bitIndex)) {
118: if (found) {
119: return false;
120: } else {
121: found = true;
122: }
123: }
124: }
125:
126: return found;
127: }
128:
129: /**
130: * Get the first set bit (starting at index 0) from a JBitSet.
131: *
132: * @return int Index of first set bit, -1 if none set.
133: */
134: public int getFirstSetBit() {
135: for (int bitIndex = 0; bitIndex < size; bitIndex++) {
136: if (bitSet.get(bitIndex)) {
137: return bitIndex;
138: }
139: }
140:
141: return -1;
142: }
143:
144: /**
145: * Grow an existing JBitSet to the specified size.
146: *
147: * @param newSize The new size
148: *
149: */
150: public void grow(int newSize) {
151: if (SanityManager.DEBUG) {
152: SanityManager
153: .ASSERT(newSize > size,
154: "New size is expected to be larger than current size");
155: }
156:
157: size = newSize;
158:
159: }
160:
161: /**
162: * Clear all of the bits in this JBitSet
163: */
164: public void clearAll() {
165: for (int bitIndex = 0; bitIndex < size; bitIndex++) {
166: if (bitSet.get(bitIndex)) {
167: bitSet.clear(bitIndex);
168: }
169: }
170: }
171:
172: /* Wrapper methods for BitSet's methods */
173: public String toString() {
174: return bitSet.toString();
175: }
176:
177: public boolean equals(Object obj) {
178: if (SanityManager.DEBUG) {
179: SanityManager.ASSERT((obj instanceof JBitSet),
180: "obj is expected to be a JBitSet " + obj);
181: }
182: return bitSet.equals(((JBitSet) obj).bitSet);
183: }
184:
185: public int hashCode() {
186: return bitSet.hashCode();
187: }
188:
189: public Object clone() {
190: return new JBitSet((BitSet) bitSet.clone(), size);
191: }
192:
193: public boolean get(int bitIndex) {
194: return bitSet.get(bitIndex);
195: }
196:
197: public void set(int bitIndex) {
198: bitSet.set(bitIndex);
199: }
200:
201: public void clear(int bitIndex) {
202: bitSet.clear(bitIndex);
203: }
204:
205: public void and(JBitSet set) {
206: bitSet.and(set.bitSet);
207: }
208:
209: public void or(JBitSet set) {
210: bitSet.or(set.bitSet);
211: }
212:
213: public void xor(JBitSet set) {
214: bitSet.xor(set.bitSet);
215: }
216:
217: /**
218: * Return the size of bitSet
219: *
220: * @return int Size of bitSet
221: */
222: public int size() {
223: return size;
224: }
225: }
|