2 * Copyright 2015-present Open Networking Foundation
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package io.atomix.storage.buffer;
19 import java.nio.channels.FileChannel;
21 import static com.google.common.base.Preconditions.checkArgument;
22 import static com.google.common.base.Preconditions.checkNotNull;
25 * Direct {@link java.nio.ByteBuffer} based buffer.
27 * @author <a href="http://github.com/kuujo">Jordan Halterman</a>
29 public class MappedBuffer extends ByteBufferBuffer {
32 * Allocates a dynamic capacity mapped buffer in {@link FileChannel.MapMode#READ_WRITE} mode with an initial capacity
33 * of {@code 16MiB} and a maximum capacity of {@link Integer#MAX_VALUE}.
35 * The resulting buffer will have a maximum capacity of {@link Integer#MAX_VALUE}. As bytes are written to the buffer
36 * its capacity will double in count each time the current capacity is reached. Memory will be mapped by opening and
37 * expanding the given {@link File} to the desired {@code capacity} and mapping the file contents into memory via
38 * {@link FileChannel#map(FileChannel.MapMode, long, long)}.
40 * @param file The file to map into memory.
41 * @return The mapped buffer.
42 * @throws NullPointerException If {@code file} is {@code null}
43 * @see #allocate(File, FileChannel.MapMode)
44 * @see #allocate(File, int)
45 * @see #allocate(File, FileChannel.MapMode, int)
46 * @see #allocate(File, int, int)
47 * @see #allocate(File, FileChannel.MapMode, int, int)
49 public static MappedBuffer allocate(File file) {
50 return allocate(file, FileChannel.MapMode.READ_WRITE, DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE);
54 * Allocates a dynamic capacity mapped buffer in {@link FileChannel.MapMode#READ_WRITE} mode with an initial capacity
55 * of {@code 16MiB} and a maximum capacity of {@link Integer#MAX_VALUE}.
57 * The resulting buffer will be initialized to a capacity of {@code 4096} and have a maximum capacity of
58 * {@link Integer#MAX_VALUE}. As bytes are written to the buffer its capacity will double in count each time the current
59 * capacity is reached. Memory will be mapped by opening and expanding the given {@link File} to the desired
60 * {@code capacity} and mapping the file contents into memory via
61 * {@link FileChannel#map(FileChannel.MapMode, long, long)}.
63 * @param file The file to map into memory.
64 * @param mode The mode with which to map the file.
65 * @return The mapped buffer.
66 * @throws NullPointerException If {@code file} is {@code null}
67 * @see #allocate(File)
68 * @see #allocate(File, int)
69 * @see #allocate(File, FileChannel.MapMode, int)
70 * @see #allocate(File, int, int)
71 * @see #allocate(File, FileChannel.MapMode, int, int)
73 public static MappedBuffer allocate(File file, FileChannel.MapMode mode) {
74 return allocate(file, mode, DEFAULT_INITIAL_CAPACITY, Integer.MAX_VALUE);
78 * Allocates a fixed capacity mapped buffer in {@link FileChannel.MapMode#READ_WRITE} mode.
80 * Memory will be mapped by opening and expanding the given {@link File} to the desired {@code capacity} and mapping the
81 * file contents into memory via {@link FileChannel#map(FileChannel.MapMode, long, long)}.
83 * The resulting buffer will have a capacity of {@code capacity}. The underlying {@link MappedBytes} will be
84 * initialized to the next power of {@code 2}.
86 * @param file The file to map into memory.
87 * @param capacity The fixed capacity of the buffer to allocate (in bytes).
88 * @return The mapped buffer.
89 * @throws NullPointerException If {@code file} is {@code null}
90 * @throws IllegalArgumentException If the {@code capacity} is greater than {@link Integer#MAX_VALUE}.
91 * @see #allocate(File)
92 * @see #allocate(File, FileChannel.MapMode)
93 * @see #allocate(File, FileChannel.MapMode, int)
94 * @see #allocate(File, int, int)
95 * @see #allocate(File, FileChannel.MapMode, int, int)
97 public static MappedBuffer allocate(File file, int capacity) {
98 return allocate(file, FileChannel.MapMode.READ_WRITE, capacity, capacity);
102 * Allocates a fixed capacity mapped buffer in the given {@link FileChannel.MapMode}.
104 * Memory will be mapped by opening and expanding the given {@link File} to the desired {@code capacity} and mapping the
105 * file contents into memory via {@link FileChannel#map(FileChannel.MapMode, long, long)}.
107 * The resulting buffer will have a capacity of {@code capacity}. The underlying {@link MappedBytes} will be
108 * initialized to the next power of {@code 2}.
110 * @param file The file to map into memory.
111 * @param mode The mode with which to map the file.
112 * @param capacity The fixed capacity of the buffer to allocate (in bytes).
113 * @return The mapped buffer.
114 * @throws NullPointerException If {@code file} is {@code null}
115 * @throws IllegalArgumentException If the {@code capacity} is greater than {@link Integer#MAX_VALUE}.
116 * @see #allocate(File)
117 * @see #allocate(File, FileChannel.MapMode)
118 * @see #allocate(File, int)
119 * @see #allocate(File, int, int)
120 * @see #allocate(File, FileChannel.MapMode, int, int)
122 public static MappedBuffer allocate(File file, FileChannel.MapMode mode, int capacity) {
123 return allocate(file, mode, capacity, capacity);
127 * Allocates a mapped buffer.
129 * Memory will be mapped by opening and expanding the given {@link File} to the desired {@code count} and mapping the
130 * file contents into memory via {@link FileChannel#map(FileChannel.MapMode, long, long)}.
132 * The resulting buffer will have a capacity of {@code initialCapacity}. The underlying {@link MappedBytes} will be
133 * initialized to the next power of {@code 2}. As bytes are written to the buffer, the buffer's capacity will double
134 * as int as {@code maxCapacity > capacity}.
136 * @param file The file to map into memory. If the file doesn't exist it will be automatically created.
137 * @param initialCapacity The initial capacity of the buffer.
138 * @param maxCapacity The maximum capacity of the buffer.
139 * @return The mapped buffer.
140 * @throws NullPointerException If {@code file} is {@code null}
141 * @throws IllegalArgumentException If the {@code capacity} or {@code maxCapacity} is greater than
142 * {@link Integer#MAX_VALUE}.
143 * @see #allocate(File)
144 * @see #allocate(File, FileChannel.MapMode)
145 * @see #allocate(File, int)
146 * @see #allocate(File, FileChannel.MapMode, int)
147 * @see #allocate(File, FileChannel.MapMode, int, int)
149 public static MappedBuffer allocate(File file, int initialCapacity, int maxCapacity) {
150 return allocate(file, FileChannel.MapMode.READ_WRITE, initialCapacity, maxCapacity);
154 * Allocates a mapped buffer.
156 * Memory will be mapped by opening and expanding the given {@link File} to the desired {@code count} and mapping the
157 * file contents into memory via {@link FileChannel#map(FileChannel.MapMode, long, long)}.
159 * The resulting buffer will have a capacity of {@code initialCapacity}. The underlying {@link MappedBytes} will be
160 * initialized to the next power of {@code 2}. As bytes are written to the buffer, the buffer's capacity will double
161 * as int as {@code maxCapacity > capacity}.
163 * @param file The file to map into memory. If the file doesn't exist it will be automatically created.
164 * @param mode The mode with which to map the file.
165 * @param initialCapacity The initial capacity of the buffer.
166 * @param maxCapacity The maximum capacity of the buffer.
167 * @return The mapped buffer.
168 * @throws NullPointerException If {@code file} is {@code null}
169 * @throws IllegalArgumentException If the {@code capacity} or {@code maxCapacity} is greater than
170 * {@link Integer#MAX_VALUE}.
171 * @see #allocate(File)
172 * @see #allocate(File, FileChannel.MapMode)
173 * @see #allocate(File, int)
174 * @see #allocate(File, FileChannel.MapMode, int)
175 * @see #allocate(File, int, int)
177 public static MappedBuffer allocate(File file, FileChannel.MapMode mode, int initialCapacity, int maxCapacity) {
178 checkNotNull(file, "file cannot be null");
179 checkNotNull(mode, "mode cannot be null");
180 checkArgument(initialCapacity <= maxCapacity, "initial capacity cannot be greater than maximum capacity");
181 return new MappedBuffer(MappedBytes.allocate(file, mode, initialCapacity), 0, initialCapacity, maxCapacity);
184 protected MappedBuffer(MappedBytes bytes, int offset, int initialCapacity, int maxCapacity) {
185 super(bytes, offset, initialCapacity, maxCapacity, null);
189 public MappedBuffer duplicate() {
190 return new MappedBuffer((MappedBytes) bytes, offset(), capacity(), maxCapacity());
194 * Deletes the underlying file.
196 public void delete() {
197 ((MappedBytes) bytes).delete();