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

COVERAGE SUMMARY FOR SOURCE FILE [FilePathCache.java]

nameclass, %method, %block, %line, %
FilePathCache.java100% (2/2)100% (19/19)100% (224/224)100% (59/59)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class FilePathCache100% (1/1)100% (4/4)100% (18/18)100% (5/5)
FilePathCache (): void 100% (1/1)100% (3/3)100% (2/2)
getScheme (): String 100% (1/1)100% (2/2)100% (1/1)
open (String): FileChannel 100% (1/1)100% (8/8)100% (1/1)
wrap (FileChannel): FileChannel 100% (1/1)100% (5/5)100% (1/1)
     
class FilePathCache$FileCache100% (1/1)100% (15/15)100% (206/206)100% (54/54)
FilePathCache$FileCache (FileChannel): void 100% (1/1)100% (12/12)100% (4/4)
clearCache (ByteBuffer, long): void 100% (1/1)100% (25/25)100% (8/8)
force (boolean): void 100% (1/1)100% (5/5)100% (2/2)
getCachePos (long): long 100% (1/1)100% (6/6)100% (1/1)
implCloseChannel (): void 100% (1/1)100% (4/4)100% (2/2)
position (): long 100% (1/1)100% (4/4)100% (1/1)
position (long): FileChannel 100% (1/1)100% (7/7)100% (2/2)
read (ByteBuffer): int 100% (1/1)100% (5/5)100% (1/1)
read (ByteBuffer, long): int 100% (1/1)100% (86/86)100% (23/23)
size (): long 100% (1/1)100% (4/4)100% (1/1)
toString (): String 100% (1/1)100% (11/11)100% (1/1)
truncate (long): FileChannel 100% (1/1)100% (10/10)100% (3/3)
tryLock (long, long, boolean): FileLock 100% (1/1)100% (7/7)100% (1/1)
write (ByteBuffer): int 100% (1/1)100% (10/10)100% (2/2)
write (ByteBuffer, long): int 100% (1/1)100% (10/10)100% (2/2)

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.cache;
7 
8import java.io.IOException;
9import java.nio.ByteBuffer;
10import java.nio.channels.FileChannel;
11import java.nio.channels.FileLock;
12import org.h2.store.fs.FileBase;
13import org.h2.store.fs.FilePathWrapper;
14 
15/**
16 * A file with a read cache.
17 */
18public class FilePathCache extends FilePathWrapper {
19 
20    public static FileChannel wrap(FileChannel f) {
21        return new FileCache(f);
22    }
23 
24    @Override
25    public FileChannel open(String mode) throws IOException {
26        return new FileCache(getBase().open(mode));
27    }
28 
29    @Override
30    public String getScheme() {
31        return "cache";
32    }
33 
34    /**
35     * A file with a read cache.
36     */
37    public static class FileCache extends FileBase {
38 
39        private static final int CACHE_BLOCK_SIZE = 4 * 1024;
40        private final FileChannel base;
41        // 1 MB cache size
42        private final CacheLongKeyLIRS<ByteBuffer> cache =
43                new CacheLongKeyLIRS<ByteBuffer>(1024 * 1024);
44 
45        FileCache(FileChannel base) {
46            this.base = base;
47        }
48 
49        @Override
50        protected void implCloseChannel() throws IOException {
51            base.close();
52        }
53 
54        @Override
55        public FileChannel position(long newPosition) throws IOException {
56            base.position(newPosition);
57            return this;
58        }
59 
60        @Override
61        public long position() throws IOException {
62            return base.position();
63        }
64 
65        @Override
66        public int read(ByteBuffer dst) throws IOException {
67            return base.read(dst);
68        }
69 
70        @Override
71        public int read(ByteBuffer dst, long position) throws IOException {
72            long cachePos = getCachePos(position);
73            int off = (int) (position - cachePos);
74            int len = CACHE_BLOCK_SIZE - off;
75            len = Math.min(len, dst.remaining());
76            ByteBuffer buff = cache.get(cachePos);
77            if (buff == null) {
78                buff = ByteBuffer.allocate(CACHE_BLOCK_SIZE);
79                long pos = cachePos;
80                while (true) {
81                    int read = base.read(buff, pos);
82                    if (read <= 0) {
83                        break;
84                    }
85                    if (buff.remaining() == 0) {
86                        break;
87                    }
88                    pos += read;
89                }
90                int read = buff.position();
91                if (read == CACHE_BLOCK_SIZE) {
92                    cache.put(cachePos, buff, CACHE_BLOCK_SIZE);
93                } else {
94                    if (read <= 0) {
95                        return -1;
96                    }
97                    len = Math.min(len, read - off);
98                }
99            }
100            dst.put(buff.array(), off, len);
101            return len == 0 ? -1 : len;
102        }
103 
104        private static long getCachePos(long pos) {
105            return (pos / CACHE_BLOCK_SIZE) * CACHE_BLOCK_SIZE;
106        }
107 
108        @Override
109        public long size() throws IOException {
110            return base.size();
111        }
112 
113        @Override
114        public FileChannel truncate(long newSize) throws IOException {
115            cache.clear();
116            base.truncate(newSize);
117            return this;
118        }
119 
120        @Override
121        public int write(ByteBuffer src, long position) throws IOException {
122            clearCache(src, position);
123            return base.write(src, position);
124        }
125 
126        @Override
127        public int write(ByteBuffer src) throws IOException {
128            clearCache(src, position());
129            return base.write(src);
130        }
131 
132        private void clearCache(ByteBuffer src, long position) {
133            if (cache.size() > 0) {
134                int len = src.remaining();
135                long p = getCachePos(position);
136                while (len > 0) {
137                    cache.remove(p);
138                    p += CACHE_BLOCK_SIZE;
139                    len -= CACHE_BLOCK_SIZE;
140                }
141            }
142        }
143 
144        @Override
145        public void force(boolean metaData) throws IOException {
146            base.force(metaData);
147        }
148 
149        @Override
150        public FileLock tryLock(long position, long size, boolean shared)
151                throws IOException {
152            return base.tryLock(position, size, shared);
153        }
154 
155        @Override
156        public String toString() {
157            return "cache:" + base.toString();
158        }
159 
160    }
161 
162}

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