tmf: Add a StateSystemDisposedException
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / historytree / HT_IO.java
CommitLineData
a52fde77
AM
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>
3de60236 5 *
a52fde77
AM
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
3de60236 10 *
a52fde77
AM
11 *******************************************************************************/
12
2ab9afbc 13package org.eclipse.linuxtools.internal.tmf.core.statesystem.historytree;
a52fde77
AM
14
15import java.io.File;
16import java.io.FileInputStream;
17import java.io.FileOutputStream;
18import java.io.IOException;
19import java.nio.channels.FileChannel;
20
21/**
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.
3de60236 26 *
a52fde77 27 * @author alexmont
3de60236 28 *
a52fde77
AM
29 */
30class HT_IO {
31
32 /* reference to the tree to which this IO-object belongs */
33 private final HistoryTree tree;
34
35 /* Fields related to the file I/O */
36bf82a2 36 private final File historyTreeFile;
3de60236
AM
37 private final FileInputStream fis;
38 private final FileOutputStream fos;
39 private final FileChannel fcIn;
40 private final FileChannel fcOut;
a52fde77
AM
41
42 /**
43 * Standard constructor
3de60236 44 *
a52fde77 45 * @param tree
ab604305
AM
46 * @param newFile
47 * Are we creating a new file from scratch?
a52fde77
AM
48 * @throws IOException
49 */
50 HT_IO(HistoryTree tree, boolean newFile) throws IOException {
51 this.tree = tree;
36bf82a2 52 historyTreeFile = tree.config.stateFile;
ab604305 53 boolean success1 = true, success2;
a52fde77
AM
54
55 if (newFile) {
56 /* Create a new empty History Tree file */
57 if (historyTreeFile.exists()) {
ab604305
AM
58 success1 = historyTreeFile.delete();
59 }
60 success2 = historyTreeFile.createNewFile();
61 if (!(success1 && success2)) {
62 /* It seems we do not have permission to create the new file */
63 throw new IOException("Cannot create new file at " + //$NON-NLS-1$
64 historyTreeFile.getName());
a52fde77 65 }
a52fde77
AM
66 fis = new FileInputStream(historyTreeFile);
67 fos = new FileOutputStream(historyTreeFile, false);
68 } else {
69 /*
70 * We want to open an existing file, make sure we don't squash the
71 * existing content when opening the fos!
72 */
73 this.fis = new FileInputStream(historyTreeFile);
74 this.fos = new FileOutputStream(historyTreeFile, true);
75 }
76 this.fcIn = fis.getChannel();
77 this.fcOut = fos.getChannel();
78 }
79
80 /**
81 * Generic "read node" method, which checks if the node is in memory first,
82 * and if it's not it goes to disk to retrieve it.
3de60236 83 *
a52fde77
AM
84 * @param seqNumber
85 * Sequence number of the node we want
86 * @return The wanted node in object form
87 */
88 HTNode readNode(int seqNumber) {
89 HTNode node = readNodeFromMemory(seqNumber);
90 if (node == null) {
91 return readNodeFromDisk(seqNumber);
92 }
93 return node;
94 }
95
96 private HTNode readNodeFromMemory(int seqNumber) {
97 for (HTNode node : tree.latestBranch) {
98 if (node.getSequenceNumber() == seqNumber) {
99 return node;
100 }
101 }
102 return null;
103 }
104
105 /**
106 * This method here isn't private, if we know for sure the node cannot be in
107 * memory it's a bit faster to use this directly (when opening a file from
108 * disk for example)
109 */
3888fddb 110 synchronized HTNode readNodeFromDisk(int seqNumber) {
a52fde77
AM
111 HTNode readNode;
112 try {
113 seekFCToNodePos(fcIn, seqNumber);
114 readNode = HTNode.readNode(tree, fcIn);
115 return readNode;
116 } catch (IOException e) {
117 e.printStackTrace();
118 return null;
119 }
120 }
121
122 void writeNode(HTNode node) {
123 try {
124 /* Position ourselves at the start of the node and write it */
125 seekFCToNodePos(fcOut, node.getSequenceNumber());
126 node.writeSelf(fcOut);
127 } catch (IOException e) {
128 /* If we were able to open the file, we should be fine now... */
129 e.printStackTrace();
130 }
131 }
132
133 FileChannel getFcOut() {
134 return this.fcOut;
135 }
136
137 FileInputStream supplyATReader() {
138 try {
139 /*
140 * Position ourselves at the start of the Mapping section in the
141 * file (which is right after the Blocks)
142 */
143 seekFCToNodePos(fcIn, tree.getNodeCount());
144 } catch (IOException e) {
145 e.printStackTrace();
146 }
147 return fis;
148 }
149
150 File supplyATWriterFile() {
151 return tree.config.stateFile;
152 }
153
154 long supplyATWriterFilePos() {
155 return HistoryTree.getTreeHeaderSize()
156 + ((long) tree.getNodeCount() * tree.config.blockSize);
157 }
158
1a4205d9 159 synchronized void closeFile() {
3de60236
AM
160 try {
161 fis.close();
162 fos.close();
163 } catch (IOException e) {
164 e.printStackTrace();
165 }
1a4205d9
AM
166 }
167
168 synchronized void deleteFile() {
169 closeFile();
3de60236 170
36bf82a2
AM
171 if(!historyTreeFile.delete()) {
172 /* We didn't succeed in deleting the file */
173 //TODO log it?
174 }
175 }
176
a52fde77
AM
177 /**
178 * Seek the given FileChannel to the position corresponding to the node that
179 * has seqNumber
3de60236 180 *
a52fde77
AM
181 * @param seqNumber
182 * @throws IOException
183 */
184 private void seekFCToNodePos(FileChannel fc, int seqNumber)
185 throws IOException {
186 fc.position(HistoryTree.getTreeHeaderSize() + (long) seqNumber
187 * tree.config.blockSize);
188 /*
189 * cast to (long) is needed to make sure the result is a long too and
190 * doesn't get truncated
191 */
192 }
193
194}
This page took 0.038576 seconds and 5 git commands to generate.