All Downloads are FREE. Search and download functionalities are using the official Maven repository.

drv.BinIOFragment.drv Maven / Gradle / Ivy

Go to download

fastutil extends the Java Collections Framework by providing type-specific maps, sets, lists, and queues with a small memory footprint and fast operations; it provides also big (64-bit) arrays, sets, and lists, sorting algorithms, fast, practical I/O classes for binary and text files, and facilities for memory mapping large files. This jar (fastutil-core.jar) contains data structures based on integers, longs, doubles, and objects, only; fastutil.jar contains all classes. If you have both jars in your dependencies, this jar should be excluded.

There is a newer version: 8.5.15
Show newest version
/*
 * Copyright (C) 2004-2022 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 loadBytes(final InputStream inputStream, final byte[] 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 loadBytes(final InputStream inputStream, final byte[] array) throws IOException { return read(inputStream, array, 0, array.length); } /** Stores an array fragment to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #storeBytes(byte[],int,int,DataOutput)} * as it uses {@link OutputStream}'s bulk-write 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 storeBytes(final byte array[], final int offset, final int length, final OutputStream outputStream) throws IOException { write(outputStream, array, offset, length); } /** Stores an array to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #storeBytes(byte[],DataOutput)} * as it uses {@link OutputStream}'s bulk-write methods. * * @param array an array whose elements will be written to {@code outputStream}. * @param outputStream an output stream. */ public static void storeBytes(final byte 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 readable channel, 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 loadBytes(final InputStream inputStream, final byte[][] array, final long offset, final long length) throws IOException { return read(inputStream, array, offset, length); } /** Loads bytes from a given readable channel, 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 loadBytes(final InputStream inputStream, final byte[][] array) throws IOException { return read(inputStream, array, 0, length(array)); } /** Stores a big-array fragment to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #storeBytes(byte[][],long,long,DataOutput)} * as it uses {@link OutputStream}'s bulk-write 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 storeBytes(final byte array[][], final long offset, final long length, final OutputStream outputStream) throws IOException { write(outputStream, array, offset, length); } /** Stores a big array to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #storeBytes(byte[][],DataOutput)} * as it uses {@link OutputStream}'s bulk-write methods. * * @param array a big array whose elements will be written to {@code outputStream}. * @param outputStream an output stream. */ public static void storeBytes(final byte array[][], final OutputStream outputStream) throws IOException { write(outputStream, array, 0, length(array)); } // Methods working with channels. /** Loads bytes from a given readable channel, 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 ReadableByteChannel}'s bulk-read methods. * * @param channel a readable channel. * @param array an array which will be filled with data from {@code channel}. * @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 channel} (it might be less than {@code length} if {@code channel} ends). */ public static int loadBytes(final ReadableByteChannel channel, final byte[] array, int offset, int length) throws IOException { ensureOffsetLength(array.length, offset, length); ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE); int read = 0; for (;;) { buffer.clear(); buffer.limit(Math.min(buffer.capacity(), length)); int r = channel.read(buffer); if (r <= 0) return read; read += r; buffer.flip(); buffer.get(array, offset, r); offset += r; length -= r; } } /** Loads bytes from a given readable channel, storing them in a given array. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link ReadableByteChannel}'s bulk-read methods. * * @param channel a readable channel. * @param array an array which will be filled with data from {@code channel}. * @return the number of elements actually read from {@code channel} (it might be less than the array length if {@code channel} ends). */ public static int loadBytes(final ReadableByteChannel channel, final byte[] array) throws IOException { return loadBytes(channel, array, 0, array.length); } /** Stores an array fragment to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link WritableByteChannel}'s bulk-write methods. * * @param array an array whose elements will be written to {@code channel}. * @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 channel a writable channel. */ public static void storeBytes(final byte array[], int offset, int length, final WritableByteChannel channel) throws IOException { ensureOffsetLength(array.length, offset, length); ByteBuffer buffer = ByteBuffer.allocateDirect(BUFFER_SIZE); while(length != 0) { final int l = Math.min(length, buffer.capacity()); buffer.clear(); buffer.put(array, offset, l); buffer.flip(); channel.write(buffer); offset += l; length -= l; } } /** Stores an array to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link WritableByteChannel}'s bulk-write methods. * * @param array an array whose elements will be written to {@code channel}. * @param channel a writable channel. */ public static void storeBytes(final byte array[], final WritableByteChannel channel) throws IOException { storeBytes(array, 0, array.length, channel); } /** Loads bytes from a given readable channel, storing them in a given big-array fragment. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link ReadableByteChannel}'s bulk-read methods. * * @param channel a readable channel. * @param array a big array which will be filled with data from {@code channel}. * @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 channel} (it might be less than {@code length} if {@code channel} ends). */ public static long loadBytes(final ReadableByteChannel channel, final byte[][] array, final long offset, final long length) throws IOException { ensureOffsetLength(array, offset, length); long read = 0; for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) { final byte[] t = array[i]; final int s = (int)Math.max(0, offset - start(i)); final int e = (int)Math.min(t.length, offset + length - start(i)); final int r = loadBytes(channel, t, s, e - s); read += r; if (r < e -s) break; } return read; } /** Loads bytes from a given readable channel, storing them in a given big array. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link ReadableByteChannel}'s bulk-read methods. * * @param channel a readable channel. * @param array a big array which will be filled with data from {@code channel}. * @return the number of elements actually read from {@code channel} (it might be less than the array length if {@code channel} ends). */ public static long loadBytes(final ReadableByteChannel channel, final byte[][] array) throws IOException { return loadBytes(channel, array, 0, length(array)); } /** Stores a big-array fragment to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link WritableByteChannel}'s bulk-write methods. * * @param array a big array whose elements will be written to {@code channel}. * @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 channel a writable channel. */ public static void storeBytes(final byte array[][], final long offset, final long length, final WritableByteChannel channel) throws IOException { for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) { final int s = (int)Math.max(0, offset - start(i)); final int l = (int)Math.min(array[i].length, offset + length - start(i)); storeBytes(array[i], s, l - s, channel); } } /** Stores a big array to a given writable channel. * *

Note that this method is going to be significantly faster than {@link #loadBytes(DataInput,byte[],int,int)} * as it uses {@link WritableByteChannel}'s bulk-write methods. * * @param array a big array whose elements will be written to {@code channel}. * @param channel a writable channel. */ public static void storeBytes(final byte array[][], final WritableByteChannel channel) throws IOException { for(byte[] t: array) storeBytes(t, channel); } #elif ! KEY_CLASS_Boolean /** Loads elements from a given readable channel, using the given byte order, storing them in a given array fragment. * * @param channel a readable channel. * @param byteOrder the byte order of the data from {@code channel}. * @param array an array which will be filled with data from {@code channel}. * @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 channel} (it might be less than {@code length} if {@code channel} ends). */ public static int LOAD_KEYS(final ReadableByteChannel channel, final ByteOrder byteOrder, final KEY_TYPE[] array, int offset, int length) throws IOException { ensureOffsetLength(array.length, offset, length); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE).order(byteOrder); final KEY_BUFFER buffer = byteBuffer.AS_KEY_BUFFER(); int read = 0; for (;;) { byteBuffer.clear(); byteBuffer.limit((int)Math.min(buffer.capacity(), (long)length << MAPPED_BIG_LIST.LOG2_BYTES)); int r = channel.read(byteBuffer); if (r <= 0) return read; r >>>= MAPPED_BIG_LIST.LOG2_BYTES; read += r; // TODO: use the indexed get() method when switching to Java 13+ buffer.clear(); buffer.limit(r); buffer.get(array, offset, r); offset += r; length -= r; } } /** Loads elements from a given readable channel, using the given byte order, storing them in a given array. * * @param channel a readable channel. * @param byteOrder the byte order of the data from {@code channel}. * @param array an array which will be filled with data from {@code channel}. * @return the number of elements actually read from {@code channel} (it might be less than the array length if {@code channel} ends). */ public static int LOAD_KEYS(final ReadableByteChannel channel, final ByteOrder byteOrder, final KEY_TYPE[] array) throws IOException { return LOAD_KEYS(channel, byteOrder, array, 0, array.length); } /** Loads elements from a file given by a {@link File} object, using the given byte order, storing them in a given array fragment. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code 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 ByteOrder byteOrder, final KEY_TYPE[] array, final int offset, final int length) throws IOException { ensureOffsetLength(array.length, offset, length); final FileChannel channel = FileChannel.open(file.toPath()); final int read = LOAD_KEYS(channel, byteOrder, array, offset, length); channel.close(); return read; } /** Loads elements from a file given by a filename, using the given byte order, storing them in a given array fragment. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code 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 ByteOrder byteOrder, final KEY_TYPE[] array, final int offset, final int length) throws IOException { return LOAD_KEYS(new File(filename.toString()), byteOrder, array, offset, length); } /** Loads elements from a file given by a {@link File} object, using the given byte order, storing them in a given array. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code 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 ByteOrder byteOrder, final KEY_TYPE[] array) throws IOException { return LOAD_KEYS(file, byteOrder, array, 0, array.length); } /** Loads elements from a file given by a filename, using the given byte order, storing them in a given array. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code 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 ByteOrder byteOrder, final KEY_TYPE[] array) throws IOException { return LOAD_KEYS(new File(filename.toString()), byteOrder, array); } /** Loads elements from a file given by a {@link File} object, using the given byte order, 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. * @param byteOrder the byte order of the data stored in {@code file}. * @return an array filled with the content of the specified file. */ public static KEY_TYPE[] LOAD_KEYS(final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath()); final long length = channel.size() / KEY_CLASS.BYTES; if (length > Integer.MAX_VALUE) { channel.close(); throw new IllegalArgumentException("File too long: " + channel.size()+ " bytes (" + length + " elements)"); } final KEY_TYPE[] array = new KEY_TYPE[(int)length]; if (LOAD_KEYS(channel, byteOrder, array) < length) throw new EOFException(); channel.close(); return array; } /** Loads elements from a file given by a filename, using the given byte order, 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, final ByteOrder byteOrder) throws IOException { return LOAD_KEYS(new File(filename.toString()), byteOrder); } /** Stores an array fragment to a given writable channel, using the given byte order. * * @param array an array whose elements will be written to {@code channel}. * @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 channel a writable channel. * @param byteOrder the byte order to be used to store data in {@code channel}. */ public static void STORE_KEYS(final KEY_TYPE array[], int offset, int length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException { ensureOffsetLength(array.length, offset, length); ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE).order(byteOrder); final KEY_BUFFER buffer = byteBuffer.AS_KEY_BUFFER(); while(length != 0) { final int l = Math.min(length, buffer.capacity()); buffer.clear(); buffer.put(array, offset, l); buffer.flip(); byteBuffer.clear(); byteBuffer.limit(buffer.limit() << MAPPED_BIG_LIST.LOG2_BYTES); channel.write(byteBuffer); offset += l; length -= l; } } /** Stores an array to a given writable channel, using the given byte order. * * @param array an array whose elements will be written to {@code channel}. * @param channel a writable channel. * @param byteOrder the byte order to be used to store data in {@code channel}. */ public static void STORE_KEYS(final KEY_TYPE array[], final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, 0, array.length, channel, byteOrder); } /** Stores an array fragment to a file given by a {@link File} object, using the given byte order. * * @param array an array whose elements will be written to {@code file}. * @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. * @param byteOrder the byte order to be used to store data in {@code file}. */ public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); STORE_KEYS(array, offset, length, channel, byteOrder); channel.close(); } /** Stores an array fragment to a file given by a filename, using the given byte order. * * @param array an array whose elements will be written to the file {@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. * @param byteOrder the byte order to be used to store data in the file {@code filename}. */ public static void STORE_KEYS(final KEY_TYPE array[], final int offset, final int length, final CharSequence filename, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, offset, length, new File(filename.toString()), byteOrder); } /** Stores an array to a file given by a {@link File} object, using the given byte order. * * @param array an array whose elements will be written to {@code file}. * @param file a file. * @param byteOrder the byte order to be used to store data in {@code file}. */ public static void STORE_KEYS(final KEY_TYPE array[], final File file, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, 0, array.length, file, byteOrder); } /** Stores an array to a file given by a filename, using the given byte order. * * @param array an array whose elements will be written to the file {@code filename}. * @param filename a filename. * @param byteOrder the byte order to be used to store data in the file {@code filename}. */ public static void STORE_KEYS(final KEY_TYPE array[], final CharSequence filename, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, new File(filename.toString()), byteOrder); } /** Loads elements from a given readable channel, using the given byte order, storing them in a given big-array fragment. * * @param channel a readable channel. * @param byteOrder the byte order of the data from {@code channel}. * @param array a big array which will be filled with data from {@code channel}. * @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 channel} (it might be less than {@code length} if {@code channel} ends). */ public static long LOAD_KEYS(final ReadableByteChannel channel, final ByteOrder byteOrder, final KEY_TYPE[][] array, final long offset, final long length) throws IOException { ensureOffsetLength(array, offset, length); long read = 0; for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) { final KEY_TYPE[] t = array[i]; final int s = (int)Math.max(0, offset - start(i)); final int e = (int)Math.min(t.length, offset + length - start(i)); final int r = LOAD_KEYS(channel, byteOrder, t, s, e - s); read += r; if (r < e -s) break; } return read; } /** Loads elements from a given readable channel, using the given byte order, storing them in a given big array. * * @param channel a readable channel. * @param byteOrder the byte order of the data from {@code channel}. * @param array a big array which will be filled with data from {@code channel}. * @return the number of elements actually read from {@code channel} (it might be less than the array length if {@code channel} ends). */ public static long LOAD_KEYS(final ReadableByteChannel channel, final ByteOrder byteOrder, final KEY_TYPE[][] array) throws IOException { return LOAD_KEYS(channel, byteOrder, array, 0, length(array)); } /** Loads elements from a file given by a {@link File} object, using the given byte order, storing them in a given big-array fragment. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code 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 ByteOrder byteOrder, final KEY_TYPE[][] array, final long offset, final long length) throws IOException { final FileChannel channel = FileChannel.open(file.toPath()); final long read = LOAD_KEYS(channel, byteOrder, array, offset, length); channel.close(); return read; } /** Loads elements from a file given by a filename, using the given byte order, storing them in a given big-array fragment. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code 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 ByteOrder byteOrder, final KEY_TYPE[][] array, final long offset, final long length) throws IOException { return LOAD_KEYS(new File(filename.toString()), byteOrder, array, offset, length); } /** Loads elements from a file given by a {@link File} object, using the given byte order, storing them in a given big array. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code 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 ByteOrder byteOrder, final KEY_TYPE[][] array) throws IOException { return LOAD_KEYS(file, byteOrder, array, 0, length(array)); } /** Loads elements from a file given by a filename, using the given byte order, storing them in a given big array. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code 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 ByteOrder byteOrder, final KEY_TYPE[][] array) throws IOException { return LOAD_KEYS(new File(filename.toString()), byteOrder, array); } /** Loads elements from a file given by a {@link File} object, using the given byte order, 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. * @param byteOrder the byte order of the data stored in {@code file}. * @return a big array filled with the content of the specified file. */ public static KEY_TYPE[][] LOAD_KEYS_BIG(final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath()); final long length = channel.size() / KEY_CLASS.BYTES; final KEY_TYPE[][] array = BIG_ARRAYS.newBigArray(length); for(final KEY_TYPE[] t: array) LOAD_KEYS(channel, byteOrder, t); channel.close(); return array; } /** Loads elements from a file given by a filename, using the given byte order, 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. * @param byteOrder the byte order of the data stored in the file {@code filename}. * @return a big array filled with the content of the specified file. */ public static KEY_TYPE[][] LOAD_KEYS_BIG(final CharSequence filename, final ByteOrder byteOrder) throws IOException { return LOAD_KEYS_BIG(new File(filename.toString()), byteOrder); } /** Stores an array fragment to a given writable channel, using the given byte order. * * @param array an array whose elements will be written to {@code channel}. * @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 channel a writable channel. * @param byteOrder the byte order to be used to store data in {@code channel}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException { for(int i = segment(offset); i < segment(offset + length + SEGMENT_MASK); i++) { final int s = (int)Math.max(0, offset - start(i)); final int l = (int)Math.min(array[i].length, offset + length - start(i)); STORE_KEYS(array[i], s, l - s, channel, byteOrder); } } /** Stores a big array to a given writable channel, using the given byte order. * * @param array a big array whose elements will be written to {@code channel}. * @param channel a writable channel. * @param byteOrder the byte order to be used to store data in {@code channel}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException { for(KEY_TYPE[] t: array) STORE_KEYS(t, channel, byteOrder); } /** Stores a big-array fragment to a file given by a {@link File} object, using the given byte order. * * @param array a big array whose elements will be written to {@code file}. * @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. * @param byteOrder the byte order to be used to store data in {@code file}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); STORE_KEYS(array, offset, length, channel, byteOrder); channel.close(); } /** Stores a big-array fragment to a file given by a filename, using the given byte order. * * @param array a big array whose elements will be written to the file {@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. * @param byteOrder the byte order to be used to store data in the file {@code filename}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final long offset, final long length, final CharSequence filename, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, offset, length, new File(filename.toString()), byteOrder); } /** Stores an array to a file given by a {@link File} object, using the given byte order. * * @param array an array whose elements will be written to {@code file}. * @param file a file. * @param byteOrder the byte order to be used to store data in {@code file}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); STORE_KEYS(array, channel, byteOrder); channel.close(); } /** Stores a big array to a file given by a filename, using the given byte order. * * @param array a big array whose elements will be written to the file {@code filename}. * @param filename a filename. * @param byteOrder the byte order to be used to store data in the file {@code filename}. */ public static void STORE_KEYS(final KEY_TYPE array[][], final CharSequence filename, final ByteOrder byteOrder) throws IOException { STORE_KEYS(array, new File(filename.toString()), byteOrder); } /** Stores the element returned by an iterator to a given writable channel, using the given byte order. * * @param i an iterator whose output will be written to {@code channel}. * @param channel a writable channel. * @param byteOrder the byte order to be used to store data in {@code channel}. */ public static void STORE_KEYS(final KEY_ITERATOR i, final WritableByteChannel channel, final ByteOrder byteOrder) throws IOException { ByteBuffer byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE).order(byteOrder); final KEY_BUFFER buffer = byteBuffer.AS_KEY_BUFFER(); while(i.hasNext()) { if (! buffer.hasRemaining()) { buffer.flip(); byteBuffer.clear(); byteBuffer.limit(buffer.limit() << MAPPED_BIG_LIST.LOG2_BYTES); channel.write(byteBuffer); buffer.clear(); } buffer.put(i.NEXT_KEY()); } buffer.flip(); byteBuffer.clear(); byteBuffer.limit(buffer.limit() << MAPPED_BIG_LIST.LOG2_BYTES); channel.write(byteBuffer); } /** Stores the element returned by an iterator to a file given by a {@link File} object, using the given byte order. * * @param i an iterator whose output will be written to {@code file}. * @param file a file. * @param byteOrder the byte order to be used to store data in {@code file}. */ public static void STORE_KEYS(final KEY_ITERATOR i, final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); STORE_KEYS(i, channel, byteOrder); channel.close(); } /** Stores the element returned by an iterator to a file given by a filename, using the given byte order. * * @param i an iterator whose output will be written to the file {@code filename}. * @param filename a filename. * @param byteOrder the byte order to be used to store data in the file {@code filename}. */ public static void STORE_KEYS(final KEY_ITERATOR i, final CharSequence filename, final ByteOrder byteOrder) throws IOException { STORE_KEYS(i, new File(filename.toString()), byteOrder); } /** A wrapper that exhibits the content of a readable channel as a type-specific iterator. */ private static final class KEY_DATA_NIO_INPUT_WRAPPER implements KEY_ITERATOR { private final ReadableByteChannel channel; private final ByteBuffer byteBuffer; private final KEY_BUFFER buffer; public KEY_DATA_NIO_INPUT_WRAPPER(final ReadableByteChannel channel, final ByteOrder byteOrder) { this.channel = channel; byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE).order(byteOrder); buffer = byteBuffer.AS_KEY_BUFFER(); buffer.clear().flip(); } @Override public boolean hasNext() { if (! buffer.hasRemaining()) { byteBuffer.clear(); try { channel.read(byteBuffer); } catch(IOException e) { throw new RuntimeException(e); } byteBuffer.flip(); buffer.clear(); buffer.limit(byteBuffer.limit() >>> MAPPED_BIG_LIST.LOG2_BYTES); } return buffer.hasRemaining(); } @Override public KEY_TYPE NEXT_KEY() { if (! hasNext()) throw new NoSuchElementException(); return buffer.get(); } } /** Wraps the given readable channel, using the given byte order, into an iterator. * * @param channel a readable channel. * @param byteOrder the byte order of the data from {@code channel}. */ public static KEY_ITERATOR AS_KEY_ITERATOR(final ReadableByteChannel channel, final ByteOrder byteOrder) { return new KEY_DATA_NIO_INPUT_WRAPPER(channel, byteOrder); } /** Wraps a file given by a {@link File} object, using the given byte order, into an iterator. * * @implNote This method opens a {@link FileChannel} that will not be closed until * it is garbage collected. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code file}. */ public static KEY_ITERATOR AS_KEY_ITERATOR(final File file, final ByteOrder byteOrder) throws IOException { final FileChannel channel = FileChannel.open(file.toPath()); return new KEY_DATA_NIO_INPUT_WRAPPER(channel, byteOrder); } /** Wraps a file given by a filename, using the given byte order, into an iterator. * * @implNote This method opens a {@link FileChannel} that will not be closed until * it is garbage collected. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code filename}. */ public static KEY_ITERATOR AS_KEY_ITERATOR(final CharSequence filename, final ByteOrder byteOrder) throws IOException { return AS_KEY_ITERATOR(new File(filename.toString()), byteOrder); } /** Wraps a file given by a {@link File} object, using the given byte order, into an iterable object. * * @implNote Each iterator returned by this class opens a {@link FileChannel} * that will not be closed until it is garbage collected. * * @param file a file. * @param byteOrder the byte order of the data stored in {@code file}. */ public static KEY_ITERABLE AS_KEY_ITERABLE(final File file, final ByteOrder byteOrder) { return () -> { try { return AS_KEY_ITERATOR(file, byteOrder); } catch(IOException e) { throw new RuntimeException(e); } }; } /** Wraps a file given by a filename, using the given byte order, into an iterable object. * * @implNote Each iterator returned by this class opens a {@link FileChannel} * that will not be closed until it is garbage collected. * * @param filename a filename. * @param byteOrder the byte order of the data stored in the file {@code filename}. */ public static KEY_ITERABLE AS_KEY_ITERABLE(final CharSequence filename, final ByteOrder byteOrder) { return () -> { try { return AS_KEY_ITERATOR(filename, byteOrder); } catch(IOException e) { throw new RuntimeException(e); } }; } #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 { ensureOffsetLength(array.length, 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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath()); final int result = loadBytes(channel, array, offset, length); channel.close(); return result; #elif KEY_CLASS_Boolean ensureOffsetLength(array.length, offset, length); final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(new FileInputStream(file))); int i = 0; try { for(i = 0; i < length; i++) array[i + offset] = dis.READ_KEY(); } catch(EOFException itsOk) {} dis.close(); return i; #else return LOAD_KEYS(file, ByteOrder.BIG_ENDIAN, array, offset, length); #endif } /** Loads elements from a file given by a filename, 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 { return LOAD_KEYS(file, array, 0, array.length); } /** Loads elements from a file given by a filename, 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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath()); final long length = channel.size(); if (length > Integer.MAX_VALUE) { channel.close(); throw new IllegalArgumentException("File too long: " + channel.size()+ " bytes (" + length + " elements)"); } final byte[] array = new byte[(int)length]; if (loadBytes(channel, array) < length) throw new EOFException(); return array; #elif KEY_CLASS_Boolean final FileInputStream fis = new FileInputStream(file); final long length = fis.getChannel().size(); if (length > Integer.MAX_VALUE) { fis.close(); throw new IllegalArgumentException("File too long: " + fis.getChannel().size()+ " bytes (" + length + " elements)"); } final boolean[] array = new boolean[(int)length]; final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis)); for(int i = 0; i < length; i++) array[i] = dis.READ_KEY(); dis.close(); return array; #else return LOAD_KEYS(file, ByteOrder.BIG_ENDIAN); #endif } /** 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 { ensureOffsetLength(array.length, 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 file}. * @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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); storeBytes(array, offset, length, channel); channel.close(); #elif KEY_CLASS_Boolean ensureOffsetLength(array.length, offset, length); final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file))); for(int i = 0; i < length; i++) dos.writeBoolean(array[offset + i]); dos.close(); #else STORE_KEYS(array, offset, length, file, ByteOrder.BIG_ENDIAN); #endif } /** Stores an array fragment to a file given by a filename. * * @param array an array whose elements will be written to the file {@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 file}. * @param file a file. */ public static void STORE_KEYS(final KEY_TYPE array[], final File file) throws IOException { STORE_KEYS(array, 0, array.length, file); } /** Stores an array to a file given by a filename. * * @param array an array whose elements will be written to the file {@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 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 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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath()); final long read = LOAD_KEYS(channel, array, offset, length); return read; #elif KEY_CLASS_Boolean ensureOffsetLength(array, offset, length); final FileInputStream fis = new FileInputStream(file); 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.readBoolean(); c++; } } } catch(EOFException itsOk) {} dis.close(); return c; #else return LOAD_KEYS(file, ByteOrder.BIG_ENDIAN, array, offset, length); #endif } /** Loads elements from a file given by a filename, 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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath()); final long read = LOAD_KEYS(channel, array); return read; #elif KEY_CLASS_Boolean final FileInputStream fis = new FileInputStream(file); 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.readBoolean(); c++; } } } catch(EOFException itsOk) {} dis.close(); return c; #else return LOAD_KEYS(file, ByteOrder.BIG_ENDIAN, array); #endif } /** Loads elements from a file given by a filename, 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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath()); final long length = channel.size(); final byte[][] array = ByteBigArrays.newBigArray(length); loadBytes(channel, array); channel.close(); return array; #elif KEY_CLASS_Boolean final FileInputStream fis = new FileInputStream(file); final long length = fis.getChannel().size(); final KEY_TYPE[][] array = BooleanBigArrays.newBigArray(length); final DataInputStream dis = new DataInputStream(new FastBufferedInputStream(fis)); for(int i = 0; i < array.length; i++) { final boolean[] t = array[i]; final int l = t.length; for(int d = 0; d < l; d++) t[d] = dis.readBoolean(); } dis.close(); return array; #else return LOAD_KEYS_BIG(file, ByteOrder.BIG_ENDIAN); #endif } /** 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 file}. * @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 { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); storeBytes(array, offset, length, channel); channel.close(); #elif KEY_CLASS_Boolean 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(); #else STORE_KEYS(array, offset, length, file, ByteOrder.BIG_ENDIAN); #endif } /** Stores a big-array fragment to a file given by a filename. * * @param array a big array whose elements will be written to the file {@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 file}. * @param file a file. */ public static void STORE_KEYS(final KEY_TYPE array[][], final File file) throws IOException { #if KEY_CLASS_Byte final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.WRITE, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); storeBytes(array, channel); channel.close(); #elif KEY_CLASS_Boolean 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(); #else STORE_KEYS(array, file, ByteOrder.BIG_ENDIAN); #endif } /** Stores a big array to a file given by a filename. * * @param array a big array whose elements will be written to the file {@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 file}. * @param file a file. */ public static void STORE_KEYS(final KEY_ITERATOR i, final File file) throws IOException { #if KEY_CLASS_Boolean || KEY_CLASS_Byte final DataOutputStream dos = new DataOutputStream(new FastBufferedOutputStream(new FileOutputStream(file))); while(i.hasNext()) dos.WRITE_KEY(i.NEXT_KEY()); dos.close(); #else STORE_KEYS(i, file, ByteOrder.BIG_ENDIAN); #endif } /** Stores the element returned by an iterator to a file given by a filename. * * @param i an iterator whose output will be written to the file {@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. * * @implNote This method opens a {@link FileChannel} that will not be closed until * it is garbage collected. * * @param file a file. */ public static KEY_ITERATOR AS_KEY_ITERATOR(final File file) throws IOException { #if KEY_CLASS_Boolean || KEY_CLASS_Byte return new KEY_DATA_INPUT_WRAPPER(new DataInputStream(new FastBufferedInputStream(new FileInputStream(file)))); #else return AS_KEY_ITERATOR(file, ByteOrder.BIG_ENDIAN); #endif } /** Wraps a file given by a filename into an iterator. * * @implNote This method opens a {@link FileChannel} that will not be closed until * it is garbage collected. * * @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. * * @implNote Each iterator returned by this class opens a {@link FileChannel} * that will not be closed until it is garbage collected. * * @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 filename into an iterable object. * * @implNote Each iterator returned by this class opens a {@link FileChannel} * that will not be closed until it is garbage collected. * * @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); } }; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy