tmf: Deprecate TmfStateSystemFactory and HistoryBuilder
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / internal / tmf / core / statesystem / backends / historytree / HT_IO.java
CommitLineData
a52fde77 1/*******************************************************************************
61759503 2 * Copyright (c) 2012, 2013 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
f9a76cac 13package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.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 */
360f899e
EB
59 HT_IO(HTConfig config, boolean newFile) throws IOException {
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
AM
89 /**
90 * This method here isn't private, if we know for sure the node cannot be in
91 * memory it's a bit faster to use this directly (when opening a file from
92 * disk for example)
3b7f5abe
AM
93 *
94 * @throws ClosedChannelException
95 * Usually happens because the file was closed while we were
96 * reading. Instead of using a big reader-writer lock, we'll
97 * just catch this exception.
a52fde77 98 */
360f899e 99 synchronized HTNode readNode(int seqNumber) throws ClosedChannelException {
6993c1ca
EB
100 /* Do a cache lookup */
101 int offset = seqNumber & (CACHE_SIZE - 1);
102 HTNode readNode = fNodeCache[offset];
103 if (readNode != null && readNode.getSequenceNumber() == seqNumber) {
104 return readNode;
105 }
106
107 /* Lookup on disk */
a52fde77
AM
108 try {
109 seekFCToNodePos(fcIn, seqNumber);
360f899e 110 readNode = HTNode.readNode(fConfig, fcIn);
6993c1ca
EB
111
112 /* Put the node in the cache. */
113 fNodeCache[offset] = readNode;
a52fde77 114 return readNode;
3b7f5abe
AM
115 } catch (ClosedChannelException e) {
116 throw e;
a52fde77 117 } catch (IOException e) {
3b7f5abe 118 /* Other types of IOExceptions shouldn't happen at this point though */
a52fde77
AM
119 e.printStackTrace();
120 return null;
121 }
122 }
123
124 void writeNode(HTNode node) {
125 try {
6993c1ca
EB
126 /* Insert the node into the cache. */
127 int seqNumber = node.getSequenceNumber();
128 int offset = seqNumber & (CACHE_SIZE - 1);
129 fNodeCache[offset] = node;
130
a52fde77 131 /* Position ourselves at the start of the node and write it */
6993c1ca 132 seekFCToNodePos(fcOut, seqNumber);
a52fde77
AM
133 node.writeSelf(fcOut);
134 } catch (IOException e) {
135 /* If we were able to open the file, we should be fine now... */
136 e.printStackTrace();
137 }
138 }
139
140 FileChannel getFcOut() {
141 return this.fcOut;
142 }
143
360f899e 144 FileInputStream supplyATReader(int nodeOffset) {
a52fde77
AM
145 try {
146 /*
147 * Position ourselves at the start of the Mapping section in the
148 * file (which is right after the Blocks)
149 */
360f899e 150 seekFCToNodePos(fcIn, nodeOffset);
a52fde77
AM
151 } catch (IOException e) {
152 e.printStackTrace();
153 }
154 return fis;
155 }
156
1a4205d9 157 synchronized void closeFile() {
3de60236
AM
158 try {
159 fis.close();
160 fos.close();
161 } catch (IOException e) {
162 e.printStackTrace();
163 }
1a4205d9
AM
164 }
165
166 synchronized void deleteFile() {
167 closeFile();
3de60236 168
360f899e 169 File historyTreeFile = fConfig.getStateFile();
6993c1ca 170 if (!historyTreeFile.delete()) {
36bf82a2
AM
171 /* We didn't succeed in deleting the file */
172 //TODO log it?
173 }
174 }
175
a52fde77
AM
176 /**
177 * Seek the given FileChannel to the position corresponding to the node that
178 * has seqNumber
3de60236 179 *
360f899e
EB
180 * @param fc the channel to seek
181 * @param seqNumber the node sequence number to seek the channel to
a52fde77
AM
182 * @throws IOException
183 */
184 private void seekFCToNodePos(FileChannel fc, int seqNumber)
185 throws IOException {
a52fde77 186 /*
360f899e 187 * Cast to (long) is needed to make sure the result is a long too and
a52fde77
AM
188 * doesn't get truncated
189 */
360f899e
EB
190 fc.position(HistoryTree.TREE_HEADER_SIZE
191 + ((long) seqNumber) * fConfig.getBlockSize());
a52fde77
AM
192 }
193
194}
This page took 0.051009 seconds and 5 git commands to generate.