MappedByteBuffer.java revision 3ff29eb11a241d58c54ecc84230bb0672f4aa148
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 org.apache.harmony.luni.platform.IMemorySystem;
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 int 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
51    }
52
53    MappedByteBuffer(PlatformAddress addr, int capa, int offset, int mode) {
54        super(capa);
55        mapMode = mode;
56        switch (mapMode) {
57            case IMemorySystem.MMAP_READ_ONLY:
58                wrapped = new ReadOnlyDirectByteBuffer(addr, capa, offset);
59                break;
60            case IMemorySystem.MMAP_READ_WRITE:
61            case IMemorySystem.MMAP_WRITE_COPY:
62                wrapped = new ReadWriteDirectByteBuffer(addr, capa, offset);
63                break;
64            default:
65                throw new IllegalArgumentException();
66        }
67        addr.autoFree();
68    }
69
70    /**
71     * Indicates whether this buffer's content is loaded. If the result is true
72     * there is a high probability that the whole buffer memory is currently
73     * loaded in RAM. If it is false it is unsure if it is loaded or not.
74     *
75     * @return {@code true} if this buffer's content is loaded, {@code false}
76     *         otherwise.
77     */
78    public final boolean isLoaded() {
79        return ((MappedPlatformAddress) ((DirectBuffer) wrapped)
80                .getBaseAddress()).mmapIsLoaded();
81    }
82
83    /**
84     * Loads this buffer's content into memory but it is not guaranteed to
85     * succeed.
86     *
87     * @return this buffer.
88     */
89    public final MappedByteBuffer load() {
90        ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress())
91                .mmapLoad();
92        return this;
93    }
94
95    /**
96     * Writes all changes of the buffer to the mapped file. If the mapped file
97     * is stored on a local device, it is guaranteed that the changes are
98     * written to the file. No such guarantee is given if the file is located on
99     * a remote device.
100     *
101     * @return this buffer.
102     */
103    public final MappedByteBuffer force() {
104        if (mapMode == IMemorySystem.MMAP_READ_WRITE) {
105            ((MappedPlatformAddress) ((DirectBuffer) wrapped).getBaseAddress())
106                    .mmapFlush();
107        }
108        return this;
109    }
110}
111