Commit | Line | Data |
---|---|---|
9a4c098d GB |
1 | /******************************************************************************* |
2 | * Copyright (c) 2016 École Polytechnique de Montréal | |
3 | * | |
4 | * All rights reserved. This program and the accompanying materials are | |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
8 | *******************************************************************************/ | |
9 | ||
10 | package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree; | |
11 | ||
cf8efcef | 12 | import java.io.File; |
9a4c098d GB |
13 | import java.io.IOException; |
14 | import java.nio.ByteBuffer; | |
15 | import java.nio.ByteOrder; | |
16 | import java.nio.channels.ReadableByteChannel; | |
17 | import java.nio.file.Files; | |
18 | import java.nio.file.Path; | |
19 | import java.nio.file.StandardOpenOption; | |
20 | ||
21 | import org.eclipse.jdt.annotation.NonNullByDefault; | |
cf8efcef AM |
22 | import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.IHistoryTree; |
23 | import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.classic.ClassicHistoryTree; | |
9a4c098d GB |
24 | |
25 | /** | |
26 | * Class that contains factory methods to build different types of history trees | |
27 | * | |
28 | * @author Geneviève Bastien | |
29 | */ | |
30 | @NonNullByDefault | |
31 | public final class HistoryTreeFactory { | |
32 | ||
33 | private HistoryTreeFactory() { | |
34 | } | |
35 | ||
36 | /** | |
cf8efcef AM |
37 | * Create a new History Tree from scratch, specifying all configuration |
38 | * parameters. | |
9a4c098d | 39 | * |
cf8efcef AM |
40 | * @param stateHistoryFile |
41 | * The name of the history file | |
42 | * @param blockSize | |
43 | * The size of each "block" on disk in bytes. One node will | |
44 | * always fit in one block. It should be at least 4096. | |
45 | * @param maxChildren | |
46 | * The maximum number of children allowed per core (non-leaf) | |
47 | * node. | |
48 | * @param providerVersion | |
49 | * The version of the state provider. If a file already exists, | |
50 | * and their versions match, the history file will not be rebuilt | |
51 | * uselessly. | |
52 | * @param treeStart | |
53 | * The start time of the history | |
54 | * @return The new history tree | |
9a4c098d GB |
55 | * @throws IOException |
56 | * If an error happens trying to open/write to the file | |
57 | * specified in the config | |
58 | */ | |
cf8efcef AM |
59 | public static IHistoryTree<StateSystemInterval> createHistoryTree(File stateHistoryFile, |
60 | int blockSize, | |
61 | int maxChildren, | |
62 | int providerVersion, | |
63 | long treeStart) throws IOException { | |
64 | ||
65 | return new ClassicHistoryTree<>(stateHistoryFile, | |
66 | blockSize, | |
67 | maxChildren, | |
68 | providerVersion, | |
69 | treeStart, | |
70 | StateSystemInterval.DESERIALISER); | |
9a4c098d GB |
71 | } |
72 | ||
73 | /** | |
74 | * "Reader" factory : instantiate a SHTree from an existing tree file on | |
75 | * disk | |
76 | * | |
77 | * @param existingStateFile | |
78 | * Path/filename of the history-file we are to open | |
79 | * @param expectedProviderVersion | |
80 | * The expected version of the state provider | |
81 | * @return The history tree | |
82 | * @throws IOException | |
83 | * If an error happens reading the file | |
84 | */ | |
cf8efcef AM |
85 | public static IHistoryTree<StateSystemInterval> createFromFile( |
86 | Path existingStateFile, int expectedProviderVersion) throws IOException { | |
9a4c098d GB |
87 | /* |
88 | * Check the file exists and has a positive length. These verifications | |
89 | * will also be done in the HT's constructor. | |
90 | */ | |
91 | if (!Files.isReadable(existingStateFile)) { | |
92 | throw new IOException("Selected state file does not exist or is not readable."); //$NON-NLS-1$ | |
93 | } | |
94 | if (Files.size(existingStateFile) <= 0) { | |
95 | throw new IOException("Empty target file"); //$NON-NLS-1$ | |
96 | } | |
97 | ||
98 | /* Read the magic number from the history tree file */ | |
99 | ByteBuffer buffer = ByteBuffer.allocate(Integer.BYTES); | |
100 | try (ReadableByteChannel channel = Files.newByteChannel(existingStateFile, StandardOpenOption.READ);) { | |
101 | buffer.order(ByteOrder.LITTLE_ENDIAN); | |
102 | buffer.clear(); | |
103 | channel.read(buffer); | |
104 | buffer.flip(); | |
105 | } | |
106 | ||
107 | /* | |
108 | * Check the magic number to see which history tree class to create | |
109 | */ | |
110 | int magicNumber = buffer.getInt(); | |
111 | switch (magicNumber) { | |
cf8efcef AM |
112 | case ClassicHistoryTree.HISTORY_FILE_MAGIC_NUMBER: |
113 | return new ClassicHistoryTree<>(existingStateFile.toFile(), | |
114 | expectedProviderVersion, StateSystemInterval.DESERIALISER); | |
9a4c098d GB |
115 | default: |
116 | throw new IOException("Not a known history tree file"); //$NON-NLS-1$ | |
117 | } | |
118 | } | |
119 | } |