1 /*******************************************************************************
2 * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
4 * All rights reserved. This program and the accompanying materials are made
5 * 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
9 * Contributors: Matthew Khouzam - Initial API and implementation
10 * Contributors: Simon Marchi - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.ctf
.core
.event
.types
;
15 import java
.util
.Collections
;
16 import java
.util
.HashSet
;
17 import java
.util
.LinkedList
;
18 import java
.util
.List
;
22 * A CTF enum declaration.
24 * The definition of a enum point basic data type. It will take the data from a
25 * trace and store it (and make it fit) as an integer and a string.
28 * @author Matthew Khouzam
29 * @author Simon Marchi
31 public class EnumDeclaration
implements IDeclaration
{
33 // ------------------------------------------------------------------------
35 // ------------------------------------------------------------------------
37 private final EnumTable fTable
= new EnumTable();
38 private final IntegerDeclaration fContainerType
;
39 private final Set
<String
> fLabels
= new HashSet
<>();
41 // ------------------------------------------------------------------------
43 // ------------------------------------------------------------------------
48 * @param containerType
49 * the enum is an int, this is the type that the data is
50 * contained in. If you have 1000 possible values, you need at
51 * least a 10 bit enum. If you store 2 values in a 128 bit int,
52 * you are wasting space.
54 public EnumDeclaration(IntegerDeclaration containerType
) {
55 fContainerType
= containerType
;
58 // ------------------------------------------------------------------------
59 // Getters/Setters/Predicates
60 // ------------------------------------------------------------------------
64 * @return The container type
66 public IntegerDeclaration
getContainerType() {
67 return fContainerType
;
71 public long getAlignment() {
72 return this.getContainerType().getAlignment();
75 // ------------------------------------------------------------------------
77 // ------------------------------------------------------------------------
80 public EnumDefinition
createDefinition(IDefinitionScope definitionScope
,
82 return new EnumDefinition(this, definitionScope
, fieldName
);
86 * Add a value. Do not overlap, this is <i><u><b>not</i></u></b> an interval
90 * lowest value that this int can be to have label as a return
93 * highest value that this int can be to have label as a return
96 * the name of the value.
97 * @return was the value be added? true == success
99 public boolean add(long low
, long high
, String label
) {
101 return fTable
.add(low
, high
, label
);
105 * Check if the label for a value (enum a{day=0,night=1} would return "day"
109 * the value to lookup
110 * @return the label of that value, can be null
112 public String
query(long value
) {
113 return fTable
.query(value
);
117 * Gets a set of labels of the enum
119 * @return A set of labels of the enum, can be empty but not null
122 public Set
<String
> getLabels() {
123 return Collections
.unmodifiableSet(fLabels
);
127 * Maps integer range -> string. A simple list for now, but feel free to
128 * optimize it. Babeltrace suggests an interval tree.
130 private class EnumTable
{
132 private final List
<LabelAndRange
> ranges
= new LinkedList
<>();
137 public boolean add(long low
, long high
, String label
) {
138 LabelAndRange newRange
= new LabelAndRange(low
, high
, label
);
140 for (LabelAndRange r
: ranges
) {
141 if (r
.intersects(newRange
)) {
146 ranges
.add(newRange
);
152 * Return the first label that matches a value
156 * @return the label corresponding to that value
158 public String
query(long value
) {
159 for (LabelAndRange r
: ranges
) {
160 if (r
.intersects(value
)) {
169 private class LabelAndRange
{
171 private final long low
, high
;
172 private final String fLabel
;
174 public LabelAndRange(long low
, long high
, String str
) {
180 public boolean intersects(long i
) {
181 return (i
>= this.low
) && (i
<= this.high
);
184 public boolean intersects(LabelAndRange other
) {
185 return this.intersects(other
.low
)
186 || this.intersects(other
.high
);
191 public String
toString() {
192 /* Only used for debugging */
193 return "[declaration] enum[" + Integer
.toHexString(hashCode()) + ']'; //$NON-NLS-1$