1 /*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.core
.statesystem
.backend
.historytree
;
16 import java
.io
.FileInputStream
;
17 import java
.io
.FileOutputStream
;
18 import java
.io
.IOException
;
19 import java
.nio
.channels
.FileChannel
;
22 * This class exists mainly for code isolation/clarification purposes. It
23 * contains all the methods and descriptors to handle reading/writing to the
24 * tree-file on disk and all the caching mechanisms. Every HistoryTree should
25 * contain 1 and only 1 HT_IO element.
32 /* reference to the tree to which this IO-object belongs */
33 private final HistoryTree tree
;
35 /* Fields related to the file I/O */
36 private FileInputStream fis
;
37 private FileOutputStream fos
;
38 private FileChannel fcIn
;
39 private FileChannel fcOut
;
42 * Standard constructor
45 * @param newFile Are we creating a new file from scratch?
48 HT_IO(HistoryTree tree
, boolean newFile
) throws IOException
{
50 File historyTreeFile
= tree
.config
.stateFile
;
53 /* Create a new empty History Tree file */
54 if (historyTreeFile
.exists()) {
55 historyTreeFile
.delete();
57 historyTreeFile
.createNewFile();
58 fis
= new FileInputStream(historyTreeFile
);
59 fos
= new FileOutputStream(historyTreeFile
, false);
62 * We want to open an existing file, make sure we don't squash the
63 * existing content when opening the fos!
65 this.fis
= new FileInputStream(historyTreeFile
);
66 this.fos
= new FileOutputStream(historyTreeFile
, true);
68 this.fcIn
= fis
.getChannel();
69 this.fcOut
= fos
.getChannel();
73 * Generic "read node" method, which checks if the node is in memory first,
74 * and if it's not it goes to disk to retrieve it.
77 * Sequence number of the node we want
78 * @return The wanted node in object form
80 HTNode
readNode(int seqNumber
) {
81 HTNode node
= readNodeFromMemory(seqNumber
);
83 return readNodeFromDisk(seqNumber
);
88 private HTNode
readNodeFromMemory(int seqNumber
) {
89 for (HTNode node
: tree
.latestBranch
) {
90 if (node
.getSequenceNumber() == seqNumber
) {
98 * This method here isn't private, if we know for sure the node cannot be in
99 * memory it's a bit faster to use this directly (when opening a file from
102 HTNode
readNodeFromDisk(int seqNumber
) {
105 seekFCToNodePos(fcIn
, seqNumber
);
106 readNode
= HTNode
.readNode(tree
, fcIn
);
108 } catch (IOException e
) {
114 void writeNode(HTNode node
) {
116 /* Position ourselves at the start of the node and write it */
117 seekFCToNodePos(fcOut
, node
.getSequenceNumber());
118 node
.writeSelf(fcOut
);
119 } catch (IOException e
) {
120 /* If we were able to open the file, we should be fine now... */
125 FileChannel
getFcOut() {
129 FileInputStream
supplyATReader() {
132 * Position ourselves at the start of the Mapping section in the
133 * file (which is right after the Blocks)
135 seekFCToNodePos(fcIn
, tree
.getNodeCount());
136 } catch (IOException e
) {
142 File
supplyATWriterFile() {
143 return tree
.config
.stateFile
;
146 long supplyATWriterFilePos() {
147 return HistoryTree
.getTreeHeaderSize()
148 + ((long) tree
.getNodeCount() * tree
.config
.blockSize
);
152 * Seek the given FileChannel to the position corresponding to the node that
156 * @throws IOException
158 private void seekFCToNodePos(FileChannel fc
, int seqNumber
)
160 fc
.position(HistoryTree
.getTreeHeaderSize() + (long) seqNumber
161 * tree
.config
.blockSize
);
163 * cast to (long) is needed to make sure the result is a long too and
164 * doesn't get truncated
This page took 0.040028 seconds and 5 git commands to generate.