diff --git a/drv/ArrayFIFOQueue.drv b/drv/ArrayFIFOQueue.drv index 5c3697da..ce6c58bd 100644 --- a/drv/ArrayFIFOQueue.drv +++ b/drv/ArrayFIFOQueue.drv @@ -97,11 +97,19 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, return t; } - /** Dequeues the {@linkplain PriorityQueue#last() last} element from the queue. - * - * @return the dequeued element. - * @throws NoSuchElementException if the queue is empty. - */ + @Override + public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) { + if (start == end) return x; + final KEY_GENERIC_TYPE t = array[start]; +#if KEYS_REFERENCE + array[start] = null; // Clean-up for the garbage collector. +#endif + if (++start == length) start = 0; + reduce(); + return t; + } + + @Override public KEY_GENERIC_TYPE DEQUEUE_LAST() { if (start == end) throw new NoSuchElementException(); if (end == 0) end = length; @@ -113,6 +121,18 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, return t; } + @Override + public KEY_GENERIC_TYPE DEQUEUE_LAST(KEY_GENERIC_TYPE x) { + if (start == end) return x; + if (end == 0) end = length; + final KEY_GENERIC_TYPE t = array[--end]; +#if KEYS_REFERENCE + array[end] = null; // Clean-up for the garbage collector. +#endif + reduce(); + return t; + } + SUPPRESS_WARNINGS_KEY_UNCHECKED private final void resize(final int size, final int newLength) { final KEY_GENERIC_TYPE[] newArray = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[newLength]; @@ -139,19 +159,19 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, } @Override - public void enqueue(KEY_GENERIC_TYPE x) { + public boolean enqueue(KEY_GENERIC_TYPE x) { array[end++] = x; if (end == length) end = 0; if (end == start) expand(); + return true; } - /** Enqueues a new element as the first element (in dequeuing order) of the queue. - * @param x the element to enqueue. - */ - public void enqueueFirst(KEY_GENERIC_TYPE x) { + @Override + public boolean enqueueFirst(KEY_GENERIC_TYPE x) { if (start == 0) start = length; array[--start] = x; if (end == start) expand(); + return true; } @Override @@ -160,6 +180,12 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, return array[start]; } + @Override + public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) { + if (start == end) return x; + return array[start]; + } + @Override public KEY_GENERIC_TYPE LAST() { @@ -167,6 +193,12 @@ public class ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, return array[(end == 0 ? length : end) - 1]; } + @Override + public KEY_GENERIC_TYPE LAST(KEY_GENERIC_TYPE x) { + if (start == end) return x; + return array[(end == 0 ? length : end) - 1]; + } + @Override public void clear() { #if KEYS_REFERENCE diff --git a/drv/ArrayPriorityQueue.drv b/drv/ArrayPriorityQueue.drv index f3465a2d..4e571853 100644 --- a/drv/ArrayPriorityQueue.drv +++ b/drv/ArrayPriorityQueue.drv @@ -154,13 +154,9 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENE return this.firstIndex = firstIndex; } - private void ensureNonEmpty() { - if (size == 0) throw new NoSuchElementException(); - } - @Override SUPPRESS_WARNINGS_KEY_UNCHECKED - public void enqueue(KEY_GENERIC_TYPE x) { + public boolean enqueue(KEY_GENERIC_TYPE x) { if (size == array.length) array = ARRAYS.grow(array, size + 1); if (firstIndexValid) { if (c == null) { if (KEY_LESS(x, array[firstIndex])) firstIndex = size; } @@ -168,11 +164,25 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENE } else firstIndexValid = false; array[size++] = x; + return true; } @Override public KEY_GENERIC_TYPE DEQUEUE() { - ensureNonEmpty(); + if (size == 0) throw new NoSuchElementException(); + final int first = findFirst(); + final KEY_GENERIC_TYPE result = array[first]; + System.arraycopy(array, first + 1, array, first, --size - first); +#if KEY_CLASS_Object + array[size] = null; +#endif + firstIndexValid = false; + return result; + } + + @Override + public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) { + if (size == 0) return x; final int first = findFirst(); final KEY_GENERIC_TYPE result = array[first]; System.arraycopy(array, first + 1, array, first, --size - first); @@ -185,13 +195,19 @@ public class ARRAY_PRIORITY_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENE @Override public KEY_GENERIC_TYPE FIRST() { - ensureNonEmpty(); + if (size == 0) throw new NoSuchElementException(); + return array[findFirst()]; + } + + @Override + public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) { + if (size == 0) return x; return array[findFirst()]; } @Override public void changed() { - ensureNonEmpty(); + if (size == 0) throw new NoSuchElementException(); firstIndexValid = false; } diff --git a/drv/FixedArrayFIFOQueue.drv b/drv/FixedArrayFIFOQueue.drv new file mode 100644 index 00000000..7c81700b --- /dev/null +++ b/drv/FixedArrayFIFOQueue.drv @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2010-2023 Sebastiano Vigna + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +package PACKAGE; + +#if KEY_CLASS_Object +import java.util.Arrays; +import java.util.Comparator; +#endif + +import java.io.Serializable; +import it.unimi.dsi.fastutil.HashCommon; +import it.unimi.dsi.fastutil.PriorityQueue; + +import java.util.NoSuchElementException; + +/** A type-specific array-based FIFO queue, supporting also deque operations. + * + *
Instances of this class represent a FIFO queue using a backing + * array in a circular way. + * + *
This class provides additional methods that implement a deque (double-ended queue).
+ */
+
+public class FIXED_ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, Serializable {
+ private static final long serialVersionUID = 0L;
+
+ /** The backing array. */
+ protected transient KEY_GENERIC_TYPE array[];
+
+ /** The current (cached) length of {@link #array}. */
+ protected transient int length;
+
+ /** The start position in {@link #array}. It is always strictly smaller than {@link #length}.*/
+ protected transient int start;
+
+ /** The end position in {@link #array}. It is always strictly smaller than {@link #length}.
+ * Might be actually smaller than {@link #start} because {@link #array} is used cyclically. */
+ protected transient int end;
+
+ /** Creates a new empty queue with given capacity.
+ *
+ * @implNote Because of inner limitations of the JVM, the initial
+ * capacity cannot exceed {@link it.unimi.dsi.fastutil.Arrays#MAX_ARRAY_SIZE} − 1.
+ *
+ * @param capacity the initial capacity of this queue.
+ */
+ SUPPRESS_WARNINGS_KEY_UNCHECKED
+ public FIXED_ARRAY_FIFO_QUEUE(final int capacity) {
+ if (capacity > it.unimi.dsi.fastutil.Arrays.MAX_ARRAY_SIZE - 1) throw new IllegalArgumentException("Initial capacity (" + capacity + ") exceeds " + (it.unimi.dsi.fastutil.Arrays.MAX_ARRAY_SIZE - 1));
+ if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative");
+ // We never build a queue with a zero-sized backing array; moreover, to
+ // avoid resizing at the given capacity we need one additional element.
+ array = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[Math.max(1, capacity + 1)];
+ length = array.length;
+ }
+
+ /** {@inheritDoc}
+ * @implSpec This implementation returns {@code null} (FIFO queues have no comparator). */
+ @Override
+ public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() {
+ return null;
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE() {
+ if (start == end) throw new NoSuchElementException();
+ final KEY_GENERIC_TYPE t = array[start];
+#if KEYS_REFERENCE
+ array[start] = null; // Clean-up for the garbage collector.
+#endif
+ if (++start == length) start = 0;
+ return t;
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) {
+ if (start == end) return x;
+ final KEY_GENERIC_TYPE t = array[start];
+#if KEYS_REFERENCE
+ array[start] = null; // Clean-up for the garbage collector.
+#endif
+ if (++start == length) start = 0;
+ return t;
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE_LAST() {
+ if (start == end) throw new NoSuchElementException();
+ if (end == 0) end = length;
+ final KEY_GENERIC_TYPE t = array[--end];
+#if KEYS_REFERENCE
+ array[end] = null; // Clean-up for the garbage collector.
+#endif
+ return t;
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE_LAST(KEY_GENERIC_TYPE x) {
+ if (start == end) return x;
+ if (end == 0) end = length;
+ final KEY_GENERIC_TYPE t = array[--end];
+#if KEYS_REFERENCE
+ array[end] = null; // Clean-up for the garbage collector.
+#endif
+ return t;
+ }
+
+ SUPPRESS_WARNINGS_KEY_UNCHECKED
+ private final void resize(final int size, final int newLength) {
+ final KEY_GENERIC_TYPE[] newArray = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[newLength];
+ if (start >= end) {
+ if (size != 0) {
+ System.arraycopy(array, start, newArray, 0, length - start);
+ System.arraycopy(array, 0, newArray, length - start, end);
+ }
+ }
+ else System.arraycopy(array, start, newArray, 0, end - start);
+ start = 0;
+ end = size;
+ array = newArray;
+ length = newLength;
+ }
+
+ @Override
+ public boolean enqueue(KEY_GENERIC_TYPE x) {
+ final int next = end++;
+ if (end == start) return false;
+ array[next] = x;
+ if (end == length) end = 0;
+ return true;
+ }
+
+ @Override
+ public boolean enqueueFirst(KEY_GENERIC_TYPE x) {
+ if (start == 0) start = length;
+ final int next = --start;
+ if (end == start) return false;
+ array[next] = x;
+ return true;
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE FIRST() {
+ if (start == end) throw new NoSuchElementException();
+ return array[start];
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) {
+ if (start == end) return x;
+ return array[start];
+ }
+
+
+ @Override
+ public KEY_GENERIC_TYPE LAST() {
+ if (start == end) throw new NoSuchElementException();
+ return array[(end == 0 ? length : end) - 1];
+ }
+
+ @Override
+ public KEY_GENERIC_TYPE LAST(KEY_GENERIC_TYPE x) {
+ if (start == end) return x;
+ return array[(end == 0 ? length : end) - 1];
+ }
+
+ @Override
+ public void clear() {
+#if KEYS_REFERENCE
+ if (start <= end) Arrays.fill(array, start, end, null);
+ else {
+ Arrays.fill(array, start, length, null);
+ Arrays.fill(array, 0, end, null);
+ }
+#endif
+ start = end = 0;
+ }
+
+ @Override
+ public int size() {
+ final int apparentLength = end - start;
+ return apparentLength >= 0 ? apparentLength : length + apparentLength;
+ }
+
+ public int capacity() {
+ return array.length - 1;
+ }
+
+ private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
+ s.defaultWriteObject();
+ int size = size();
+ s.writeInt(size);
+ for(int i = start; size-- != 0;) {
+ s.WRITE_KEY(array[i++]);
+ if (i == length) i = 0;
+ }
+ }
+
+ SUPPRESS_WARNINGS_KEY_UNCHECKED
+ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
+ s.defaultReadObject();
+ end = s.readInt();
+ array = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[length = HashCommon.nextPowerOfTwo(end + 1)];
+ for(int i = 0; i < end; i++) array[i] = KEY_GENERIC_CAST s.READ_KEY();
+ }
+}
diff --git a/drv/HeapPriorityQueue.drv b/drv/HeapPriorityQueue.drv
index 549349d4..72072efd 100644
--- a/drv/HeapPriorityQueue.drv
+++ b/drv/HeapPriorityQueue.drv
@@ -213,11 +213,12 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENER
#endif
@Override
- public void enqueue(KEY_GENERIC_TYPE x) {
+ public boolean enqueue(KEY_GENERIC_TYPE x) {
if (size == heap.length) heap = ARRAYS.grow(heap, size + 1);
heap[size++] = x;
HEAPS.upHeap(heap, size, size - 1, c);
+ return true;
}
@Override
@@ -233,12 +234,31 @@ public class HEAP_PRIORITY_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENER
return result;
}
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) {
+ if (size == 0) return x;
+
+ final KEY_GENERIC_TYPE result = heap[0];
+ heap[0] = heap[--size];
+#if KEY_CLASS_Object
+ heap[size] = null;
+#endif
+ if (size != 0) HEAPS.downHeap(heap, size, 0, c);
+ return result;
+ }
+
@Override
public KEY_GENERIC_TYPE FIRST() {
if (size == 0) throw new NoSuchElementException();
return heap[0];
}
+ @Override
+ public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) {
+ if (size == 0) return x;
+ return heap[0];
+ }
+
@Override
public void changed() {
HEAPS.downHeap(heap, size, 0, c);
diff --git a/drv/PriorityQueue.drv b/drv/PriorityQueue.drv
index 0c891345..8016da3e 100644
--- a/drv/PriorityQueue.drv
+++ b/drv/PriorityQueue.drv
@@ -31,9 +31,19 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
+ * @param x the element to enqueue.
+ * @return true if element was added into this queue.
+ */
+
+ default boolean enqueueFirst(KEY_GENERIC_TYPE x) { throw new UnsupportedOperationException(); }
/** Dequeues the {@linkplain #first() first} element from the queue.
* @see #dequeue()
@@ -43,6 +53,36 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
+ * @see #dequeue()
+ * @return the dequeued element.
+ * @throws NoSuchElementException if the queue is empty.
+ */
+
+ default KEY_GENERIC_TYPE DEQUEUE_LAST() { throw new UnsupportedOperationException(); }
+
+ /** Dequeues the {@linkplain #last() last} element from the queue
+ * or return {@code x} if the queue is empty.
+ *
+ * This default implementation just throws an {@link UnsupportedOperationException}.
+ * @see #dequeue()
+ * @param x the element to return when queue is empty.
+ * @return the dequeued element or {@code x} if the queue is empty.
+ */
+
+ default KEY_GENERIC_TYPE DEQUEUE_LAST(KEY_GENERIC_TYPE x) { throw new UnsupportedOperationException(); }
+
/** Returns the first element of the queue.
* @see #first()
* @return the first element.
@@ -51,6 +91,14 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
* @see #last()
@@ -60,6 +108,16 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
+ * @see #last()
+ * @return the last element.
+ * @throws NoSuchElementException if the queue is empty.
+ */
+
+ default KEY_GENERIC_TYPE LAST(KEY_GENERIC_TYPE x) { throw new UnsupportedOperationException(); }
+
/** Returns the comparator associated with this priority queue, or null if it uses its elements' natural ordering.
*
* @apiNote Note that this specification strengthens the one given in {@link PriorityQueue#comparator()}.
@@ -74,7 +132,14 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default boolean enqueueFirst(final KEY_GENERIC_CLASS x) { return enqueueFirst(x.KEY_VALUE()); }
/** {@inheritDoc}
* This default implementation delegates to the corresponding type-specific method.
@@ -83,6 +148,27 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default KEY_GENERIC_CLASS dequeue(KEY_GENERIC_CLASS x) { try { return dequeue(); } catch (NoSuchElementException ignored) { return x; } }
+
+ /** {@inheritDoc}
+ * This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default KEY_GENERIC_CLASS dequeueLast() { return KEY2OBJ(DEQUEUE_LAST()); }
+
+ /** {@inheritDoc}
+ * This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default KEY_GENERIC_CLASS dequeueLast(KEY_GENERIC_CLASS x) { try { return dequeueLast(); } catch (NoSuchElementException ignored) { return x; } }
+
/** {@inheritDoc}
* This default implementation delegates to the corresponding type-specific method.
* @deprecated Please use the corresponding type-specific method instead. */
@@ -90,10 +176,24 @@ public interface PRIORITY_QUEUE extends PriorityQueue This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default KEY_GENERIC_CLASS first(KEY_GENERIC_CLASS x) { return KEY2OBJ(FIRST(x)); }
+
/** {@inheritDoc}
* This default implementation delegates to the corresponding type-specific method.
* @deprecated Please use the corresponding type-specific method instead. */
@Deprecated
@Override
default KEY_GENERIC_CLASS last() { return KEY2OBJ(LAST()); }
+
+ /** {@inheritDoc}
+ * This default implementation delegates to the corresponding type-specific method.
+ * @deprecated Please use the corresponding type-specific method instead. */
+ @Deprecated
+ @Override
+ default KEY_GENERIC_CLASS last(KEY_GENERIC_CLASS x) { return KEY2OBJ(LAST(x)); }
}
diff --git a/drv/PriorityQueues.drv b/drv/PriorityQueues.drv
index 9075108d..0cd19287 100644
--- a/drv/PriorityQueues.drv
+++ b/drv/PriorityQueues.drv
@@ -43,17 +43,26 @@ public final class PRIORITY_QUEUES {
}
@Override
- public void enqueue(KEY_GENERIC_TYPE x) { synchronized(sync) { q.enqueue(x); } }
+ public boolean enqueue(KEY_GENERIC_TYPE x) { synchronized(sync) { return q.enqueue(x); } }
@Override
public KEY_GENERIC_TYPE DEQUEUE() { synchronized(sync) { return q.DEQUEUE(); } }
+ @Override
+ public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) { synchronized(sync) { return q.DEQUEUE(x); } }
+
@Override
public KEY_GENERIC_TYPE FIRST() { synchronized(sync) { return q.FIRST(); } }
+ @Override
+ public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) { synchronized(sync) { return q.FIRST(x); } }
+
@Override
public KEY_GENERIC_TYPE LAST() { synchronized(sync) { return q.LAST(); } }
+ @Override
+ public KEY_GENERIC_TYPE LAST(KEY_GENERIC_TYPE x) { synchronized(sync) { return q.LAST(x); } }
+
@Override
public boolean isEmpty() { synchronized(sync) { return q.isEmpty(); } }
@@ -73,20 +82,32 @@ public final class PRIORITY_QUEUES {
@Deprecated
@Override
- public void enqueue(KEY_CLASS x) { synchronized(sync) { q.enqueue(x); } }
+ public boolean enqueue(KEY_CLASS x) { synchronized(sync) { return q.enqueue(x); } }
@Deprecated
@Override
public KEY_CLASS dequeue() { synchronized(sync) { return q.dequeue(); } }
+ @Deprecated
+ @Override
+ public KEY_CLASS dequeue(KEY_CLASS x) { synchronized(sync) { return q.dequeue(x); } }
+
@Deprecated
@Override
public KEY_CLASS first() { synchronized(sync) { return q.first(); } }
+ @Deprecated
+ @Override
+ public KEY_CLASS first(KEY_CLASS x) { synchronized(sync) { return q.first(x); } }
+
@Deprecated
@Override
public KEY_CLASS last() { synchronized(sync) { return q.last(); } }
+ @Deprecated
+ @Override
+ public KEY_CLASS last(KEY_CLASS x) { synchronized(sync) { return q.last(x); } }
+
#endif
@Override
public int hashCode() { synchronized(sync) { return q.hashCode(); } }
diff --git a/gencsource.sh b/gencsource.sh
index b7b5f26e..407ea69c 100755
--- a/gencsource.sh
+++ b/gencsource.sh
@@ -577,6 +577,7 @@ $(if [[ "${CLASS[$k]}" != "" && "${CLASS[$v]}" != "" ]]; then\
"#define HEAP_SESQUI_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}HeapSesquiIndirectDoublePriorityQueue\n"\
"#define HEAP_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}HeapIndirectDoublePriorityQueue\n"\
"#define ARRAY_FIFO_QUEUE ${TYPE_CAP2[$k]}ArrayFIFOQueue\n"\
+"#define FIXED_ARRAY_FIFO_QUEUE ${TYPE_CAP2[$k]}FixedArrayFIFOQueue\n"\
"#define ARRAY_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayPriorityQueue\n"\
"#define ARRAY_INDIRECT_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayIndirectPriorityQueue\n"\
"#define ARRAY_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayIndirectDoublePriorityQueue\n"\
diff --git a/makefile b/makefile
index 9239a3ee..91beaeab 100644
--- a/makefile
+++ b/makefile
@@ -476,6 +476,11 @@ $(ARRAY_FIFO_QUEUES): drv/ArrayFIFOQueue.drv; ./gencsource.sh $< $@ >$@
CSOURCES += $(ARRAY_FIFO_QUEUES)
+FIXED_ARRAY_FIFO_QUEUES := $(foreach k,$(TYPE_NOBOOL_NOREF), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)FixedArrayFIFOQueue.c)
+$(FIXED_ARRAY_FIFO_QUEUES): drv/FixedArrayFIFOQueue.drv; ./gencsource.sh $< $@ >$@
+
+CSOURCES += $(FIXED_ARRAY_FIFO_QUEUES)
+
HEAP_SEMI_INDIRECT_PRIORITY_QUEUES := $(foreach k, $(TYPE_NOBOOL_NOREF), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)HeapSemiIndirectPriorityQueue.c)
$(HEAP_SEMI_INDIRECT_PRIORITY_QUEUES): drv/HeapSemiIndirectPriorityQueue.drv; ./gencsource.sh $< $@ >$@
diff --git a/src/it/unimi/dsi/fastutil/PriorityQueue.java b/src/it/unimi/dsi/fastutil/PriorityQueue.java
index fe0084bf..800ee8d7 100644
--- a/src/it/unimi/dsi/fastutil/PriorityQueue.java
+++ b/src/it/unimi/dsi/fastutil/PriorityQueue.java
@@ -41,9 +41,19 @@ public interface PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
+ * @param x the element to enqueue.
+ * @return true if element was added into this queue.
+ */
+
+ default boolean enqueueFirst(K x) { throw new UnsupportedOperationException(); }
/** Dequeues the {@linkplain #first() first} element from the queue.
*
@@ -53,6 +63,32 @@ public interface PriorityQueue This default implementation just throws an {@link UnsupportedOperationException}.
+ * @return the dequeued element.
+ * @throws NoSuchElementException if the queue is empty.
+ */
+
+ default K dequeueLast() { throw new UnsupportedOperationException(); }
+
+ /** Dequeues the {@linkplain PriorityQueue#last() last} element from the queue
+ * or return {@code x} if the queue is empty.
+ *
+ * This default implementation just throws an {@link UnsupportedOperationException}.
+ * @param x the element to return when queue is empty.
+ * @return the dequeued element or {@code x} if the queue is empty.
+ */
+ default K dequeueLast(K x) { throw new UnsupportedOperationException(); }
+
/** Checks whether this queue is empty.
*
* This default implementation checks whether {@link #size()} is zero.
@@ -83,6 +119,14 @@ default boolean isEmpty() {
K first();
+ /** Returns the first element of the queue or {@code x} if the queue is empty.
+ *
+ * @param x the element to return when queue is empty.
+ * @return the first element or {@code x} if the queue is empty.
+ */
+
+ K first(K x);
+
/** Returns the last element of the queue, that is, the element the would be dequeued last (optional operation).
*
* This default implementation just throws an {@link UnsupportedOperationException}.
@@ -92,6 +136,15 @@ default boolean isEmpty() {
default K last() { throw new UnsupportedOperationException(); }
+ /** Returns the last element of the queue or {@code x} if the queue is empty,
+ * that is, the element the would be dequeued last (optional operation).
+ *
+ * This default implementation just throws an {@link UnsupportedOperationException}.
+ * @return the last element or {@code x} if the queue is empty.
+ */
+
+ default K last(K x) { throw new UnsupportedOperationException(); }
+
/** Notifies the queue that the {@linkplain #first() first} element has changed (optional operation).
* This default implementation just throws an {@link UnsupportedOperationException}.
*/
diff --git a/src/it/unimi/dsi/fastutil/PriorityQueues.java b/src/it/unimi/dsi/fastutil/PriorityQueues.java
index 817f55a1..d6ba3d99 100644
--- a/src/it/unimi/dsi/fastutil/PriorityQueues.java
+++ b/src/it/unimi/dsi/fastutil/PriorityQueues.java
@@ -42,11 +42,14 @@ public static class EmptyPriorityQueue implements PriorityQueue, Serializable {
protected EmptyPriorityQueue() {}
@Override
- public void enqueue(final Object o) { throw new UnsupportedOperationException(); }
+ public boolean enqueue(final Object o) { throw new UnsupportedOperationException(); }
@Override
public Object dequeue() { throw new NoSuchElementException(); }
+ @Override
+ public Object dequeue(Object x) {return x;}
+
@Override
public boolean isEmpty() { return true; }
@@ -59,9 +62,15 @@ public void clear() {}
@Override
public Object first() { throw new NoSuchElementException(); }
+ @Override
+ public Object first(Object x) { return x; }
+
@Override
public Object last() { throw new NoSuchElementException(); }
+ @Override
+ public Object last(Object x) { return x; }
+
@Override
public void changed() { throw new NoSuchElementException(); }
@@ -114,17 +123,26 @@ protected SynchronizedPriorityQueue(final PriorityQueue