jodd.util.buffer.FastDoubleBuffer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of extractor Show documentation
Show all versions of extractor Show documentation
Web Data Extractor - Extract data from common web format. like HTML,XML,JSON.
The newest version!
// Copyright (c) 2003-present, Jodd Team (http://jodd.org)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
package jodd.util.buffer;
/**
* Fast, fast double
buffer.
* This buffer implementation does not store all data
* in single array, but in array of chunks.
*/
public class FastDoubleBuffer {
private double[][] buffers = new double[16][];
private int buffersCount;
private int currentBufferIndex = -1;
private double[] currentBuffer;
private int offset;
private int size;
private final int minChunkLen;
/**
* Creates a new double
buffer. The buffer capacity is
* initially 1024 bytes, though its size increases if necessary.
*/
public FastDoubleBuffer() {
this.minChunkLen = 1024;
}
/**
* Creates a new double
buffer, with a buffer capacity of
* the specified size, in bytes.
*
* @param size the initial size.
* @throws IllegalArgumentException if size is negative.
*/
public FastDoubleBuffer(int size) {
if (size < 0) {
throw new IllegalArgumentException("Invalid size: " + size);
}
this.minChunkLen = size;
}
/**
* Prepares next chunk to match new size.
* The minimal length of new chunk is minChunkLen
.
*/
private void needNewBuffer(int newSize) {
int delta = newSize - size;
int newBufferSize = Math.max(minChunkLen, delta);
currentBufferIndex++;
currentBuffer = new double[newBufferSize];
offset = 0;
// add buffer
if (currentBufferIndex >= buffers.length) {
int newLen = buffers.length << 1;
double[][] newBuffers = new double[newLen][];
System.arraycopy(buffers, 0, newBuffers, 0, buffers.length);
buffers = newBuffers;
}
buffers[currentBufferIndex] = currentBuffer;
buffersCount++;
}
/**
* Appends double
array to buffer.
*/
public FastDoubleBuffer append(double[] array, int off, int len) {
int end = off + len;
if ((off < 0)
|| (len < 0)
|| (end > array.length)) {
throw new IndexOutOfBoundsException();
}
if (len == 0) {
return this;
}
int newSize = size + len;
int remaining = len;
if (currentBuffer != null) {
// first try to fill current buffer
int part = Math.min(remaining, currentBuffer.length - offset);
System.arraycopy(array, end - remaining, currentBuffer, offset, part);
remaining -= part;
offset += part;
size += part;
}
if (remaining > 0) {
// still some data left
// ask for new buffer
needNewBuffer(newSize);
// then copy remaining
// but this time we are sure that it will fit
int part = Math.min(remaining, currentBuffer.length - offset);
System.arraycopy(array, end - remaining, currentBuffer, offset, part);
offset += part;
size += part;
}
return this;
}
/**
* Appends double
array to buffer.
*/
public FastDoubleBuffer append(double[] array) {
return append(array, 0, array.length);
}
/**
* Appends single double
to buffer.
*/
public FastDoubleBuffer append(double element) {
if ((currentBuffer == null) || (offset == currentBuffer.length)) {
needNewBuffer(size + 1);
}
currentBuffer[offset] = element;
offset++;
size++;
return this;
}
/**
* Appends another fast buffer to this one.
*/
public FastDoubleBuffer append(FastDoubleBuffer buff) {
if (buff.size == 0) {
return this;
}
for (int i = 0; i < buff.currentBufferIndex; i++) {
append(buff.buffers[i]);
}
append(buff.currentBuffer, 0, buff.offset);
return this;
}
/**
* Returns buffer size.
*/
public int size() {
return size;
}
/**
* Tests if this buffer has no elements.
*/
public boolean isEmpty() {
return size == 0;
}
/**
* Returns current index of inner double
array chunk.
* Represents the index of last used inner array chunk.
*/
public int index() {
return currentBufferIndex;
}
/**
* Returns the offset of last used element in current inner array chunk.
*/
public int offset() {
return offset;
}
/**
* Returns double
inner array chunk at given index.
* May be used for iterating inner chunks in fast manner.
*/
public double[] array(int index) {
return buffers[index];
}
/**
* Resets the buffer content.
*/
public void clear() {
size = 0;
offset = 0;
currentBufferIndex = -1;
currentBuffer = null;
buffersCount = 0;
}
/**
* Creates double
array from buffered content.
*/
public double[] toArray() {
int pos = 0;
double[] array = new double[size];
if (currentBufferIndex == -1) {
return array;
}
for (int i = 0; i < currentBufferIndex; i++) {
int len = buffers[i].length;
System.arraycopy(buffers[i], 0, array, pos, len);
pos += len;
}
System.arraycopy(buffers[currentBufferIndex], 0, array, pos, offset);
return array;
}
/**
* Creates double
subarray from buffered content.
*/
public double[] toArray(int start, int len) {
int remaining = len;
int pos = 0;
double[] array = new double[len];
if (len == 0) {
return array;
}
int i = 0;
while (start >= buffers[i].length) {
start -= buffers[i].length;
i++;
}
while (i < buffersCount) {
double[] buf = buffers[i];
int c = Math.min(buf.length - start, remaining);
System.arraycopy(buf, start, array, pos, c);
pos += c;
remaining -= c;
if (remaining == 0) {
break;
}
start = 0;
i++;
}
return array;
}
/**
* Returns double
element at given index.
*/
public double get(int index) {
if ((index >= size) || (index < 0)) {
throw new IndexOutOfBoundsException();
}
int ndx = 0;
while (true) {
double[] b = buffers[ndx];
if (index < b.length) {
return b[index];
}
ndx++;
index -= b.length;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy