Skip to content

Commit 7ab4a93

Browse files
committed
Introduced FixedArrayFIFOQueue
This is a copy of `ArrayFIFOQueue` which has fixed capacity.
1 parent 566da9d commit 7ab4a93

File tree

4 files changed

+542
-0
lines changed

4 files changed

+542
-0
lines changed

drv/FixedArrayFIFOQueue.drv

+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
/*
2+
* Copyright (C) 2010-2023 Sebastiano Vigna
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+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
18+
package PACKAGE;
19+
20+
#if KEY_CLASS_Object
21+
import java.util.Arrays;
22+
import java.util.Comparator;
23+
#endif
24+
25+
import java.io.Serializable;
26+
import it.unimi.dsi.fastutil.HashCommon;
27+
import it.unimi.dsi.fastutil.PriorityQueue;
28+
29+
import java.util.NoSuchElementException;
30+
31+
/** A type-specific array-based FIFO queue, supporting also deque operations.
32+
*
33+
* <p>Instances of this class represent a FIFO queue using a backing
34+
* array in a circular way.
35+
*
36+
* <p>This class provides additional methods that implement a <em>deque</em> (double-ended queue).
37+
*/
38+
39+
public class FIXED_ARRAY_FIFO_QUEUE KEY_GENERIC implements PRIORITY_QUEUE KEY_GENERIC, Serializable {
40+
private static final long serialVersionUID = 0L;
41+
42+
/** The backing array. */
43+
protected transient KEY_GENERIC_TYPE array[];
44+
45+
/** The current (cached) length of {@link #array}. */
46+
protected transient int length;
47+
48+
/** The start position in {@link #array}. It is always strictly smaller than {@link #length}.*/
49+
protected transient int start;
50+
51+
/** The end position in {@link #array}. It is always strictly smaller than {@link #length}.
52+
* Might be actually smaller than {@link #start} because {@link #array} is used cyclically. */
53+
protected transient int end;
54+
55+
/** Creates a new empty queue with given capacity.
56+
*
57+
* @implNote Because of inner limitations of the JVM, the initial
58+
* capacity cannot exceed {@link it.unimi.dsi.fastutil.Arrays#MAX_ARRAY_SIZE} &minus; 1.
59+
*
60+
* @param capacity the initial capacity of this queue.
61+
*/
62+
SUPPRESS_WARNINGS_KEY_UNCHECKED
63+
public FIXED_ARRAY_FIFO_QUEUE(final int capacity) {
64+
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));
65+
if (capacity < 0) throw new IllegalArgumentException("Initial capacity (" + capacity + ") is negative");
66+
// We never build a queue with a zero-sized backing array; moreover, to
67+
// avoid resizing at the given capacity we need one additional element.
68+
array = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[Math.max(1, capacity + 1)];
69+
length = array.length;
70+
}
71+
72+
/** {@inheritDoc}
73+
* @implSpec This implementation returns {@code null} (FIFO queues have no comparator). */
74+
@Override
75+
public KEY_COMPARATOR KEY_SUPER_GENERIC comparator() {
76+
return null;
77+
}
78+
79+
@Override
80+
public KEY_GENERIC_TYPE DEQUEUE() {
81+
if (start == end) throw new NoSuchElementException();
82+
final KEY_GENERIC_TYPE t = array[start];
83+
#if KEYS_REFERENCE
84+
array[start] = null; // Clean-up for the garbage collector.
85+
#endif
86+
if (++start == length) start = 0;
87+
return t;
88+
}
89+
90+
@Override
91+
public KEY_GENERIC_TYPE DEQUEUE(KEY_GENERIC_TYPE x) {
92+
if (start == end) return x;
93+
final KEY_GENERIC_TYPE t = array[start];
94+
#if KEYS_REFERENCE
95+
array[start] = null; // Clean-up for the garbage collector.
96+
#endif
97+
if (++start == length) start = 0;
98+
return t;
99+
}
100+
101+
@Override
102+
public KEY_GENERIC_TYPE DEQUEUE_LAST() {
103+
if (start == end) throw new NoSuchElementException();
104+
if (end == 0) end = length;
105+
final KEY_GENERIC_TYPE t = array[--end];
106+
#if KEYS_REFERENCE
107+
array[end] = null; // Clean-up for the garbage collector.
108+
#endif
109+
return t;
110+
}
111+
112+
@Override
113+
public KEY_GENERIC_TYPE DEQUEUE_LAST(KEY_GENERIC_TYPE x) {
114+
if (start == end) return x;
115+
if (end == 0) end = length;
116+
final KEY_GENERIC_TYPE t = array[--end];
117+
#if KEYS_REFERENCE
118+
array[end] = null; // Clean-up for the garbage collector.
119+
#endif
120+
return t;
121+
}
122+
123+
SUPPRESS_WARNINGS_KEY_UNCHECKED
124+
private final void resize(final int size, final int newLength) {
125+
final KEY_GENERIC_TYPE[] newArray = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[newLength];
126+
if (start >= end) {
127+
if (size != 0) {
128+
System.arraycopy(array, start, newArray, 0, length - start);
129+
System.arraycopy(array, 0, newArray, length - start, end);
130+
}
131+
}
132+
else System.arraycopy(array, start, newArray, 0, end - start);
133+
start = 0;
134+
end = size;
135+
array = newArray;
136+
length = newLength;
137+
}
138+
139+
@Override
140+
public boolean enqueue(KEY_GENERIC_TYPE x) {
141+
final int next = end++;
142+
if (end == start) return false;
143+
array[next] = x;
144+
if (end == length) end = 0;
145+
return true;
146+
}
147+
148+
@Override
149+
public boolean enqueueFirst(KEY_GENERIC_TYPE x) {
150+
if (start == 0) start = length;
151+
final int next = --start;
152+
if (end == start) return false;
153+
array[next] = x;
154+
return true;
155+
}
156+
157+
@Override
158+
public KEY_GENERIC_TYPE FIRST() {
159+
if (start == end) throw new NoSuchElementException();
160+
return array[start];
161+
}
162+
163+
@Override
164+
public KEY_GENERIC_TYPE FIRST(KEY_GENERIC_TYPE x) {
165+
if (start == end) return x;
166+
return array[start];
167+
}
168+
169+
170+
@Override
171+
public KEY_GENERIC_TYPE LAST() {
172+
if (start == end) throw new NoSuchElementException();
173+
return array[(end == 0 ? length : end) - 1];
174+
}
175+
176+
@Override
177+
public KEY_GENERIC_TYPE LAST(KEY_GENERIC_TYPE x) {
178+
if (start == end) return x;
179+
return array[(end == 0 ? length : end) - 1];
180+
}
181+
182+
@Override
183+
public void clear() {
184+
#if KEYS_REFERENCE
185+
if (start <= end) Arrays.fill(array, start, end, null);
186+
else {
187+
Arrays.fill(array, start, length, null);
188+
Arrays.fill(array, 0, end, null);
189+
}
190+
#endif
191+
start = end = 0;
192+
}
193+
194+
@Override
195+
public int size() {
196+
final int apparentLength = end - start;
197+
return apparentLength >= 0 ? apparentLength : length + apparentLength;
198+
}
199+
200+
public int capacity() {
201+
return array.length - 1;
202+
}
203+
204+
private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
205+
s.defaultWriteObject();
206+
int size = size();
207+
s.writeInt(size);
208+
for(int i = start; size-- != 0;) {
209+
s.WRITE_KEY(array[i++]);
210+
if (i == length) i = 0;
211+
}
212+
}
213+
214+
SUPPRESS_WARNINGS_KEY_UNCHECKED
215+
private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
216+
s.defaultReadObject();
217+
end = s.readInt();
218+
array = KEY_GENERIC_ARRAY_CAST new KEY_TYPE[length = HashCommon.nextPowerOfTwo(end + 1)];
219+
for(int i = 0; i < end; i++) array[i] = KEY_GENERIC_CAST s.READ_KEY();
220+
}
221+
}

gencsource.sh

+1
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,7 @@ $(if [[ "${CLASS[$k]}" != "" && "${CLASS[$v]}" != "" ]]; then\
577577
"#define HEAP_SESQUI_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}HeapSesquiIndirectDoublePriorityQueue\n"\
578578
"#define HEAP_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}HeapIndirectDoublePriorityQueue\n"\
579579
"#define ARRAY_FIFO_QUEUE ${TYPE_CAP2[$k]}ArrayFIFOQueue\n"\
580+
"#define FIXED_ARRAY_FIFO_QUEUE ${TYPE_CAP2[$k]}FixedArrayFIFOQueue\n"\
580581
"#define ARRAY_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayPriorityQueue\n"\
581582
"#define ARRAY_INDIRECT_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayIndirectPriorityQueue\n"\
582583
"#define ARRAY_INDIRECT_DOUBLE_PRIORITY_QUEUE ${TYPE_CAP2[$k]}ArrayIndirectDoublePriorityQueue\n"\

makefile

+5
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,11 @@ $(ARRAY_FIFO_QUEUES): drv/ArrayFIFOQueue.drv; ./gencsource.sh $< $@ >$@
476476

477477
CSOURCES += $(ARRAY_FIFO_QUEUES)
478478

479+
FIXED_ARRAY_FIFO_QUEUES := $(foreach k,$(TYPE_NOBOOL_NOREF), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)FixedArrayFIFOQueue.c)
480+
$(FIXED_ARRAY_FIFO_QUEUES): drv/FixedArrayFIFOQueue.drv; ./gencsource.sh $< $@ >$@
481+
482+
CSOURCES += $(FIXED_ARRAY_FIFO_QUEUES)
483+
479484
HEAP_SEMI_INDIRECT_PRIORITY_QUEUES := $(foreach k, $(TYPE_NOBOOL_NOREF), $(GEN_SRCDIR)/$(PKG_PATH)/$(PACKAGE_$(k))/$(k)HeapSemiIndirectPriorityQueue.c)
480485
$(HEAP_SEMI_INDIRECT_PRIORITY_QUEUES): drv/HeapSemiIndirectPriorityQueue.drv; ./gencsource.sh $< $@ >$@
481486

0 commit comments

Comments
 (0)