tmf.analysis: Restore the "getCPU" for data-driven analyses
[deliverable/tracecompass.git] / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / backend / historytree / HT_IO.java
CommitLineData
a52fde77 1/*******************************************************************************
60ae41e1 2 * Copyright (c) 2012, 2014 Ericsson
a52fde77
AM
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
e894a508 13package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree;
a52fde77
AM
14
15import java.io.File;
16import java.io.FileInputStream;
17import java.io.FileOutputStream;
18import java.io.IOException;
3b7f5abe 19import java.nio.channels.ClosedChannelException;
a52fde77
AM
20import java.nio.channels.FileChannel;
21
22/**
360f899e
EB
23 * This class abstracts inputs/outputs of the HistoryTree nodes.
24 *
25 * It contains all the methods and descriptors to handle reading/writing nodes
26 * to the tree-file on disk and all the caching mechanisms.
27 *
28 * This abstraction is mainly for code isolation/clarification purposes.
29 * Every HistoryTree must contain 1 and only 1 HT_IO element.
3de60236 30 *
ffd0aa67 31 * @author Alexandre Montplaisir
3de60236 32 *
a52fde77
AM
33 */
34class HT_IO {
360f899e
EB
35 /* Configuration of the History Tree */
36 private final HTConfig fConfig;
a52fde77
AM
37
38 /* Fields related to the file I/O */
3de60236
AM
39 private final FileInputStream fis;
40 private final FileOutputStream fos;
41 private final FileChannel fcIn;
42 private final FileChannel fcOut;
a52fde77 43
0c1d4577 44 // TODO test/benchmark optimal cache size
6993c1ca
EB
45 private final int CACHE_SIZE = 256;
46 private final HTNode fNodeCache[] = new HTNode[CACHE_SIZE];
47
a52fde77
AM
48 /**
49 * Standard constructor
3de60236 50 *
360f899e
EB
51 * @param config
52 * The configuration object for the StateHistoryTree
ab604305 53 * @param newFile
360f899e
EB
54 * Flag indicating that the file must be created from scratch
55
a52fde77 56 * @throws IOException
360f899e 57 * An exception can be thrown when file cannot be accessed
a52fde77 58 */
8d47cc34 59 public HT_IO(HTConfig config, boolean newFile) throws IOException {
360f899e 60 fConfig = config;
a52fde77 61
360f899e 62 File historyTreeFile = config.getStateFile();
a52fde77 63 if (newFile) {
360f899e 64 boolean success1 = true;
a52fde77
AM
65 /* Create a new empty History Tree file */
66 if (historyTreeFile.exists()) {
ab604305
AM
67 success1 = historyTreeFile.delete();
68 }
cb42195c 69 boolean success2 = historyTreeFile.createNewFile();
ab604305
AM
70 if (!(success1 && success2)) {
71 /* It seems we do not have permission to create the new file */
72 throw new IOException("Cannot create new file at " + //$NON-NLS-1$
73 historyTreeFile.getName());
a52fde77 74 }
a52fde77
AM
75 fis = new FileInputStream(historyTreeFile);
76 fos = new FileOutputStream(historyTreeFile, false);
77 } else {
78 /*
79 * We want to open an existing file, make sure we don't squash the
80 * existing content when opening the fos!
81 */
82 this.fis = new FileInputStream(historyTreeFile);
83 this.fos = new FileOutputStream(historyTreeFile, true);
84 }
85 this.fcIn = fis.getChannel();
86 this.fcOut = fos.getChannel();
87 }
88
a52fde77 89 /**
8d47cc34 90 * Read a node from the file on disk.
3b7f5abe 91 *
8d47cc34
AM
92 * @param seqNumber
93 * The sequence number of the node to read.
94 * @return The object representing the node
3b7f5abe
AM
95 * @throws ClosedChannelException
96 * Usually happens because the file was closed while we were
97 * reading. Instead of using a big reader-writer lock, we'll
98 * just catch this exception.
a52fde77 99 */
8d47cc34 100 public synchronized HTNode readNode(int seqNumber) throws ClosedChannelException {
6993c1ca
EB
101 /* Do a cache lookup */
102 int offset = seqNumber & (CACHE_SIZE - 1);
103 HTNode readNode = fNodeCache[offset];
104 if (readNode != null && readNode.getSequenceNumber() == seqNumber) {
105 return readNode;
106 }
107
108 /* Lookup on disk */
a52fde77
AM
109 try {
110 seekFCToNodePos(fcIn, seqNumber);
360f899e 111 readNode = HTNode.readNode(fConfig, fcIn);
6993c1ca
EB
112
113 /* Put the node in the cache. */
114 fNodeCache[offset] = readNode;
a52fde77 115 return readNode;
3b7f5abe
AM
116 } catch (ClosedChannelException e) {
117 throw e;
a52fde77 118 } catch (IOException e) {
3b7f5abe 119 /* Other types of IOExceptions shouldn't happen at this point though */
a52fde77
AM
120 e.printStackTrace();
121 return null;
122 }
123 }
124
e8b7cc14 125 public synchronized void writeNode(HTNode node) {
a52fde77 126 try {
6993c1ca
EB
127 /* Insert the node into the cache. */
128 int seqNumber = node.getSequenceNumber();
129 int offset = seqNumber & (CACHE_SIZE - 1);
130 fNodeCache[offset] = node;
131
a52fde77 132 /* Position ourselves at the start of the node and write it */
6993c1ca 133 seekFCToNodePos(fcOut, seqNumber);
a52fde77
AM
134 node.writeSelf(fcOut);
135 } catch (IOException e) {
136 /* If we were able to open the file, we should be fine now... */
137 e.printStackTrace();
138 }
139 }
140
e8b7cc14 141 public FileChannel getFcOut() {
a52fde77
AM
142 return this.fcOut;
143 }
144
8d47cc34 145 public FileInputStream supplyATReader(int nodeOffset) {
a52fde77
AM
146 try {
147 /*
148 * Position ourselves at the start of the Mapping section in the
149 * file (which is right after the Blocks)
150 */
360f899e 151 seekFCToNodePos(fcIn, nodeOffset);
a52fde77
AM
152 } catch (IOException e) {
153 e.printStackTrace();
154 }
155 return fis;
156 }
157
8d47cc34 158 public synchronized void closeFile() {
3de60236
AM
159 try {
160 fis.close();
161 fos.close();
162 } catch (IOException e) {
163 e.printStackTrace();
164 }
1a4205d9
AM
165 }
166
8d47cc34 167 public synchronized void deleteFile() {
1a4205d9 168 closeFile();
3de60236 169
360f899e 170 File historyTreeFile = fConfig.getStateFile();
6993c1ca 171 if (!historyTreeFile.delete()) {
36bf82a2
AM
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 *
360f899e
EB
181 * @param fc the channel to seek
182 * @param seqNumber the node sequence number to seek the channel to
a52fde77
AM
183 * @throws IOException
184 */
185 private void seekFCToNodePos(FileChannel fc, int seqNumber)
186 throws IOException {
a52fde77 187 /*
360f899e 188 * Cast to (long) is needed to make sure the result is a long too and
a52fde77
AM
189 * doesn't get truncated
190 */
360f899e
EB
191 fc.position(HistoryTree.TREE_HEADER_SIZE
192 + ((long) seqNumber) * fConfig.getBlockSize());
a52fde77
AM
193 }
194
195}
This page took 0.068797 seconds and 5 git commands to generate.