001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.common;
012:
013: import com.versant.core.metadata.ClassMetaData;
014: import com.versant.core.metadata.ModelMetaData;
015: import com.versant.core.metadata.MDStatics;
016:
017: /**
018: * This is a set type Container for ClassMetaData.
019: * It is based on the index of the ClassMetaData.
020: */
021: public final class CmdBitSet {
022: private static final ClassMetaData[] EMPTY_CMDS = new ClassMetaData[0];
023: private final int[] bitSet;
024: private final ModelMetaData jmd;
025: private int size;
026: private boolean cacheble = true;
027:
028: public CmdBitSet(ModelMetaData jmd) {
029: bitSet = new int[(jmd.classes.length / 32) + 1];
030: this .jmd = jmd;
031: }
032:
033: public boolean isCacheble() {
034: return cacheble;
035: }
036:
037: /**
038: * set the bit for the supplied ClassMetaData and its subclasses.
039: */
040: public void addPlus(ClassMetaData cmd) {
041: if ((bitSet[(cmd.index / 32)] & (1 << (cmd.index % 32))) == 0) {
042: bitSet[(cmd.index / 32)] |= (1 << (cmd.index % 32));
043: if (cmd.cacheStrategy == MDStatics.CACHE_STRATEGY_NO)
044: cacheble = false;
045: size++;
046: }
047: if (cmd.pcSubclasses != null) {
048: final ClassMetaData[] subs = cmd.pcSubclasses;
049: for (int k = subs.length - 1; k >= 0; k--) {
050: addPlus(subs[k]);
051: }
052: }
053: }
054:
055: /**
056: * set the bit for the supplied ClassMetaData.
057: */
058: public boolean add(ClassMetaData cmd) {
059: if ((bitSet[(cmd.index / 32)] & (1 << (cmd.index % 32))) == 0) {
060: bitSet[(cmd.index / 32)] |= (1 << (cmd.index % 32));
061: if (cmd.cacheStrategy == MDStatics.CACHE_STRATEGY_NO)
062: cacheble = false;
063: size++;
064: return true;
065: }
066: return false;
067: }
068:
069: public boolean remove(ClassMetaData cmd) {
070: if ((bitSet[(cmd.index / 32)] & (1 << (cmd.index % 32))) == 0) {
071: bitSet[(cmd.index / 32)] ^= (1 << (cmd.index % 32));
072: size--;
073: return true;
074: }
075: return false;
076: }
077:
078: /**
079: * Return a ClassMetaData array of the classes which index's has been set set on the bitSet.
080: */
081: public ClassMetaData[] toArray() {
082: if (size == 0)
083: return EMPTY_CMDS;
084: final ClassMetaData[] cmds = new ClassMetaData[size];
085: int count = 0;
086: for (int i = 0; i < bitSet.length; i++) {
087: int val = bitSet[i];
088: for (int bit = 0; bit < 32; bit++) {
089: if ((val & (1 << bit)) != 0) {
090: cmds[count++] = jmd.classes[bit + (i * 32)];
091: if (count == size)
092: return cmds;
093: }
094: }
095: }
096: return cmds;
097: }
098:
099: /**
100: * Return a int[] array of the class indexes set on the bitSet.
101: */
102: public int[] getIndexes() {
103: if (size == 0)
104: return null;
105: final int[] indexes = new int[size];
106: int count = 0;
107: for (int i = 0; i < bitSet.length; i++) {
108: int val = bitSet[i];
109: for (int bit = 0; bit < 32; bit++) {
110: if ((val & (1 << bit)) != 0) {
111: indexes[count++] = bit + (i * 32);
112: if (count == size)
113: return indexes;
114: }
115: }
116: }
117: return indexes;
118: }
119:
120: /**
121: * Return a ClassMetaData array if all the classes in the bitSet is cacheble.
122: */
123: public ClassMetaData[] toArrayIfCacheble() {
124: if (!cacheble)
125: return null;
126: if (size == 0)
127: return null;
128: final ClassMetaData[] cmds = new ClassMetaData[size];
129: int count = 0;
130: for (int i = 0; i < bitSet.length; i++) {
131: int val = bitSet[i];
132: for (int bit = 0; bit < 32; bit++) {
133: if ((val & (1 << bit)) != 0) {
134: ClassMetaData cmd = jmd.classes[bit + (i * 32)];
135: if (cmd.cacheStrategy == MDStatics.CACHE_STRATEGY_NO)
136: return null;
137: cmds[count++] = cmd;
138: if (count == size)
139: return cmds;
140: }
141: }
142: }
143: return cmds;
144: }
145:
146: public void clear() {
147: for (int i = bitSet.length - 1; i >= 0; i--) {
148: bitSet[i] = 0;
149: }
150: size = 0;
151: }
152:
153: public boolean contains(ClassMetaData cmd) {
154: return (bitSet[(cmd.index / 32)] & (1 << (cmd.index % 32))) != 0;
155: }
156:
157: public boolean containsAny(int[] bits) {
158: return CmdBitSet.containsAny(bitSet, bits);
159: }
160:
161: public static boolean contains(ClassMetaData cmd, int[] bits) {
162: return (bits[(cmd.index / 32)] & (1 << (cmd.index % 32))) != 0;
163: }
164:
165: public boolean contains(ClassMetaData[] cmds) {
166: for (int i = cmds.length - 1; i >= 0; i--) {
167: if (contains(cmds[i]))
168: return true;
169: }
170: return false;
171: }
172:
173: public static boolean contains(ClassMetaData[] cmds, int[] bits) {
174: for (int i = cmds.length - 1; i >= 0; i--) {
175: if (contains(cmds[i], bits))
176: return true;
177: }
178: return false;
179: }
180:
181: public static int[] createFor(ClassMetaData[] cmds,
182: ModelMetaData jdm) {
183: final CmdBitSet cmdBits = new CmdBitSet(jdm);
184: if (cmds != null) {
185: for (int i = 0; i < cmds.length; i++) {
186: cmdBits.add(cmds[i]);
187: }
188: }
189: return cmdBits.getBits();
190: }
191:
192: /**
193: * This will check if the supplied src int[] contain any of the bits of the
194: * data array.
195: */
196: public static boolean containsAny(int[] src, int[] data) {
197: for (int i = 0; i < src.length; i++) {
198: if ((src[i] & data[i]) != 0)
199: return true;
200: }
201: return false;
202: }
203:
204: /**
205: * This returns the actual int[] used by the instance.
206: * DO NO MODIFY IT.
207: */
208: public int[] getBits() {
209: return bitSet;
210: }
211: }
|