MappedByteBuffer.java revision 8510524dab13e0acc1babf22cbc55002fb122777
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements.  See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License.  You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package java.nio;
18
19import java.nio.channels.FileChannel.MapMode;
20import org.apache.harmony.luni.platform.MappedPlatformAddress;
21import org.apache.harmony.luni.platform.PlatformAddress;
22import org.apache.harmony.nio.internal.DirectBuffer;
23
24/**
25 * {@code MappedByteBuffer} is a special kind of direct byte buffer which maps a
26 * region of file to memory.
27 * <p>
28 * {@code MappedByteBuffer} can be created by calling
29 * {@link java.nio.channels.FileChannel#map(java.nio.channels.FileChannel.MapMode, long, long) FileChannel.map}.
30 * Once created, the mapping between the byte buffer and the file region remains
31 * valid until the byte buffer is garbage collected.
32 * <p>
33 * All or part of a {@code MappedByteBuffer}'s content may change or become
34 * inaccessible at any time, since the mapped file region can be modified by
35 * another thread or process at any time. If this happens, the behavior of the
36 * {@code MappedByteBuffer} is undefined.
37 */
38public abstract class MappedByteBuffer extends ByteBuffer {
39
40    final DirectByteBuffer wrapped;
41
42    private final MapMode mapMode;
43
44    MappedByteBuffer(ByteBuffer directBuffer) {
45        super(directBuffer.capacity);
46        if (!directBuffer.isDirect()) {
47            throw new IllegalArgumentException();
48        }
49        this.wrapped = (DirectByteBuffer) directBuffer;
50        this.mapMode = null;
51    }
52
53    MappedByteBuffer(PlatformAddress addr, int capacity, int offset, MapMode mapMode) {
54        super(capacity);
55        this.mapMode = mapMode;
56        if (mapMode == MapMode.READ_ONLY) {
57            wrapped = new ReadOnlyDirectByteBuffer(addr, capacity, offset);
58        } else {
59            wrapped = new ReadWriteDirectByteBuffer(addr, capacity, offset);
60        }
61        addr.autoFree();
62    }
63
64    /**
65     * Indicates whether this buffer's content is loaded. If the result is true
66     * there is a high probability that the whole buffer memory is currently
67     * loaded in RAM. If it is false it is unsure if it is loaded or not.
68     *
69     * @return {@code true} if this buffer's content is loaded, {@code false}
70     *         otherwise.
71     */
72    public final boolean isLoaded() {
73        return ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress()).mmapIsLoaded();
74    }
75
76    /**
77     * Loads this buffer's content into memory but it is not guaranteed to
78     * succeed.
79     *
80     * @return this buffer.
81     */
82    public final MappedByteBuffer load() {
83        ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress()).mmapLoad();
84        return this;
85    }
86
87    /**
88     * Writes all changes of the buffer to the mapped file. If the mapped file
89     * is stored on a local device, it is guaranteed that the changes are
90     * written to the file. No such guarantee is given if the file is located on
91     * a remote device.
92     *
93     * @return this buffer.
94     */
95    public final MappedByteBuffer force() {
96        if (mapMode == MapMode.READ_WRITE) {
97            ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress()).mmapFlush();
98        }
99        return this;
100    }
101}
102