blob: 24cd0b2bee91d96ef54a1f49000e7b55443a0a13 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Polytechnique
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Loïc Prieur-Drevon - Initial API and implementation
******************************************************************************/
package org.eclipse.tracecompass.segmentstore.core;
import java.io.IOException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.datastore.core.interval.IHTIntervalReader;
import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.ArrayListStore;
import org.eclipse.tracecompass.internal.segmentstore.core.arraylist.LazyArrayListStore;
import org.eclipse.tracecompass.internal.segmentstore.core.segmentHistoryTree.HistoryTreeSegmentStore;
import org.eclipse.tracecompass.internal.segmentstore.core.treemap.TreeMapStore;
/**
* Factory to create Segment Stores.
*
* Since segment stores are meant to be accessed using the {@link ISegmentStore}
* interface, you can use this factory to instantiate new ones.
*
* @author Loïc Prieur-Drevon
* @param <E>
* The type of segment held in this store
* @since 1.1
*/
public final class SegmentStoreFactory<E> {
/**
* Flags to determine the type of SegmentStore to use.
*/
public enum SegmentStoreType {
/**
* Segment Store should be as fast as possible to build and read.
* Performance of individual operations may be slower, but overall the
* speed should be faster.
*/
Fast,
/**
* Segment Store based should have predictable performance. This does
* not mean it's faster, it should not give a surprise random slow down
* though. If it slows down, it will be on the {@link ISegment} that
* slows it down.
*/
Stable,
/**
* Segment Store should contain no duplicate segments
*/
Distinct,
/**
* Segment store that doesn't have to reside entirely in memory, ideal
* for very large stores, the performance are not as high as the other
* segment stores. These kind of stores should be created using the
* {@link SegmentStoreFactory#createOnDiskSegmentStore(Path, IHTIntervalReader)}
* factory method
*
* @since 2.0
*/
OnDisk
}
private SegmentStoreFactory() {
// Do nothing
}
/**
* New SegmentStore factory method
*
* @param segmentTypes
* Flags used to determine the type of Segment Store that will be
* created
*
* @return a new {@link ISegmentStore}
*/
public static <E extends ISegment> ISegmentStore<E> createSegmentStore(@Nullable SegmentStoreType... segmentTypes) {
Set<@NonNull SegmentStoreType> segments = getListOfFlags(segmentTypes);
if (segments.contains(SegmentStoreType.Distinct)) {
return createTreeMapStore();
}
if (segments.contains(SegmentStoreType.Stable)) {
return createArrayListStore();
}
// default option is the fastest
return createLazyArrayListStore();
}
/**
* New SegmentStore factory method to create store from an array of Objects
*
* @param segmentTypes
* Flags used to determine the type of Segment Store that will be
* created
* @param array
* the {@link Object} array we want the returned segment store to
* contain, {@link Object} are only inserted if they extend
* {@link ISegment}
* @return an {@link ISegmentStore} containing the {@link ISegment}s from
* array.
*/
public static <E extends ISegment> ISegmentStore<E> createSegmentStore(Object[] array, SegmentStoreType... segmentTypes) {
Set<@NonNull SegmentStoreType> segments = getListOfFlags(segmentTypes);
if (segments.contains(SegmentStoreType.Distinct)) {
ISegmentStore<E> store = createTreeMapStore();
for (Object elem : array) {
if (elem instanceof ISegment) {
store.add((E) elem); // warning from type, it should be fine
}
}
return store;
}
if (segments.contains(SegmentStoreType.Stable)) {
return new ArrayListStore<>(array);
}
// default option is the fastest
return new LazyArrayListStore<>(array);
}
/**
* SegmentStore factory method that creates a segment store on disk
*
* @param segmentFile
* The file where to store the segments
* @param segmentReader
* The factory to read the segments from a safe byte buffer
*
* @return an {@link ISegmentStore}
* @throws IOException
* Exceptions when creating the segment store
* @since 2.0
* @deprecated Use the {@link #createOnDiskSegmentStore(Path, IHTIntervalReader, int)} instead
*/
@Deprecated
public static <E extends ISegment> ISegmentStore<E> createOnDiskSegmentStore(Path segmentFile, IHTIntervalReader<E> segmentReader) throws IOException {
return createOnDiskSegmentStore(segmentFile, segmentReader, 1);
}
/**
* SegmentStore factory method that creates a segment store on disk
*
* @param segmentFile
* The file where to store the segments
* @param segmentReader
* The factory to read the segments from a safe byte buffer
* @param version
* The version number of the segment reader/writer
*
* @return an {@link ISegmentStore}
* @throws IOException
* Exceptions when creating the segment store
* @since 2.1
*/
public static <E extends ISegment> ISegmentStore<E> createOnDiskSegmentStore(Path segmentFile, IHTIntervalReader<E> segmentReader, int version) throws IOException {
return new HistoryTreeSegmentStore<>(segmentFile, segmentReader, version);
}
private static Set<@NonNull SegmentStoreType> getListOfFlags(SegmentStoreType... segmentTypes) {
Set<@NonNull SegmentStoreType> segments = new HashSet<>();
for(@Nullable SegmentStoreType segmentType : segmentTypes ) {
if(segmentType != null) {
segments.add(segmentType);
}
}
return segments;
}
/**
* New {@link TreeMapStore} factory method
*
* @return the new Segment Store
*/
private static <E extends ISegment> ISegmentStore<E> createTreeMapStore() {
return new TreeMapStore<>();
}
/**
* New {@link ArrayListStore} factory method
*
* @return the new Segment Store
*/
private static <E extends ISegment> ISegmentStore<E> createArrayListStore() {
return new ArrayListStore<>();
}
/**
* New {@link LazyArrayListStore} factory method
*
* @return the new Segment Store
*/
private static <E extends ISegment> ISegmentStore<E> createLazyArrayListStore() {
return new LazyArrayListStore<>();
}
}