@Deprecated @operator( value = {"copy_between" /* , "copy" */}, can_be_const = true, content_type = ITypeProvider.FIRST_CONTENT_TYPE, category = {IOperatorCategory.LIST}) @doc(deprecated = "Deprecated. Use copy_between(list, int, int) instead") public static IList copy_between(final IScope scope, final IList l1, final GamaPoint p) { return Containers.copy_between(scope, l1, (int) nullCheck(scope, p).x, (int) p.y); }
@Test public void should_Place_Container_In_JFrame_Without_Showing() { FrameFixture frameFixture = null; try { frameFixture = Containers.frameFixtureFor(robot, panel); frameFixture.requireNotVisible(); assertThat(frameFixture.target()).isNotNull(); } finally { cleanUp(frameFixture); } }
@operator( value = {"collate"}, content_type = ITypeProvider.FIRST_ELEMENT_CONTENT_TYPE) @doc( deprecated = "The idiom 'collate' is considered as deprecated. Please use 'interleave' instead.", value = "a new list containing the interleaved elements of the containers contained in the operand", comment = "the operand should be a list of lists of elements. The result is a list of elements. ", examples = { @example("interleave([1,2,4,3,5,7,6,8]) --: [1,2,3,4,5,7,6,8]"), @example( "interleave([['e11','e12','e13'],['e21','e22','e23'],['e31','e32','e33']]) --: [e11,e21,e31,e12,e22,e32,e13,e23,e33]") }) @Deprecated public static IList collate(final IScope scope, final IContainer cc) { return Containers.interleave(scope, cc); // final Iterator it = new Guava.InterleavingIterator(toArray(nullCheck(scope, // cc).iterable(scope), Object.class)); // return GamaListFactory.create(Iterators.toArray(it, Object.class), Types.NO_TYPE); }
/** @author Jiri Rechtacek, Radek Matous */ public class UpdateTableModel extends UnitCategoryTableModel { // just prevents from gc, do not delete private OperationContainer<InstallSupport> container = Containers.forUpdate(); private OperationContainer<OperationSupport> containerCustom = Containers.forCustomInstall(); private static String col0, col1, col2; /** * Creates a new instance of UpdateTableModel * * @param units */ public UpdateTableModel(List<UpdateUnit> units) { setUnits(units); } public final void setUnits(List<UpdateUnit> units) { setData(Utilities.makeUpdateCategories(units, false)); } @Override public void setValueAt(Object anValue, int row, int col) { if (isExpansionControlAtRow(row)) return; // NOI18N // second column is editable but doesn't want to edit its value if (col == 1) { return; } super.setValueAt(anValue, row, col); Unit u = getUnitAtRow(row); assert anValue instanceof Boolean : anValue + " must be instanceof Boolean."; boolean beforeMarked = u.isMarked(); if ((Boolean) anValue != beforeMarked) { u.setMarked(!beforeMarked); if (u.isMarked() != beforeMarked) { fireButtonsChange(); } else { // TODO: message should contain spec.version String message = NbBundle.getMessage( UpdateTableModel.class, "NotificationAlreadyPreparedToIntsall", u.getDisplayName()); // NOI18N DialogDisplayer.getDefault().notify(new NotifyDescriptor.Message(message)); } } } public Object getValueAt(int row, int col) { Object res = null; if (isExpansionControlAtRow(row)) return ""; // NOI18N Unit u = getUnitAtRow(row); switch (col) { case 0: res = u.isMarked() ? Boolean.TRUE : Boolean.FALSE; break; case 1: res = u.getDisplayName(); break; case 2: res = u.getCategoryName(); break; } return res; } public int getColumnCount() { return 3; } public Class getColumnClass(int c) { Class res = null; switch (c) { case 0: res = Boolean.class; break; case 1: res = DisplayName.class; break; case 2: res = String.class; break; } return res; } @Override public String getColumnName(int column) { switch (column) { case 0: if (col0 == null) { col0 = getBundle("UpdateTableModel_Columns_Update"); } return col0; case 1: if (col1 == null) { col1 = getBundle("UpdateTableModel_Columns_Name"); } return col1; case 2: if (col2 == null) { col2 = getBundle("UpdateTableModel_Columns_Category"); } return col2; } assert false; return super.getColumnName(column); } public int getPreferredWidth(JTableHeader header, int col) { final int minWidth = super.getMinWidth(header, col); switch (col) { case 1: return minWidth * 4; case 2: return minWidth * 2; } return minWidth; } public Type getType() { return UnitCategoryTableModel.Type.UPDATE; } public class DisplayName { public DisplayName(String name) {} } public boolean isSortAllowed(Object columnIdentifier) { boolean isUpdate = getColumnName(0).equals(columnIdentifier); return isUpdate ? false : true; } protected Comparator<Unit> getComparator( final Object columnIdentifier, final boolean sortAscending) { return new Comparator<Unit>() { public int compare(Unit o1, Unit o2) { Unit unit1 = sortAscending ? o1 : o2; Unit unit2 = sortAscending ? o2 : o1; if (getColumnName(0).equals(columnIdentifier)) { assert false : columnIdentifier.toString(); } else if (getColumnName(1).equals(columnIdentifier)) { return Unit.compareDisplayNames(unit1, unit2); } else if (getColumnName(2).equals(columnIdentifier)) { return Unit.compareCategories(unit1, unit2); } return 0; } }; } @SuppressWarnings("unchecked") public int getDownloadSize() { int res = 0; assert container != null || containerCustom != null : "OperationContainer found when asking for download size."; Set<OperationInfo> infos = new HashSet<OperationInfo>(); infos.addAll(container.listAll()); infos.addAll(containerCustom.listAll()); Set<UpdateElement> elements = new HashSet<UpdateElement>(); for (OperationInfo info : infos) { elements.add(info.getUpdateElement()); elements.addAll(info.getRequiredElements()); } for (UpdateElement el : elements) { res += el.getDownloadSize(); } return res; } private String getBundle(String key) { return NbBundle.getMessage(this.getClass(), key); } public String getTabTitle() { return NbBundle.getMessage( PluginManagerUI.class, "PluginManagerUI_UnitTab_Update_Title"); // NOI18N } @Override public String getTabTooltipText() { if (isTabEnabled()) { return super.getTabTooltipText(); } return NbBundle.getMessage(PluginManagerUI.class, "PluginManagerUI_UnitTab_Update_ToolTip"); } public int getTabIndex() { return PluginManagerUI.INDEX_OF_UPDATES_TAB; } @Override public boolean isTabEnabled() { return true; // getRawItemCount() > 0; } public boolean needsRestart() { return true; } }
/*! ${TemplateOptions.generatedAnnotation} !*/ public class KTypeHashSet<KType> extends AbstractKTypeCollection<KType> implements KTypeLookupContainer<KType>, KTypeSet<KType>, Cloneable { /** * Hash-indexed array holding all set entries. * * <p>Direct set iteration: iterate {keys[i]} for i in [0; keys.length[ where keys[i] != 0/null, * then also {0/null} is in the set if {@link #allocatedDefaultKey} = true. */ public /*! #if ($TemplateOptions.KTypePrimitive) KType [] #else !*/ Object[] /*! #end !*/ keys; /*! #if ($RH) !*/ /** * #if ($RH) Caches the hash value = hash(keys[i]) & mask, if keys[i] != 0/null, for every index * i. #end * * @see #assigned */ /*! #end !*/ /*! #if ($RH) !*/ protected int[] hash_cache; /*! #end !*/ /** True if key = 0/null is in the map. */ public boolean allocatedDefaultKey = false; /** Cached number of assigned slots in {@link #keys}. */ protected int assigned; /** * The load factor for this map (fraction of allocated slots before the buffers must be rehashed * or reallocated). */ protected final double loadFactor; /** Resize buffers when {@link #keys} hits this value. */ private int resizeAt; /** Per-instance perturbation introduced in rehashing to create a unique key distribution. */ private final int perturbation = Containers.randomSeed32(); /*! #if ($TemplateOptions.KTypeGeneric) !*/ /** * Override this method, together with {@link #equalKeys(Object, Object)} to customize the hashing * strategy. Note that this method is guaranteed to be called with a non-null key argument. By * default, this method calls key.{@link #hashCode()}. * * @param key KType to be hashed. * @return the hashed value of key, following the same semantic as {@link #hashCode()}; * @see #hashCode() * @see #equalKeys(Object, Object) */ protected int hashKey(final KType key) { // default maps on Object.hashCode() return key.hashCode(); } /** * Override this method together with {@link #hashKey(Object)} to customize the hashing strategy. * Note that this method is guaranteed to be called with both non-null arguments. By default, this * method calls a.{@link #equals(b)}. * * @param a not-null KType to be compared * @param b not-null KType to be compared * @return true if a and b are considered equal, following the same semantic as {@link * #equals(Object)}. * @see #equals(Object) * @see #hashKey(Object) */ protected boolean equalKeys(final KType a, final KType b) { // default maps on Object.equals() return Intrinsics.<KType>equalsNotNull(a, b); } /*! #end !*/ /** * Default constructor: Creates a hash set with the default capacity of {@link * Containers#DEFAULT_EXPECTED_ELEMENTS}, load factor of {@link * HashContainers#DEFAULT_LOAD_FACTOR}. */ public KTypeHashSet() { this(Containers.DEFAULT_EXPECTED_ELEMENTS, HashContainers.DEFAULT_LOAD_FACTOR); } /** * Creates a hash set with the given capacity, load factor of {@link * HashContainers#DEFAULT_LOAD_FACTOR}. */ public KTypeHashSet(final int initialCapacity) { this(initialCapacity, HashContainers.DEFAULT_LOAD_FACTOR); } /** Creates a hash set with the given capacity and load factor. */ public KTypeHashSet(final int initialCapacity, final double loadFactor) { this.loadFactor = loadFactor; // take into account of the load factor to guarantee no reallocations before reaching // initialCapacity. allocateBuffers(HashContainers.minBufferSize(initialCapacity, loadFactor)); } /** Creates a hash set from elements of another container. Default load factor is used. */ public KTypeHashSet(final KTypeContainer<KType> container) { this(container.size()); addAll(container); } /** {@inheritDoc} */ @Override public boolean add(KType key) { if (Intrinsics.<KType>isEmpty(key)) { if (this.allocatedDefaultKey) { return false; } this.allocatedDefaultKey = true; return true; } final int mask = this.keys.length - 1; final KType[] keys = Intrinsics.<KType[]>cast(this.keys); int slot = REHASH(key) & mask; KType existing; /*! #if ($RH) !*/ final int[] cached = this.hash_cache; KType tmpKey; int tmpAllocated; int initial_slot = slot; int dist = 0; int existing_distance = 0; /*! #if($DEBUG) !*/ final KType originalKey = key; /*! #end !*/ /*! #end !*/ while (!Intrinsics.<KType>isEmpty(existing = keys[slot])) { /*! #if ($RH) !*/ existing_distance = probe_distance(slot, cached); // When first entering the while loop, then key == original key to search. // So either: // 1) key is immediately found and the routine bail out, // or // 2) If the Robin-hood criteria of distance is not met, we search the next slot, (usual // linear probing) // or // 3) else the criteria of distance is met, then (key) is swapped with the ones in // slot position which becomes the new (key) to consider. This is OK because keys are swapped // only if dist > existing_distance, // i.e only if the key to add is NOT in the set, see contains(). So we steal the rich (a // previously entered key, favored because having being inserted // in a less crowed array) to give to the poor, the now inserted key. Then, we start searching // again in the next slot. /*! #if($DEBUG) !*/ // if the original key been swapped by the Robin-hood process, we actually never enter the // following if, so we are fine. if (!KEYEQUALS(key, originalKey)) { assert !KEYEQUALS(key, existing); } /*! #end !*/ /*! #end !*/ /*! #if($RH) !*/ // Robin-hood shortcut: if key exists, it can only be found in dist <= existing_distance // range. // indeed we should expect to never see an existing element with a shorter probe count // (existing_distance) // than our current count (dist): if that had happened, there would’ve been a swap during // insertion, see below. // also see contains() and remove() for the same trick. /*! #end !*/ if ( /*! #if ($RH) !*/ dist <= existing_distance && /*! #end !*/ KEYEQUALS(key, existing)) { return false; } /*! #if ($RH) !*/ // re-shuffle keys to minimize variance if (dist > existing_distance) { // we actually enter here only if the key to add is NOT in the set. // swap current (key, value, initial_slot) with slot places tmpKey = keys[slot]; keys[slot] = key; key = tmpKey; tmpAllocated = cached[slot]; cached[slot] = initial_slot; initial_slot = tmpAllocated; /*! #if($DEBUG) !*/ // Check invariants assert cached[slot] == (REHASH(keys[slot]) & mask); assert initial_slot == (REHASH(key) & mask); /*! #end !*/ dist = existing_distance; } /*! #end !*/ slot = (slot + 1) & mask; /*! #if ($RH) !*/ dist++; /*! #end !*/ } // Check if we need to grow. If so, reallocate new data, // fill in the last element and rehash. if (this.assigned == this.resizeAt) { expandAndAdd(key, slot); } else { this.assigned++; /*! #if ($RH) !*/ cached[slot] = initial_slot; /*! #end !*/ keys[slot] = key; /*! #if ($RH) !*/ /*! #if($DEBUG) !*/ // Check invariants assert cached[slot] == (REHASH(keys[slot]) & mask); /*! #end !*/ /*! #end !*/ } return true; } /** Adds two elements to the set. */ public int add(final KType e1, final KType e2) { int count = 0; if (add(e1)) { count++; } if (add(e2)) { count++; } return count; } /** * Vararg-signature method for adding elements to this set. * * <p><b>This method is handy, but costly if used in tight loops (anonymous array passing)</b> * * @return Returns the number of elements that were added to the set (were not present in the * set). */ public int add(final KType... elements) { int count = 0; for (final KType e : elements) { if (add(e)) { count++; } } return count; } /** {@inheritDoc} */ @Override public int addAll(final KTypeContainer<? extends KType> container) { return addAll((Iterable<? extends KTypeCursor<? extends KType>>) container); } /** {@inheritDoc} */ @Override public int addAll(final Iterable<? extends KTypeCursor<? extends KType>> iterable) { int count = 0; for (final KTypeCursor<? extends KType> cursor : iterable) { if (add(cursor.value)) { count++; } } return count; } /** * Expand the internal storage buffers (capacity) or rehash current keys and values if there are a * lot of deleted slots. */ private void expandAndAdd(final KType pendingKey, final int freeSlot) { assert this.assigned == this.resizeAt; // default sentinel value is never in the keys[] array, so never trigger reallocs assert (!Intrinsics.<KType>isEmpty(pendingKey)); // Try to allocate new buffers first. If we OOM, it'll be now without // leaving the data structure in an inconsistent state. final KType[] oldKeys = Intrinsics.<KType[]>cast(this.keys); allocateBuffers( HashContainers.nextBufferSize(this.keys.length, this.assigned, this.loadFactor)); // We have succeeded at allocating new data so insert the pending key/value at // the free slot in the old arrays before rehashing. this.assigned++; oldKeys[freeSlot] = pendingKey; // Variables for adding final int mask = this.keys.length - 1; KType key = Intrinsics.<KType>empty(); // adding phase int slot = -1; final KType[] keys = Intrinsics.<KType[]>cast(this.keys); /*! #if ($RH) !*/ final int[] cached = this.hash_cache; /*! #end !*/ /*! #if ($RH) !*/ KType tmpKey = Intrinsics.<KType>empty(); int tmpAllocated = -1; int initial_slot = -1; int dist = -1; int existing_distance = -1; /*! #end !*/ // iterate all the old arrays to add in the newly allocated buffers // It is important to iterate backwards to minimize the conflict chain length ! final int perturb = this.perturbation; for (int i = oldKeys.length; --i >= 0; ) { // only consider non-empty slots, of course if (!Intrinsics.<KType>isEmpty(key = oldKeys[i])) { slot = REHASH2(key, perturb) & mask; /*! #if ($RH) !*/ initial_slot = slot; dist = 0; /*! #end !*/ // similar to add(), except all inserted keys are known to be unique. while (is_allocated(slot, keys)) { /*! #if ($RH) !*/ // re-shuffle keys to minimize variance existing_distance = probe_distance(slot, cached); if (dist > existing_distance) { // swap current (key, value, initial_slot) with slot places tmpKey = keys[slot]; keys[slot] = key; key = tmpKey; tmpAllocated = cached[slot]; cached[slot] = initial_slot; initial_slot = tmpAllocated; /*! #if($DEBUG) !*/ // Check invariants assert cached[slot] == (REHASH(keys[slot]) & mask); assert initial_slot == (REHASH(key) & mask); /*! #end !*/ dist = existing_distance; } // endif /*! #end !*/ slot = (slot + 1) & mask; /*! #if ($RH) !*/ dist++; /*! #end !*/ } // end while // place it at that position /*! #if ($RH) !*/ cached[slot] = initial_slot; /*! #end !*/ keys[slot] = key; /*! #if ($RH) !*/ /*! #if($DEBUG) !*/ // Check invariants assert cached[slot] == (REHASH(keys[slot]) & mask); /*! #end !*/ /*! #end !*/ } } } /** * Allocate internal buffers for a given capacity. * * @param capacity New capacity (must be a power of two). */ @SuppressWarnings("boxing") private void allocateBuffers(final int capacity) { try { final KType[] keys = Intrinsics.<KType>newArray(capacity); /*! #if ($RH) !*/ final int[] allocated = new int[capacity]; /*! #end !*/ this.keys = keys; /*! #if ($RH) !*/ this.hash_cache = allocated; /*! #end !*/ // allocate so that there is at least one slot that remains allocated = false // this is compulsory to guarantee proper stop in searching loops this.resizeAt = HashContainers.expandAtCount(capacity, this.loadFactor); } catch (final OutOfMemoryError e) { throw new BufferAllocationException( "Not enough memory to allocate buffers to grow from %d -> %d elements", e, (this.keys == null) ? 0 : this.keys.length, capacity); } } /** {@inheritDoc} */ @Override public int removeAll(final KType key) { return remove(key) ? 1 : 0; } /** {@inheritDoc} */ @Override public boolean remove(final KType key) { if (Intrinsics.<KType>isEmpty(key)) { if (this.allocatedDefaultKey) { this.allocatedDefaultKey = false; return true; } return false; } final int mask = this.keys.length - 1; final KType[] keys = Intrinsics.<KType[]>cast(this.keys); int slot = REHASH(key) & mask; KType existing; /*! #if ($RH) !*/ int dist = 0; final int[] cached = this.hash_cache; /*! #end !*/ while (!Intrinsics.<KType>isEmpty(existing = keys[slot]) /*! #if ($RH) !*/ && dist <= probe_distance(slot, cached) /*! #end !*/) { if (KEYEQUALS(key, existing)) { shiftConflictingKeys(slot); return true; } slot = (slot + 1) & mask; /*! #if ($RH) !*/ dist++; /*! #end !*/ } // end while true return false; } /** Shift all the slot-conflicting keys allocated to (and including) <code>slot</code>. */ private void shiftConflictingKeys(int gapSlot) { final int mask = this.keys.length - 1; final KType[] keys = Intrinsics.<KType[]>cast(this.keys); /*! #if ($RH) !*/ final int[] cached = this.hash_cache; /*! #else final int perturb = this.perturbation; #end !*/ // Perform shifts of conflicting keys to fill in the gap. int distance = 0; while (true) { final int slot = (gapSlot + (++distance)) & mask; final KType existing = keys[slot]; if (Intrinsics.<KType>isEmpty(existing)) { break; } /*! #if ($RH) !*/ // use the cached value, no need to recompute final int idealSlotModMask = cached[slot]; /*! #if($DEBUG) !*/ // Check invariants assert idealSlotModMask == (REHASH(existing) & mask); /*! #end !*/ /*! #else final int idealSlotModMask = REHASH2(existing, perturb) & mask; #end !*/ // original HPPC code: shift = (slot - idealSlot) & mask; // equivalent to shift = (slot & mask - idealSlot & mask) & mask; // since slot and idealSlotModMask are already folded, we have : final int shift = (slot - idealSlotModMask) & mask; if (shift >= distance) { // Entry at this position was originally at or before the gap slot. // Move the conflict-shifted entry to the gap's position and repeat the procedure // for any entries to the right of the current position, treating it // as the new gap. keys[gapSlot] = existing; /*! #if ($RH) !*/ cached[gapSlot] = idealSlotModMask; /*! #if($DEBUG) !*/ assert cached[gapSlot] == (REHASH(existing) & mask); /*! #end !*/ /*! #end !*/ gapSlot = slot; distance = 0; } } // end while // Mark the last found gap slot without a conflict as empty. keys[gapSlot] = Intrinsics.<KType>empty(); this.assigned--; } /** {@inheritDoc} */ @Override public boolean contains(final KType key) { if (Intrinsics.<KType>isEmpty(key)) { return this.allocatedDefaultKey; } final int mask = this.keys.length - 1; final KType[] keys = Intrinsics.<KType[]>cast(this.keys); int slot = REHASH(key) & mask; KType existing; /*! #if ($RH) !*/ final int[] cached = this.hash_cache; int dist = 0; /*! #end !*/ while (!Intrinsics.<KType>isEmpty(existing = keys[slot]) /*! #if ($RH) !*/ && dist <= probe_distance(slot, cached) /*! #end !*/) { if (KEYEQUALS(key, existing)) { return true; } slot = (slot + 1) & mask; /*! #if ($RH) !*/ dist++; /*! #end !*/ } // end while true return false; } /** * {@inheritDoc} * * <p>Does not release internal buffers. */ @Override public void clear() { this.assigned = 0; // States are always cleared. this.allocatedDefaultKey = false; // Faster than Arrays.fill(keys, null); // Help the GC. KTypeArrays.blankArray(this.keys, 0, this.keys.length); } /** {@inheritDoc} */ @Override public int size() { return this.assigned + (this.allocatedDefaultKey ? 1 : 0); } /** {@inheritDoc} */ @Override public int capacity() { return this.resizeAt; } /** {@inheritDoc} */ @Override public int hashCode() { int h = 0; // allocated default key has hash = 0 final KType[] keys = Intrinsics.<KType[]>cast(this.keys); for (int i = keys.length; --i >= 0; ) { KType existing; if (!Intrinsics.<KType>isEmpty(existing = keys[i])) { h += BitMixer.mix(existing); } } return h; } /** {@inheritDoc} */ @Override public boolean equals(final Object obj) { if (obj != null) { if (obj == this) { return true; } // must be of the same class, subclasses are not comparable if (obj.getClass() != this.getClass()) { return false; } @SuppressWarnings("unchecked") final KTypeSet<KType> other = (KTypeSet<KType>) obj; // must be of the same size if (other.size() != this.size()) { return false; } final EntryIterator it = this.iterator(); while (it.hasNext()) { if (!other.contains(it.next().value)) { // recycle it.release(); return false; } } return true; } return false; } /** * An iterator implementation for {@link #iterator}. Holds a KTypeCursor returning (value, index) * = (KType value, index the position in {@link KTypeHashSet#keys}, or keys.length for key = * 0/null.) */ public final class EntryIterator extends AbstractIterator<KTypeCursor<KType>> { public final KTypeCursor<KType> cursor; public EntryIterator() { this.cursor = new KTypeCursor<KType>(); this.cursor.index = -2; } /** * Iterate backwards w.r.t the buffer, to minimize collision chains when filling another hash * container (ex. with putAll()) */ @Override protected KTypeCursor<KType> fetch() { if (this.cursor.index == KTypeHashSet.this.keys.length + 1) { if (KTypeHashSet.this.allocatedDefaultKey) { this.cursor.index = KTypeHashSet.this.keys.length; this.cursor.value = Intrinsics.<KType>empty(); return this.cursor; } // no value associated with the default key, continue iteration... this.cursor.index = KTypeHashSet.this.keys.length; } int i = this.cursor.index - 1; while (i >= 0 && !is_allocated(i, Intrinsics.<KType[]>cast(KTypeHashSet.this.keys))) { i--; } if (i == -1) { return done(); } this.cursor.index = i; this.cursor.value = Intrinsics.<KType>cast(KTypeHashSet.this.keys[i]); return this.cursor; } } /** internal pool of EntryIterator */ protected final IteratorPool<KTypeCursor<KType>, EntryIterator> entryIteratorPool = new IteratorPool<KTypeCursor<KType>, EntryIterator>( new ObjectFactory<EntryIterator>() { @Override public EntryIterator create() { return new EntryIterator(); } @Override public void initialize(final EntryIterator obj) { obj.cursor.index = KTypeHashSet.this.keys.length + 1; } @Override public void reset(final EntryIterator obj) { /*! #if ($TemplateOptions.KTypeGeneric) !*/ obj.cursor.value = null; /*! #end !*/ } }); /** {@inheritDoc} */ @Override public EntryIterator iterator() { // return new EntryIterator(); return this.entryIteratorPool.borrow(); } /** {@inheritDoc} */ @Override public <T extends KTypeProcedure<? super KType>> T forEach(final T procedure) { if (this.allocatedDefaultKey) { procedure.apply(Intrinsics.<KType>empty()); } final KType[] keys = Intrinsics.<KType[]>cast(this.keys); // Iterate in reverse for side-stepping the longest conflict chain // in another hash, in case apply() is actually used to fill another hash container. for (int i = keys.length - 1; i >= 0; i--) { KType existing; if (!Intrinsics.<KType>isEmpty(existing = keys[i])) { procedure.apply(existing); } } return procedure; } /** {@inheritDoc} */ @Override public KType[] toArray(final KType[] target) { int count = 0; if (this.allocatedDefaultKey) { target[count++] = Intrinsics.<KType>empty(); } final KType[] keys = Intrinsics.<KType[]>cast(this.keys); for (int i = 0; i < keys.length; i++) { KType existing; if (!Intrinsics.<KType>isEmpty(existing = keys[i])) { target[count++] = existing; } } assert count == this.size(); return target; } /** {@inheritDoc} */ @Override public KTypeHashSet<KType> clone() { // clone to size() to prevent eventual exponential growth final KTypeHashSet<KType> cloned = new KTypeHashSet<KType>(this.size(), this.loadFactor); // We must NOT clone, because of the independent perturbation seeds cloned.addAll(this); return cloned; } /** {@inheritDoc} */ @Override public <T extends KTypePredicate<? super KType>> T forEach(final T predicate) { if (this.allocatedDefaultKey) { if (!predicate.apply(Intrinsics.<KType>empty())) { return predicate; } } final KType[] keys = Intrinsics.<KType[]>cast(this.keys); // Iterate in reverse for side-stepping the longest conflict chain // in another hash, in case apply() is actually used to fill another hash container. for (int i = keys.length - 1; i >= 0; i--) { KType existing; if (!Intrinsics.<KType>isEmpty(existing = keys[i])) { if (!predicate.apply(existing)) { break; } } } return predicate; } /** {@inheritDoc} */ @Override public int removeAll(final KTypePredicate<? super KType> predicate) { final int before = this.size(); if (this.allocatedDefaultKey) { if (predicate.apply(Intrinsics.<KType>empty())) { this.allocatedDefaultKey = false; } } final KType[] keys = Intrinsics.<KType[]>cast(this.keys); for (int i = 0; i < keys.length; ) { KType existing; if (!Intrinsics.<KType>isEmpty(existing = keys[i]) && predicate.apply(existing)) { shiftConflictingKeys(i); // Shift, do not increment slot. } else { i++; } } return before - this.size(); } /** Create a set from a variable number of arguments or an array of <code>KType</code>. */ public static <KType> KTypeHashSet<KType> from(final KType... elements) { final KTypeHashSet<KType> set = new KTypeHashSet<KType>(elements.length); set.add(elements); return set; } /** Create a set from elements of another container. */ public static <KType> KTypeHashSet<KType> from(final KTypeContainer<KType> container) { return new KTypeHashSet<KType>(container); } /** Create a new hash set with default parameters (shortcut instead of using a constructor). */ public static <KType> KTypeHashSet<KType> newInstance() { return new KTypeHashSet<KType>(); } /** * Returns a new object of this class with no need to declare generic type (shortcut instead of * using a constructor). */ public static <KType> KTypeHashSet<KType> newInstance( final int initialCapacity, final double loadFactor) { return new KTypeHashSet<KType>(initialCapacity, loadFactor); } // Test for existence in template /*! #if ($TemplateOptions.declareInline("is_allocated(slot, keys)", "<*>==>!Intrinsics.<KType>isEmpty(keys[slot])")) !*/ /** template version (actual method is inlined in generated code) */ private boolean is_allocated(final int slot, final KType[] keys) { return !Intrinsics.<KType>isEmpty(keys[slot]); } /*! #end !*/ /*! #if ($RH) !*/ private int probe_distance(final int slot, final int[] cached) { final int rh = cached[slot]; /*! #if($DEBUG) !*/ // Check : cached hashed slot is == computed value final int mask = cached.length - 1; assert rh == (REHASH(Intrinsics.<KType>cast(this.keys[slot])) & mask); /*! #end !*/ if (slot < rh) { // wrap around return slot - rh + cached.length; } return slot - rh; } /*! #end !*/ /*! #if ($TemplateOptions.declareInline("REHASH(value)", "<Object>==>BitMixer.mix(hashKey(value) , this.perturbation)", "<*>==>BitMixer.mix(value , this.perturbation)")) !*/ /** * REHASH method for rehashing the keys. (inlined in generated code) Thanks to single array mode, * no need to check for null/0 or booleans. */ private int REHASH(final KType value) { return BitMixer.mix(hashKey(value), this.perturbation); } /*! #end !*/ /*! #if ($TemplateOptions.declareInline("REHASH2(value, perturb)", "<Object>==>BitMixer.mix(hashKey(value) , perturb)", "<*>==>BitMixer.mix(value , perturb)")) !*/ /** * REHASH2 method for rehashing the keys with perturbation seed as parameter (inlined in generated * code) Thanks to single array mode, no need to check for null/0 or booleans. */ private int REHASH2(final KType value, final int perturb) { return BitMixer.mix(hashKey(value), perturb); } /*! #end !*/ /*! #if ($TemplateOptions.declareInline("KEYEQUALS(key1, key2)", "<Object>==>equalKeys(key1, key2)", "<*>==>Intrinsics.<KType> equalsNotNull(key1, key2)")) !*/ /** macro which hides the applied equality criteria */ private boolean KEYEQUALS(final KType key1, final KType key2) { return equalKeys(key1, key2); } /*! #end !*/ }