EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.mvstore]

COVERAGE SUMMARY FOR SOURCE FILE [OffHeapStore.java]

nameclass, %method, %block, %line, %
OffHeapStore.java100% (1/1)73%  (8/11)72%  (227/314)76%  (54/71)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class OffHeapStore100% (1/1)73%  (8/11)72%  (227/314)76%  (54/71)
close (): void 0%   (0/1)0%   (0/4)0%   (0/2)
open (String, boolean, char []): void 0%   (0/1)0%   (0/4)0%   (0/2)
sync (): void 0%   (0/1)0%   (0/1)0%   (0/1)
truncate (long): void 100% (1/1)48%  (32/66)50%  (8/16)
free (long, int): void 100% (1/1)65%  (20/31)83%  (5/6)
writeFully (long, ByteBuffer): void 100% (1/1)78%  (78/100)90%  (19/21)
readFully (long, int): ByteBuffer 100% (1/1)82%  (49/60)91%  (10/11)
OffHeapStore (): void 100% (1/1)100% (8/8)100% (2/2)
getDefaultRetentionTime (): int 100% (1/1)100% (2/2)100% (1/1)
toString (): String 100% (1/1)100% (4/4)100% (1/1)
writeNewEntry (long, ByteBuffer): void 100% (1/1)100% (34/34)100% (8/8)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.mvstore;
7 
8import java.nio.ByteBuffer;
9import java.util.Iterator;
10import java.util.Map.Entry;
11import java.util.TreeMap;
12 
13/**
14 * A storage mechanism that "persists" data in the off-heap area of the main
15 * memory.
16 */
17public class OffHeapStore extends FileStore {
18 
19    private final TreeMap<Long, ByteBuffer> memory =
20            new TreeMap<Long, ByteBuffer>();
21 
22    @Override
23    public void open(String fileName, boolean readOnly, char[] encryptionKey) {
24        memory.clear();
25    }
26 
27    @Override
28    public String toString() {
29        return memory.toString();
30    }
31 
32    @Override
33    public ByteBuffer readFully(long pos, int len) {
34        Entry<Long, ByteBuffer> memEntry = memory.floorEntry(pos);
35        if (memEntry == null) {
36            throw DataUtils.newIllegalStateException(
37                    DataUtils.ERROR_READING_FAILED,
38                    "Could not read from position {0}", pos);
39        }
40        readCount++;
41        readBytes += len;
42        ByteBuffer buff = memEntry.getValue();
43        ByteBuffer read = buff.duplicate();
44        int offset = (int) (pos - memEntry.getKey());
45        read.position(offset);
46        read.limit(len + offset);
47        return read.slice();
48    }
49 
50    @Override
51    public void free(long pos, int length) {
52        freeSpace.free(pos, length);
53        ByteBuffer buff = memory.remove(pos);
54        if (buff == null) {
55            // nothing was written (just allocated)
56        } else if (buff.remaining() != length) {
57            throw DataUtils.newIllegalStateException(
58                    DataUtils.ERROR_READING_FAILED,
59                    "Partial remove is not supported at position {0}", pos);
60        }
61    }
62 
63    @Override
64    public void writeFully(long pos, ByteBuffer src) {
65        fileSize = Math.max(fileSize, pos + src.remaining());
66        Entry<Long, ByteBuffer> mem = memory.floorEntry(pos);
67        if (mem == null) {
68            // not found: create a new entry
69            writeNewEntry(pos, src);
70            return;
71        }
72        long prevPos = mem.getKey();
73        ByteBuffer buff = mem.getValue();
74        int prevLength = buff.capacity();
75        int length = src.remaining();
76        if (prevPos == pos) {
77            if (prevLength != length) {
78                throw DataUtils.newIllegalStateException(
79                        DataUtils.ERROR_READING_FAILED,
80                        "Could not write to position {0}; " +
81                        "partial overwrite is not supported", pos);
82            }
83            writeCount++;
84            writeBytes += length;
85            buff.rewind();
86            buff.put(src);
87            return;
88        }
89        if (prevPos + prevLength > pos) {
90            throw DataUtils.newIllegalStateException(
91                    DataUtils.ERROR_READING_FAILED,
92                    "Could not write to position {0}; " +
93                    "partial overwrite is not supported", pos);
94        }
95        writeNewEntry(pos, src);
96    }
97 
98    private void writeNewEntry(long pos, ByteBuffer src) {
99        int length = src.remaining();
100        writeCount++;
101        writeBytes += length;
102        ByteBuffer buff = ByteBuffer.allocateDirect(length);
103        buff.put(src);
104        buff.rewind();
105        memory.put(pos, buff);
106    }
107 
108    @Override
109    public void truncate(long size) {
110        writeCount++;
111        if (size == 0) {
112            fileSize = 0;
113            memory.clear();
114            return;
115        }
116        fileSize = size;
117        for (Iterator<Long> it = memory.keySet().iterator(); it.hasNext();) {
118            long pos = it.next();
119            if (pos < size) {
120                break;
121            }
122            ByteBuffer buff = memory.get(pos);
123            if (buff.capacity() > size) {
124                throw DataUtils.newIllegalStateException(
125                        DataUtils.ERROR_READING_FAILED,
126                        "Could not truncate to {0}; " +
127                        "partial truncate is not supported", pos);
128            }
129            it.remove();
130        }
131    }
132 
133    @Override
134    public void close() {
135        memory.clear();
136    }
137 
138    @Override
139    public void sync() {
140        // nothing to do
141    }
142 
143    @Override
144    public int getDefaultRetentionTime() {
145        return 0;
146    }
147 
148}

[all classes][org.h2.mvstore]
EMMA 2.0.5312 (C) Vladimir Roubtsov