
io.atomix.catalyst.buffer.MappedBytes Maven / Gradle / Ivy
/*
* Copyright 2015 the original author or authors.
*
* 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.
*/
package io.atomix.catalyst.buffer;
import io.atomix.catalyst.buffer.util.MappedMemory;
import io.atomix.catalyst.buffer.util.MappedMemoryAllocator;
import java.io.File;
import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
/**
* Mapped bytes.
*
* Mapped bytes provide direct access to memory from allocated by a {@link java.nio.MappedByteBuffer}. Memory is allocated
* by opening and expanding the given {@link java.io.File} to the desired {@code count} and mapping the file contents into memory
* via {@link java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long)}.
*
* Closing the bytes via {@link Bytes#close()} will result in {@link Bytes#flush()}
* being automatically called.
*
* @author Jordan Halterman
*/
public class MappedBytes extends NativeBytes {
/**
* Allocates a mapped buffer in {@link java.nio.channels.FileChannel.MapMode#READ_WRITE} mode.
*
* Memory will be mapped by opening and expanding the given {@link java.io.File} to the desired {@code count} and mapping the
* file contents into memory via {@link java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long)}.
*
* @param file The file to map into memory. If the file doesn't exist it will be automatically created.
* @param size The count of the buffer to allocate (in bytes).
* @return The mapped buffer.
* @throws NullPointerException If {@code file} is {@code null}
* @throws IllegalArgumentException If {@code count} is greater than {@link MappedMemory#MAX_SIZE}
*
* @see MappedBytes#allocate(java.io.File, java.nio.channels.FileChannel.MapMode, long)
*/
public static MappedBytes allocate(File file, long size) {
return allocate(file, MappedMemoryAllocator.DEFAULT_MAP_MODE, size);
}
/**
* Allocates a mapped buffer.
*
* Memory will be mapped by opening and expanding the given {@link java.io.File} to the desired {@code count} and mapping the
* file contents into memory via {@link java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long)}.
*
* @param file The file to map into memory. If the file doesn't exist it will be automatically created.
* @param mode The mode with which to map the file.
* @param size The count of the buffer to allocate (in bytes).
* @return The mapped buffer.
* @throws NullPointerException If {@code file} is {@code null}
* @throws IllegalArgumentException If {@code count} is greater than {@link MappedMemory#MAX_SIZE}
*
* @see MappedBytes#allocate(java.io.File, long)
*/
public static MappedBytes allocate(File file, FileChannel.MapMode mode, long size) {
if (file == null)
throw new NullPointerException("file cannot be null");
if (mode == null)
mode = MappedMemoryAllocator.DEFAULT_MAP_MODE;
if (size > MappedMemory.MAX_SIZE)
throw new IllegalArgumentException("size for MappedBytes cannot be greater than " + MappedMemory.MAX_SIZE);
return new MappedBytes(file, MappedMemory.allocate(file, mode, size));
}
private final File file;
protected MappedBytes(File file, MappedMemory memory) {
super(memory);
this.file = file;
}
/**
* Copies the bytes to a new byte array.
*
* @return A new {@link MappedBytes} instance backed by a copy of this instance's memory.
*/
public MappedBytes copy() {
throw new UnsupportedOperationException("copy");
}
@Override
public boolean isDirect() {
return true;
}
@Override
public boolean isFile() {
return true;
}
@Override
public Bytes flush() {
((MappedMemory) memory).flush();
return this;
}
/**
* Deletes the underlying file.
*/
public void delete() {
try {
Files.delete(file.toPath());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}