org.neo4j.collection.PrimitiveLongArrayQueue Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of neo4j-collections Show documentation
Show all versions of neo4j-collections Show documentation
Collections and collection utilities for Neo4j.
/*
* Copyright (c) "Neo4j"
* Neo4j Sweden AB [https://neo4j.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.neo4j.collection;
import java.util.NoSuchElementException;
import org.eclipse.collections.api.iterator.LongIterator;
/**
* Simple array based FIFO queue for primitive longs.
* Newly enqueued element is added into the end of the queue, and dequeue will return
* element from the head of the queue. (See CLRS 10.1 for more detailed description)
*
* Queue capacity should always be power of two to be able to use
* '&' mask operation with {@link #values} length.
*/
public class PrimitiveLongArrayQueue {
private static final int DEFAULT_CAPACITY = 16;
private long[] values;
private int head;
private int tail;
public PrimitiveLongArrayQueue() {
this(DEFAULT_CAPACITY);
}
PrimitiveLongArrayQueue(int capacity) {
if (capacity == 0 || (capacity & (capacity - 1)) != 0) {
throw new IllegalArgumentException("Capacity should be power of 2. Requested capacity: " + capacity);
}
initValues(capacity);
}
public boolean isEmpty() {
return head == tail;
}
public int size() {
return (tail - head) & (values.length - 1);
}
public LongIterator longIterator() {
return new PrimitiveLongArrayQueueIterator();
}
public long dequeue() {
if (isEmpty()) {
throw new IllegalStateException("Fail to poll first element. Queue is empty.");
}
long value = values[head];
head = (head + 1) & (values.length - 1);
return value;
}
public void enqueue(long value) {
values[tail] = value;
tail = (tail + 1) & (values.length - 1);
if (tail == head) {
ensureCapacity();
}
}
public void addAll(PrimitiveLongArrayQueue otherQueue) {
while (!otherQueue.isEmpty()) {
enqueue(otherQueue.dequeue());
}
}
private void initValues(int capacity) {
values = new long[capacity];
head = 0;
tail = 0;
}
private void ensureCapacity() {
int newCapacity = values.length << 1;
if (newCapacity < 0) {
throw new IllegalStateException("Fail to increase queue capacity.");
}
long[] newValues = new long[newCapacity];
int elementsFromHeadTillEnd = values.length - head;
System.arraycopy(values, head, newValues, 0, elementsFromHeadTillEnd);
System.arraycopy(values, 0, newValues, elementsFromHeadTillEnd, head);
tail = values.length;
head = 0;
values = newValues;
}
private class PrimitiveLongArrayQueueIterator implements LongIterator {
private int position;
PrimitiveLongArrayQueueIterator() {
this.position = head;
}
@Override
public boolean hasNext() {
return position != tail;
}
@Override
public long next() {
if (hasNext()) {
long value = values[position];
position = (position + 1) & (values.length - 1);
return value;
}
throw new NoSuchElementException();
}
}
}