PageRenderTime 26ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/tags/release-4_8_6/src/groove/abstraction/neigh/equiv/NodeEquivClass.java

https://bitbucket.org/wthys/groove
Java | 277 lines | 164 code | 32 blank | 81 comment | 14 complexity | 69b346fb52da7cf07f46207286b93b73 MD5 | raw file
  1. /* GROOVE: GRaphs for Object Oriented VErification
  2. * Copyright 2003--2007 University of Twente
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing,
  10. * software distributed under the License is distributed on an
  11. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  12. * either express or implied. See the License for the specific
  13. * language governing permissions and limitations under the License.
  14. *
  15. * $Id$
  16. */
  17. package groove.abstraction.neigh.equiv;
  18. import groove.grammar.host.HostElement;
  19. import groove.grammar.host.HostFactory;
  20. import groove.grammar.host.HostNode;
  21. import java.lang.reflect.Array;
  22. import java.util.BitSet;
  23. import java.util.Collection;
  24. import java.util.Iterator;
  25. /**
  26. * An equivalence class implementation for nodes (both from host graphs and
  27. * shapes). This class is implemented as bit set instead of a hash set for
  28. * efficiency. Node numbers are used as indices in the bit set, so in order to
  29. * keep the objects of this class small, it is necessary that the number of
  30. * nodes in the store also be small.
  31. *
  32. * @author Eduardo Zambon
  33. */
  34. public final class NodeEquivClass<T extends HostNode> extends BitSet implements
  35. EquivClass<T> {
  36. // ------------------------------------------------------------------------
  37. // Object Fields
  38. // ------------------------------------------------------------------------
  39. /** Flag for indicating if the equivalence class is fixed. */
  40. private boolean fixed;
  41. /**
  42. * Simple counter to avoid the need to go over the whole set to discover
  43. * its size.
  44. */
  45. private int elemCount;
  46. /** Factory reference used to retrieve node objects. */
  47. private final HostFactory factory;
  48. // ------------------------------------------------------------------------
  49. // Constructors
  50. // ------------------------------------------------------------------------
  51. /** Basic constructor. */
  52. public NodeEquivClass(HostFactory factory) {
  53. super();
  54. this.factory = factory;
  55. this.elemCount = 0;
  56. }
  57. // ------------------------------------------------------------------------
  58. // Overridden methods
  59. // ------------------------------------------------------------------------
  60. @Override
  61. public boolean setFixed() {
  62. boolean result = !isFixed();
  63. if (result) {
  64. this.fixed = true;
  65. }
  66. return result;
  67. }
  68. @Override
  69. public boolean isFixed() {
  70. return this.fixed;
  71. }
  72. @Override
  73. public void testFixed(boolean fixed) {
  74. if (this.isFixed() != fixed) {
  75. throw new IllegalStateException();
  76. }
  77. }
  78. /**
  79. * Specialises the return type of the super method.
  80. * Shallow clone. Clones the equivalence class but not the elements.
  81. * The clone is not fixed, even if the original is.
  82. */
  83. @Override
  84. @SuppressWarnings("unchecked")
  85. public NodeEquivClass<T> clone() {
  86. NodeEquivClass<T> clone = (NodeEquivClass<T>) super.clone();
  87. clone.fixed = false;
  88. return clone;
  89. }
  90. /** Creates and returns a new iterator for elements of this class. */
  91. @Override
  92. public Iterator<T> iterator() {
  93. return new MyIterator();
  94. }
  95. /** Fast containment check based on element numbers. */
  96. @Override
  97. public boolean contains(Object o) {
  98. boolean result = false;
  99. if (o instanceof HostElement) {
  100. int idx = ((HostElement) o).getNumber();
  101. result = this.get(idx);
  102. }
  103. return result;
  104. }
  105. /** Creates and returns a new array with all elements of this class. */
  106. @Override
  107. public Object[] toArray() {
  108. Object result[] = new Object[this.elemCount];
  109. int i = 0;
  110. for (Object obj : this) {
  111. result[i] = obj;
  112. i++;
  113. }
  114. return result;
  115. }
  116. /**
  117. * Stores the elements of this class in the given array, if possible.
  118. * Otherwise creates and returns a new array.
  119. */
  120. @Override
  121. @SuppressWarnings({"hiding", "unchecked"})
  122. public <T> T[] toArray(T[] a) {
  123. if (a.length < this.elemCount) {
  124. a =
  125. (T[]) Array.newInstance(a.getClass().getComponentType(),
  126. this.elemCount);
  127. }
  128. int i = 0;
  129. for (Object obj : this) {
  130. a[i] = (T) obj;
  131. i++;
  132. }
  133. return a;
  134. }
  135. /** Checks the containment for all elements of the given collection. */
  136. @Override
  137. public boolean containsAll(Collection<?> c) {
  138. boolean result = true;
  139. for (Object obj : c) {
  140. result &= this.contains(obj);
  141. if (!result) {
  142. break;
  143. }
  144. }
  145. return result;
  146. }
  147. /**
  148. * Adds all elements of the given collection to the equivalence class.
  149. * Fails in an assertion if the class is fixed.
  150. */
  151. @Override
  152. public boolean addAll(Collection<? extends T> c) {
  153. assert !this.isFixed();
  154. boolean changed = false;
  155. for (T obj : c) {
  156. changed |= this.add(obj);
  157. }
  158. return changed;
  159. }
  160. /** Throws an UnsupportedOperationException. */
  161. @Override
  162. public boolean retainAll(Collection<?> c) {
  163. throw new UnsupportedOperationException();
  164. }
  165. /**
  166. * Removes all elements of the given collection from the equivalence class.
  167. * Fails in an assertion if the class is fixed.
  168. */
  169. @Override
  170. public boolean removeAll(Collection<?> c) {
  171. assert !this.isFixed();
  172. boolean changed = false;
  173. for (Object obj : c) {
  174. changed |= this.remove(obj);
  175. }
  176. return changed;
  177. }
  178. /**
  179. * Sets the bit indexed by the object number.
  180. * Fails in an assertion if the class is fixed.
  181. */
  182. @Override
  183. public boolean add(T obj) {
  184. assert !this.isFixed();
  185. int idx = obj.getNumber();
  186. if (!this.get(idx)) {
  187. this.set(idx);
  188. this.elemCount++;
  189. return true;
  190. }
  191. return false;
  192. }
  193. /**
  194. * Clears the bit indexed by the object number.
  195. * Fails in an assertion if the class is fixed.
  196. */
  197. @Override
  198. public boolean remove(Object obj) {
  199. assert !this.isFixed();
  200. assert obj instanceof HostElement;
  201. int idx = ((HostElement) obj).getNumber();
  202. if (this.get(idx)) {
  203. this.clear(idx);
  204. this.elemCount--;
  205. return true;
  206. }
  207. return false;
  208. }
  209. @Override
  210. public int size() {
  211. return this.elemCount;
  212. }
  213. @Override
  214. public boolean isSingleton() {
  215. return this.elemCount == 1;
  216. }
  217. // ------------------------------------------------------------------------
  218. // Inner classes
  219. // ------------------------------------------------------------------------
  220. /**
  221. * Dedicated iterator for node equivalence classes.
  222. *
  223. * @author Eduardo Zambon
  224. */
  225. private class MyIterator implements Iterator<T> {
  226. /** The number of the node that should be returned by next(). */
  227. private int curr = NodeEquivClass.this.nextSetBit(0);
  228. @Override
  229. public boolean hasNext() {
  230. return this.curr >= 0;
  231. }
  232. /** Returns the current node and computes the next one. */
  233. @Override
  234. @SuppressWarnings("unchecked")
  235. public T next() {
  236. T elem = (T) NodeEquivClass.this.factory.getNode(this.curr);
  237. this.curr = NodeEquivClass.this.nextSetBit(this.curr + 1);
  238. return elem;
  239. }
  240. @Override
  241. public void remove() {
  242. throw new UnsupportedOperationException();
  243. }
  244. }
  245. }