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

COVERAGE SUMMARY FOR SOURCE FILE [PageStreamTrunk.java]

nameclass, %method, %block, %line, %
PageStreamTrunk.java100% (2/2)76%  (16/21)86%  (332/385)86%  (83.2/97)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class PageStreamTrunk$Iterator100% (1/1)75%  (3/4)77%  (79/103)74%  (22.2/30)
getCurrentPageId (): int 0%   (0/1)0%   (0/3)0%   (0/1)
next (): PageStreamTrunk 100% (1/1)76%  (67/88)72%  (17.2/24)
PageStreamTrunk$Iterator (PageStore, int): void 100% (1/1)100% (9/9)100% (4/4)
canDelete (): boolean 100% (1/1)100% (3/3)100% (1/1)
     
class PageStreamTrunk100% (1/1)76%  (13/17)90%  (253/282)91%  (61/67)
canMove (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
canRemove (): boolean 0%   (0/1)0%   (0/2)0%   (0/1)
moveTo (Session, int): void 0%   (0/1)0%   (0/1)0%   (0/1)
toString (): String 0%   (0/1)0%   (0/20)0%   (0/1)
getPageData (int): int 100% (1/1)83%  (10/12)67%  (2/3)
contains (int): boolean 100% (1/1)89%  (16/18)75%  (3/4)
PageStreamTrunk (PageStore, Data, int): void 100% (1/1)100% (12/12)100% (5/5)
PageStreamTrunk (PageStore, int, int, int, int, int []): void 100% (1/1)100% (25/25)100% (9/9)
create (PageStore, int, int, int, int, int []): PageStreamTrunk 100% (1/1)100% (10/10)100% (1/1)
free (int): int 100% (1/1)100% (43/43)100% (12/12)
getLogKey (): int 100% (1/1)100% (3/3)100% (1/1)
getMemory (): int 100% (1/1)100% (6/6)100% (1/1)
getNextTrunk (): int 100% (1/1)100% (3/3)100% (1/1)
getPagesAddressed (int): int 100% (1/1)100% (6/6)100% (1/1)
read (): void 100% (1/1)100% (52/52)100% (11/11)
read (PageStore, Data, int): PageStreamTrunk 100% (1/1)100% (11/11)100% (3/3)
write (): void 100% (1/1)100% (56/56)100% (11/11)

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.store;
7 
8import org.h2.api.ErrorCode;
9import org.h2.engine.Session;
10import org.h2.message.DbException;
11 
12/**
13 * A trunk page of a stream. It contains the page numbers of the stream, and the
14 * page number of the next trunk. The format is:
15 * <ul>
16 * <li>page type: byte (0)</li>
17 * <li>checksum: short (1-2)</li>
18 * <li>previous trunk page, or 0 if none: int (3-6)</li>
19 * <li>log key: int (7-10)</li>
20 * <li>next trunk page: int (11-14)</li>
21 * <li>number of pages: short (15-16)</li>
22 * <li>page ids (17-)</li>
23 * </ul>
24 */
25public class PageStreamTrunk extends Page {
26 
27    private static final int DATA_START = 17;
28 
29    /**
30     * The previous stream trunk.
31     */
32    int parent;
33 
34    /**
35     * The next stream trunk.
36     */
37    int nextTrunk;
38 
39    private final PageStore store;
40    private int logKey;
41    private int[] pageIds;
42    private int pageCount;
43    private Data data;
44 
45    private PageStreamTrunk(PageStore store, int parent, int pageId, int next,
46            int logKey, int[] pageIds) {
47        setPos(pageId);
48        this.parent = parent;
49        this.store = store;
50        this.nextTrunk = next;
51        this.logKey = logKey;
52        this.pageCount = pageIds.length;
53        this.pageIds = pageIds;
54    }
55 
56    private PageStreamTrunk(PageStore store, Data data, int pageId) {
57        setPos(pageId);
58        this.data = data;
59        this.store = store;
60    }
61 
62    /**
63     * Read a stream trunk page.
64     *
65     * @param store the page store
66     * @param data the data
67     * @param pageId the page id
68     * @return the page
69     */
70    static PageStreamTrunk read(PageStore store, Data data, int pageId) {
71        PageStreamTrunk p = new PageStreamTrunk(store, data, pageId);
72        p.read();
73        return p;
74    }
75 
76    /**
77     * Create a new stream trunk page.
78     *
79     * @param store the page store
80     * @param parent the parent page
81     * @param pageId the page id
82     * @param next the next trunk page
83     * @param logKey the log key
84     * @param pageIds the stream data page ids
85     * @return the page
86     */
87    static PageStreamTrunk create(PageStore store, int parent, int pageId,
88            int next, int logKey, int[] pageIds) {
89        return new PageStreamTrunk(store, parent, pageId, next, logKey, pageIds);
90    }
91 
92    /**
93     * Read the page from the disk.
94     */
95    private void read() {
96        data.reset();
97        data.readByte();
98        data.readShortInt();
99        parent = data.readInt();
100        logKey = data.readInt();
101        nextTrunk = data.readInt();
102        pageCount = data.readShortInt();
103        pageIds = new int[pageCount];
104        for (int i = 0; i < pageCount; i++) {
105            pageIds[i] = data.readInt();
106        }
107    }
108 
109    /**
110     * Get the data page id at the given position.
111     *
112     * @param index the index (0, 1, ...)
113     * @return the value, or -1 if the index is too large
114     */
115    int getPageData(int index) {
116        if (index >= pageIds.length) {
117            return -1;
118        }
119        return pageIds[index];
120    }
121 
122    @Override
123    public void write() {
124        data = store.createData();
125        data.writeByte((byte) Page.TYPE_STREAM_TRUNK);
126        data.writeShortInt(0);
127        data.writeInt(parent);
128        data.writeInt(logKey);
129        data.writeInt(nextTrunk);
130        data.writeShortInt(pageCount);
131        for (int i = 0; i < pageCount; i++) {
132            data.writeInt(pageIds[i]);
133        }
134        store.writePage(getPos(), data);
135    }
136 
137    /**
138     * Get the number of pages that can be addressed in a stream trunk page.
139     *
140     * @param pageSize the page size
141     * @return the number of pages
142     */
143    static int getPagesAddressed(int pageSize) {
144        return (pageSize - DATA_START) / 4;
145    }
146 
147    /**
148     * Check if the given data page is in this trunk page.
149     *
150     * @param dataPageId the page id
151     * @return true if it is
152     */
153    boolean contains(int dataPageId) {
154        for (int i = 0; i < pageCount; i++) {
155            if (pageIds[i] == dataPageId) {
156                return true;
157            }
158        }
159        return false;
160    }
161 
162    /**
163     * Free this page and all data pages. Pages after the last used data page
164     * (if within this list) are empty and therefore not just freed, but marked
165     * as not used.
166     *
167     * @param lastUsedPage the last used data page
168     * @return the number of pages freed
169     */
170    int free(int lastUsedPage) {
171        store.free(getPos(), false);
172        int freed = 1;
173        boolean notUsed = false;
174        for (int i = 0; i < pageCount; i++) {
175            int page = pageIds[i];
176            if (notUsed) {
177                store.freeUnused(page);
178            } else {
179                store.free(page, false);
180            }
181            freed++;
182            if (page == lastUsedPage) {
183                notUsed = true;
184            }
185        }
186        return freed;
187    }
188 
189    /**
190     * Get the estimated memory size.
191     *
192     * @return number of double words (4 bytes)
193     */
194    @Override
195    public int getMemory() {
196        return store.getPageSize() >> 2;
197    }
198 
199    @Override
200    public void moveTo(Session session, int newPos) {
201        // not required
202    }
203 
204    int getLogKey() {
205        return logKey;
206    }
207 
208    public int getNextTrunk() {
209        return nextTrunk;
210    }
211 
212    /**
213     * An iterator over page stream trunk pages.
214     */
215    static class Iterator {
216 
217        private final PageStore store;
218        private int first;
219        private int next;
220        private int previous;
221        private boolean canDelete;
222        private int current;
223 
224        Iterator(PageStore store, int first) {
225            this.store = store;
226            this.next = first;
227        }
228 
229        int getCurrentPageId() {
230            return current;
231        }
232 
233        /**
234         * Get the next trunk page or null if no next trunk page.
235         *
236         * @return the next trunk page or null
237         */
238        PageStreamTrunk next() {
239            canDelete = false;
240            if (first == 0) {
241                first = next;
242            } else if (first == next) {
243                return null;
244            }
245            if (next == 0 || next >= store.getPageCount()) {
246                return null;
247            }
248            Page p;
249            current = next;
250            try {
251                p = store.getPage(next);
252            } catch (DbException e) {
253                if (e.getErrorCode() == ErrorCode.FILE_CORRUPTED_1) {
254                    // wrong checksum means end of stream
255                    return null;
256                }
257                throw e;
258            }
259            if (p == null || p instanceof PageStreamTrunk ||
260                    p instanceof PageStreamData) {
261                canDelete = true;
262            }
263            if (!(p instanceof PageStreamTrunk)) {
264                return null;
265            }
266            PageStreamTrunk t = (PageStreamTrunk) p;
267            if (previous > 0 && t.parent != previous) {
268                return null;
269            }
270            previous = next;
271            next = t.nextTrunk;
272            return t;
273        }
274 
275        /**
276         * Check if the current page can be deleted. It can if it's empty, a
277         * stream trunk, or a stream data page.
278         *
279         * @return true if it can be deleted
280         */
281        boolean canDelete() {
282            return canDelete;
283        }
284 
285    }
286 
287    @Override
288    public boolean canRemove() {
289        return true;
290    }
291 
292    @Override
293    public String toString() {
294        return "page[" + getPos() + "] stream trunk key:" + logKey +
295                " next:" + nextTrunk;
296    }
297 
298    @Override
299    public boolean canMove() {
300        return false;
301    }
302 
303}

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