Skip to content

Commit

Permalink
Introduced FixedArrayFIFOQueue
Browse files Browse the repository at this point in the history
This is a copy of `ArrayFIFOQueue` which has fixed capacity.
  • Loading branch information
catap committed Apr 21, 2023
1 parent 566da9d commit 7ab4a93
Show file tree
Hide file tree
Showing 4 changed files with 542 additions and 0 deletions.
221 changes: 221 additions & 0 deletions drv/FixedArrayFIFOQueue.drv
Original file line number Diff line number Diff line change
@@ -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.
*
* <p>Instances of this class represent a FIFO queue using a backing
* array in a circular way.
*
* <p>This class provides additional methods that implement a <em>deque</em> (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} &minus; 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();
}
}
1 change: 1 addition & 0 deletions gencsource.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"\
Expand Down
5 changes: 5 additions & 0 deletions makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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 $< $@ >$@

Expand Down
Loading

0 comments on commit 7ab4a93

Please sign in to comment.