drv.BinIOFragment.drv Maven / Gradle / Ivy
Show all versions of fastutil-core Show documentation
/*
* Copyright (C) 2004-2021 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.
*/
#if KEY_CLASS_Byte
// HORRIBLE kluges to work around bug #6478546
private static final int MAX_IO_LENGTH = 1024 * 1024;
private static int read(final InputStream is, final byte a[], final int offset, final int length) throws IOException {
if (length == 0) return 0;
int read = 0, result;
do {
result = is.read(a, offset + read, Math.min(length - read, MAX_IO_LENGTH));
if (result < 0) return read;
read += result;
} while(read < length);
return read;
}
private static void write(final OutputStream outputStream, final byte a[], final int offset, final int length) throws IOException {
int written = 0;
while(written < length) {
outputStream.write(a, offset + written, Math.min(length - written, MAX_IO_LENGTH));
written += Math.min(length - written, MAX_IO_LENGTH);
}
}
private static void write(final DataOutput dataOutput, final byte a[], final int offset, final int length) throws IOException {
int written = 0;
while(written < length) {
dataOutput.write(a, offset + written, Math.min(length - written, MAX_IO_LENGTH));
written += Math.min(length - written, MAX_IO_LENGTH);
}
}
// Additional read/write methods to work around the DataInput/DataOutput schizophrenia.
/** Loads bytes from a given input stream, storing them in a given array fragment.
*
* Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)}
* as it uses {@link InputStream}'s bulk-read methods.
*
* @param inputStream an input stream.
* @param array an array which will be filled with data from {@code inputStream}.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from {@code inputStream} (it might be less than {@code length} if {@code inputStream} ends).
*/
public static int LOAD_KEYS(final InputStream inputStream, final KEY_TYPE[] array, final int offset, final int length) throws IOException {
return read(inputStream, array, offset, length);
}
/** Loads bytes from a given input stream, storing them in a given array.
*
*
Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[])}
* as it uses {@link InputStream}'s bulk-read methods.
*
* @param inputStream an input stream.
* @param array an array which will be filled with data from {@code inputStream}.
* @return the number of elements actually read from {@code inputStream} (it might be less than the array length if {@code inputStream} ends).
*/
public static int LOAD_KEYS(final InputStream inputStream, final KEY_TYPE[] array) throws IOException {
return read(inputStream, array, 0, array.length);
}
/** Stores an array fragment to a given output stream.
*
*
Note that this method is going to be significantly faster than {@link #storeBytes(byte[],int,int,DataOutput)}
* as it uses {@link OutputStream}'s bulk-read methods.
*
* @param array an array whose elements will be written to {@code outputStream}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param outputStream an output stream.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final OutputStream outputStream) throws IOException {
write(outputStream, array, offset, length);
}
/** Stores an array to a given output stream.
*
*
Note that this method is going to be significantly faster than {@link #storeBytes(byte[],DataOutput)}
* as it uses {@link OutputStream}'s bulk-read methods.
*
* @param array an array whose elements will be written to {@code outputStream}.
* @param outputStream an output stream.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final OutputStream outputStream) throws IOException {
write(outputStream, array, 0, array.length);
}
private static long read(final InputStream is, final byte a[][], final long offset, final long length) throws IOException {
if (length == 0) return 0;
long read = 0;
int segment = segment(offset);
int displacement = displacement(offset);
int result;
do {
result = is.read(a[segment], displacement, (int)Math.min(a[segment].length - displacement, Math.min(length - read, MAX_IO_LENGTH)));
if (result < 0) return read;
read += result;
displacement += result;
if (displacement == a[segment].length) {
segment++;
displacement = 0;
}
} while(read < length);
return read;
}
private static void write(final OutputStream outputStream, final byte a[][], final long offset, final long length) throws IOException {
if (length == 0) return;
long written = 0;
int toWrite;
int segment = segment(offset);
int displacement = displacement(offset);
do {
toWrite = (int)Math.min(a[segment].length - displacement, Math.min(length - written, MAX_IO_LENGTH));
outputStream.write(a[segment], displacement, toWrite);
written += toWrite;
displacement += toWrite;
if (displacement == a[segment].length) {
segment++;
displacement = 0;
}
} while(written < length);
}
private static void write(final DataOutput dataOutput, final byte a[][], final long offset, final long length) throws IOException {
if (length == 0) return;
long written = 0;
int toWrite;
int segment = segment(offset);
int displacement = displacement(offset);
do {
toWrite = (int)Math.min(a[segment].length - displacement, Math.min(length - written, MAX_IO_LENGTH));
dataOutput.write(a[segment], displacement, toWrite);
written += toWrite;
displacement += toWrite;
if (displacement == a[segment].length) {
segment++;
displacement = 0;
}
} while(written < length);
}
// Additional read/write methods to work around the DataInput/DataOutput schizophrenia.
/** Loads bytes from a given input stream, storing them in a given big-array fragment.
*
*
Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[][],long,long)}
* as it uses {@link InputStream}'s bulk-read methods.
*
* @param inputStream an input stream.
* @param array a big array which will be filled with data from {@code inputStream}.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from {@code inputStream} (it might be less than {@code length} if {@code inputStream} ends).
*/
public static long LOAD_KEYS(final InputStream inputStream, final KEY_TYPE[][] array, final long offset, final long length) throws IOException {
return read(inputStream, array, offset, length);
}
/** Loads bytes from a given input stream, storing them in a given big array.
*
*
Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[][])}
* as it uses {@link InputStream}'s bulk-read methods.
*
* @param inputStream an input stream.
* @param array a big array which will be filled with data from {@code inputStream}.
* @return the number of elements actually read from {@code inputStream} (it might be less than the array length if {@code inputStream} ends).
*/
public static long LOAD_KEYS(final InputStream inputStream, final KEY_TYPE[][] array) throws IOException {
return read(inputStream, array, 0, length(array));
}
/** Stores a big-array fragment to a given output stream.
*
*
Note that this method is going to be significantly faster than {@link #storeBytes(byte[][],long,long,DataOutput)}
* as it uses {@link OutputStream}'s bulk-read methods.
*
* @param array a big array whose elements will be written to {@code outputStream}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param outputStream an output stream.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final OutputStream outputStream) throws IOException {
write(outputStream, array, offset, length);
}
/** Stores a big array to a given output stream.
*
*
Note that this method is going to be significantly faster than {@link #storeBytes(byte[][],DataOutput)}
* as it uses {@link OutputStream}'s bulk-read methods.
*
* @param array a big array whose elements will be written to {@code outputStream}.
* @param outputStream an output stream.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final OutputStream outputStream) throws IOException {
write(outputStream, array, 0, length(array));
}
#endif
/** Loads elements from a given data input, storing them in a given array fragment.
*
* @param dataInput a data input.
* @param array an array which will be filled with data from {@code dataInput}.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from {@code dataInput} (it might be less than {@code length} if {@code dataInput} ends).
*/
public static int LOAD_KEYS(final DataInput dataInput, final KEY_TYPE[] array, final int offset, final int length) throws IOException {
PACKAGE.ARRAYS.ensureOffsetLength(array, offset, length);
int i = 0;
try {
for(i = 0; i < length; i++) array[i + offset] = dataInput.READ_KEY();
}
catch(EOFException itsOk) {}
return i;
}
/** Loads elements from a given data input, storing them in a given array.
*
* @param dataInput a data input.
* @param array an array which will be filled with data from {@code dataInput}.
* @return the number of elements actually read from {@code dataInput} (it might be less than the array length if {@code dataInput} ends).
*/
public static int LOAD_KEYS(final DataInput dataInput, final KEY_TYPE[] array) throws IOException {
int i = 0;
try {
final int length = array.length;
for(i = 0; i < length; i++) array[i] = dataInput.READ_KEY();
}
catch(EOFException itsOk) {}
return i;
}
/** Loads elements from a file given by a {@link File} object, storing them in a given array fragment.
*
* @param file a file.
* @param array an array which will be filled with data from the specified file.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from the given file (it might be less than {@code length} if the file is too short).
*/
public static int LOAD_KEYS(final File file, final KEY_TYPE[] array, final int offset, final int length) throws IOException {
PACKAGE.ARRAYS.ensureOffsetLength(array, offset, length);
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Byte
final int result = read(fis, array, offset, length);
fis.close();
return result;
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
int i = 0;
try {
for(i = 0; i < length; i++) array[i + offset] = dis.READ_KEY();
}
catch(EOFException itsOk) {}
dis.close();
return i;
#endif
}
/** Loads elements from a file given by a pathname, storing them in a given array fragment.
*
* @param filename a filename.
* @param array an array which will be filled with data from the specified file.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from the given file (it might be less than {@code length} if the file is too short).
*/
public static int LOAD_KEYS(final CharSequence filename, final KEY_TYPE[] array, final int offset, final int length) throws IOException {
return LOAD_KEYS(new File(filename.toString()), array, offset, length);
}
/** Loads elements from a file given by a {@link File} object, storing them in a given array.
*
* @param file a file.
* @param array an array which will be filled with data from the specified file.
* @return the number of elements actually read from the given file (it might be less than the array length if the file is too short).
*/
public static int LOAD_KEYS(final File file, final KEY_TYPE[] array) throws IOException {
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Byte
final int result = read(fis, array, 0, array.length);
fis.close();
return result;
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
int i = 0;
try {
final int length = array.length;
for(i = 0; i < length; i++) array[i] = dis.READ_KEY();
}
catch(EOFException itsOk) {}
dis.close();
return i;
#endif
}
/** Loads elements from a file given by a pathname, storing them in a given array.
*
* @param filename a filename.
* @param array an array which will be filled with data from the specified file.
* @return the number of elements actually read from the given file (it might be less than the array length if the file is too short).
*/
public static int LOAD_KEYS(final CharSequence filename, final KEY_TYPE[] array) throws IOException {
return LOAD_KEYS(new File(filename.toString()), array);
}
/** Loads elements from a file given by a {@link File} object, storing them in a new array.
*
*
Note that the length of the returned array will be computed
* dividing the specified file size by the number of bytes used to
* represent each element.
*
* @param file a file.
* @return an array filled with the content of the specified file.
*/
public static KEY_TYPE[] LOAD_KEYS(final File file) throws IOException {
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Boolean
final long length = fis.getChannel().size();
#else
final long length = fis.getChannel().size() / (KEY_CLASS.SIZE / 8);
#endif
if (length > Integer.MAX_VALUE) {
fis.close();
throw new IllegalArgumentException("File too long: " + fis.getChannel().size()+ " bytes (" + length + " elements)");
}
final KEY_TYPE[] array = new KEY_TYPE[(int)length];
#if KEY_CLASS_Byte
if (read(fis, array, 0, (int)length) < length) throw new EOFException();
fis.close();
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
for(int i = 0; i < length; i++) array[i] = dis.READ_KEY();
dis.close();
#endif
return array;
}
/** Loads elements from a file given by a filename, storing them in a new array.
*
*
Note that the length of the returned array will be computed
* dividing the specified file size by the number of bytes used to
* represent each element.
*
* @param filename a filename.
* @return an array filled with the content of the specified file.
*/
public static KEY_TYPE[] LOAD_KEYS(final CharSequence filename) throws IOException {
return LOAD_KEYS(new File(filename.toString()));
}
/** Stores an array fragment to a given data output.
*
* @param array an array whose elements will be written to {@code dataOutput}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param dataOutput a data output.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final DataOutput dataOutput) throws IOException {
PACKAGE.ARRAYS.ensureOffsetLength(array, offset, length);
#if KEY_CLASS_Byte
write(dataOutput, array, offset, length);
#else
for(int i = 0; i < length; i++) dataOutput.WRITE_KEY(array[offset + i]);
#endif
}
/** Stores an array to a given data output.
*
* @param array an array whose elements will be written to {@code dataOutput}.
* @param dataOutput a data output.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final DataOutput dataOutput) throws IOException {
#if KEY_CLASS_Byte
write(dataOutput, array, 0, array.length);
#else
final int length = array.length;
for(int i = 0; i < length; i++) dataOutput.WRITE_KEY(array[i]);
#endif
}
/** Stores an array fragment to a file given by a {@link File} object.
*
* @param array an array whose elements will be written to {@code filename}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param file a file.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final File file) throws IOException {
PACKAGE.ARRAYS.ensureOffsetLength(array, offset, length);
#if KEY_CLASS_Byte
final OutputStream os = new FastBufferedOutputStream(new FileOutputStream(file));
write(os, array, offset, length);
os.close();
#else
final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
for(int i = 0; i < length; i++) dos.WRITE_KEY(array[offset + i]);
dos.close();
#endif
}
/** Stores an array fragment to a file given by a pathname.
*
* @param array an array whose elements will be written to {@code filename}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param filename a filename.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final CharSequence filename) throws IOException {
STORE_KEYS(array, offset, length, new File(filename.toString()));
}
/** Stores an array to a file given by a {@link File} object.
*
* @param array an array whose elements will be written to {@code filename}.
* @param file a file.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final File file) throws IOException {
#if KEY_CLASS_Byte
final OutputStream os = new FastBufferedOutputStream(new FileOutputStream(file));
write(os, array, 0, array.length);
os.close();
#else
final int length = array.length;
final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
for(int i = 0; i < length; i++) dos.WRITE_KEY(array[i]);
dos.close();
#endif
}
/** Stores an array to a file given by a pathname.
*
* @param array an array whose elements will be written to {@code filename}.
* @param filename a filename.
*/
public static void STORE_KEYS(final KEY_TYPE array[], final CharSequence filename) throws IOException {
STORE_KEYS(array, new File(filename.toString()));
}
/** Loads elements from a given data input, storing them in a given big-array fragment.
*
* @param dataInput a data input.
* @param array a big array which will be filled with data from {@code dataInput}.
* @param offset the index of the first element of {@code bigArray} to be filled.
* @param length the number of elements of {@code bigArray} to be filled.
* @return the number of elements actually read from {@code dataInput} (it might be less than {@code length} if {@code dataInput} ends).
*/
public static long LOAD_KEYS(final DataInput dataInput, final KEY_TYPE[][] array, final long offset, final long length) throws IOException {
ensureOffsetLength(array, offset, length);
long c = 0;
try {
for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) {
final KEY_TYPE[] t = array[i];
final int l = (int)Math.min(t.length, offset + length - start(i));
for(int d = (int)Math.max(0, offset - start(i)); d < l; d++) {
t[d] = dataInput.READ_KEY();
c++;
}
}
}
catch(EOFException itsOk) {}
return c;
}
/** Loads elements from a given data input, storing them in a given big array.
*
* @param dataInput a data input.
* @param array a big array which will be filled with data from {@code dataInput}.
* @return the number of elements actually read from {@code dataInput} (it might be less than the array length if {@code dataInput} ends).
*/
public static long LOAD_KEYS(final DataInput dataInput, final KEY_TYPE[][] array) throws IOException {
long c = 0;
try {
for(int i = 0; i < array.length; i++) {
final KEY_TYPE[] t = array[i];
final int l = t.length;
for(int d = 0; d < l; d++) {
t[d] = dataInput.READ_KEY();
c++;
}
}
}
catch(EOFException itsOk) {}
return c;
}
/** Loads elements from a file given by a {@link File} object, storing them in a given big-array fragment.
*
* @param file a file.
* @param array a big array which will be filled with data from the specified file.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from the given file (it might be less than {@code length} if the file is too short).
*/
public static long LOAD_KEYS(final File file, final KEY_TYPE[][] array, final long offset, final long length) throws IOException {
ensureOffsetLength(array, offset, length);
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Byte
final long result = read(fis, array, offset, length);
fis.close();
return result;
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
long c = 0;
try {
for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) {
final KEY_TYPE[] t = array[i];
final int l = (int)Math.min(t.length, offset + length - start(i));
for(int d = (int)Math.max(0, offset - start(i)); d < l; d++) {
t[d] = dis.READ_KEY();
c++;
}
}
}
catch(EOFException itsOk) {}
dis.close();
return c;
#endif
}
/** Loads elements from a file given by a pathname, storing them in a given big-array fragment.
*
* @param filename a filename.
* @param array an array which will be filled with data from the specified file.
* @param offset the index of the first element of {@code array} to be filled.
* @param length the number of elements of {@code array} to be filled.
* @return the number of elements actually read from the given file (it might be less than {@code length} if the file is too short).
*/
public static long LOAD_KEYS(final CharSequence filename, final KEY_TYPE[][] array, final long offset, final long length) throws IOException {
return LOAD_KEYS(new File(filename.toString()), array, offset, length);
}
/** Loads elements from a file given by a {@link File} object, storing them in a given big array.
*
* @param file a file.
* @param array a big array which will be filled with data from the specified file.
* @return the number of elements actually read from the given file (it might be less than the array length if the file is too short).
*/
public static long LOAD_KEYS(final File file, final KEY_TYPE[][] array) throws IOException {
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Byte
final long result = read(fis, array, 0, length(array));
fis.close();
return result;
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
long c = 0;
try {
for(int i = 0; i < array.length; i++) {
final KEY_TYPE[] t = array[i];
final int l = t.length;
for(int d = 0; d < l; d++) {
t[d] = dis.READ_KEY();
c++;
}
}
}
catch(EOFException itsOk) {}
dis.close();
return c;
#endif
}
/** Loads elements from a file given by a pathname, storing them in a given big array.
*
* @param filename a filename.
* @param array a big array which will be filled with data from the specified file.
* @return the number of elements actually read from the given file (it might be less than the array length if the file is too short).
*/
public static long LOAD_KEYS(final CharSequence filename, final KEY_TYPE[][] array) throws IOException {
return LOAD_KEYS(new File(filename.toString()), array);
}
/** Loads elements from a file given by a {@link File} object, storing them in a new big array.
*
*
Note that the length of the returned big array will be computed
* dividing the specified file size by the number of bytes used to
* represent each element.
*
* @param file a file.
* @return a big array filled with the content of the specified file.
*/
public static KEY_TYPE[][] LOAD_KEYS_BIG(final File file) throws IOException {
final FileInputStream fis = new FileInputStream(file);
#if KEY_CLASS_Boolean
final long length = fis.getChannel().size();
#else
final long length = fis.getChannel().size() / (KEY_CLASS.SIZE / 8);
#endif
final KEY_TYPE[][] array = BIG_ARRAYS.newBigArray(length);
#if KEY_CLASS_Byte
if (read(fis, array, 0, length) < length) throw new EOFException();
fis.close();
#else
final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis));
for(int i = 0; i < array.length; i++) {
final KEY_TYPE[] t = array[i];
final int l = t.length;
for(int d = 0; d < l; d++) t[d] = dis.READ_KEY();
}
dis.close();
#endif
return array;
}
/** Loads elements from a file given by a filename, storing them in a new big array.
*
*
Note that the length of the returned big array will be computed
* dividing the specified file size by the number of bytes used to
* represent each element.
*
* @param filename a filename.
* @return a big array filled with the content of the specified file.
*/
public static KEY_TYPE[][] LOAD_KEYS_BIG(final CharSequence filename) throws IOException {
return LOAD_KEYS_BIG(new File(filename.toString()));
}
/** Stores an array fragment to a given data output.
*
* @param array an array whose elements will be written to {@code dataOutput}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param dataOutput a data output.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final DataOutput dataOutput) throws IOException {
ensureOffsetLength(array, offset, length);
#if KEY_CLASS_Byte
write(dataOutput, array, offset, length);
#else
for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) {
final KEY_TYPE[] t = array[i];
final int l = (int)Math.min(t.length, offset + length - start(i));
for(int d = (int)Math.max(0, offset - start(i)); d < l; d++) dataOutput.WRITE_KEY(t[d]);
}
#endif
}
/** Stores a big array to a given data output.
*
* @param array a big array whose elements will be written to {@code dataOutput}.
* @param dataOutput a data output.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final DataOutput dataOutput) throws IOException {
#if KEY_CLASS_Byte
write(dataOutput, array, 0, length(array));
#else
for(int i = 0; i < array.length; i++) {
final KEY_TYPE[] t = array[i];
final int l = t.length;
for(int d = 0; d < l; d++) dataOutput.WRITE_KEY(t[d]);
}
#endif
}
/** Stores a big-array fragment to a file given by a {@link File} object.
*
* @param array a big array whose elements will be written to {@code filename}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param file a file.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final File file) throws IOException {
ensureOffsetLength(array, offset, length);
#if KEY_CLASS_Byte
final OutputStream os = new FastBufferedOutputStream(new FileOutputStream(file));
write(os, array, offset, length);
os.close();
#else
final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) {
final KEY_TYPE[] t = array[i];
final int l = (int)Math.min(t.length, offset + length - start(i));
for(int d = (int)Math.max(0, offset - start(i)); d < l; d++) dos.WRITE_KEY(t[d]);
}
dos.close();
#endif
}
/** Stores a big-array fragment to a file given by a pathname.
*
* @param array a big array whose elements will be written to {@code filename}.
* @param offset the index of the first element of {@code array} to be written.
* @param length the number of elements of {@code array} to be written.
* @param filename a filename.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final CharSequence filename) throws IOException {
STORE_KEYS(array, offset, length, new File(filename.toString()));
}
/** Stores an array to a file given by a {@link File} object.
*
* @param array an array whose elements will be written to {@code filename}.
* @param file a file.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final File file) throws IOException {
#if KEY_CLASS_Byte
final OutputStream os = new FastBufferedOutputStream(new FileOutputStream(file));
write(os, array, 0, length(array));
os.close();
#else
final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
for(int i = 0; i < array.length; i++) {
final KEY_TYPE[] t = array[i];
final int l = t.length;
for(int d = 0; d < l; d++) dos.WRITE_KEY(t[d]);
}
dos.close();
#endif
}
/** Stores a big array to a file given by a pathname.
*
* @param array a big array whose elements will be written to {@code filename}.
* @param filename a filename.
*/
public static void STORE_KEYS(final KEY_TYPE array[][], final CharSequence filename) throws IOException {
STORE_KEYS(array, new File(filename.toString()));
}
/** Stores the element returned by an iterator to a given data output.
*
* @param i an iterator whose output will be written to {@code dataOutput}.
* @param dataOutput a filename.
*/
public static void STORE_KEYS(final KEY_ITERATOR i, final DataOutput dataOutput) throws IOException {
while(i.hasNext()) dataOutput.WRITE_KEY(i.NEXT_KEY());
}
/** Stores the element returned by an iterator to a file given by a {@link File} object.
*
* @param i an iterator whose output will be written to {@code filename}.
* @param file a file.
*/
public static void STORE_KEYS(final KEY_ITERATOR i, final File file) throws IOException {
final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file)));
while(i.hasNext()) dos.WRITE_KEY(i.NEXT_KEY());
dos.close();
}
/** Stores the element returned by an iterator to a file given by a pathname.
*
* @param i an iterator whose output will be written to {@code filename}.
* @param filename a filename.
*/
public static void STORE_KEYS(final KEY_ITERATOR i, final CharSequence filename) throws IOException {
STORE_KEYS(i, new File(filename.toString()));
}
/** A wrapper that exhibits the content of a data input stream as a type-specific iterator. */
private static final class KEY_DATA_INPUT_WRAPPER implements KEY_ITERATOR {
private final DataInput dataInput;
private boolean toAdvance = true;
private boolean endOfProcess = false;
private KEY_TYPE next;
public KEY_DATA_INPUT_WRAPPER(final DataInput dataInput) {
this.dataInput = dataInput;
}
@Override
public boolean hasNext() {
if (! toAdvance) return ! endOfProcess;
toAdvance = false;
try { next = dataInput.READ_KEY(); }
catch(EOFException eof) { endOfProcess = true; }
catch(IOException rethrow) { throw new RuntimeException(rethrow); }
return ! endOfProcess;
}
@Override
public KEY_TYPE NEXT_KEY() {
if (! hasNext()) throw new NoSuchElementException();
toAdvance = true;
return next;
}
}
/** Wraps the given data input stream into an iterator.
*
* @param dataInput a data input.
*/
public static KEY_ITERATOR AS_KEY_ITERATOR(final DataInput dataInput) {
return new KEY_DATA_INPUT_WRAPPER(dataInput);
}
/** Wraps a file given by a {@link File} object into an iterator.
*
* @param file a file.
*/
public static KEY_ITERATOR AS_KEY_ITERATOR(final File file) throws IOException {
return new KEY_DATA_INPUT_WRAPPER(new DataInputStream(new FastBufferedInputStream(new FileInputStream(file))));
}
/** Wraps a file given by a pathname into an iterator.
*
* @param filename a filename.
*/
public static KEY_ITERATOR AS_KEY_ITERATOR(final CharSequence filename) throws IOException {
return AS_KEY_ITERATOR(new File(filename.toString()));
}
/** Wraps a file given by a {@link File} object into an iterable object.
*
* @param file a file.
*/
public static KEY_ITERABLE AS_KEY_ITERABLE(final File file) {
return () -> {
try { return AS_KEY_ITERATOR(file); }
catch(IOException e) { throw new RuntimeException(e); }
};
}
/** Wraps a file given by a pathname into an iterable object.
*
* @param filename a filename.
*/
public static KEY_ITERABLE AS_KEY_ITERABLE(final CharSequence filename) {
return () -> {
try { return AS_KEY_ITERATOR(filename); }
catch(IOException e) { throw new RuntimeException(e); }
};
}