tmf: Add the dependency level to the analyses' event requests
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.core / src / org / eclipse / tracecompass / tmf / core / statesystem / TmfAttributePool.java
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.tmf.core.statesystem;
11
12 import java.util.LinkedList;
13 import java.util.PriorityQueue;
14 import java.util.Queue;
15 import java.util.Set;
16 import java.util.TreeSet;
17
18 import org.eclipse.jdt.annotation.Nullable;
19 import org.eclipse.tracecompass.internal.tmf.core.Activator;
20 import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
21 import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
22
23 /**
24 * This class allows to recycle state system attributes. Instead of creating a
25 * lot of short-lived attributes, it is sometimes useful to re-use an attribute
26 * (and its whole sub-tree) that was previously used and is no longer required.
27 * This class keeps a list of children attributes of a base quark and grows that
28 * list as needed.
29 *
30 * @author Geneviève Bastien
31 * @since 2.0
32 */
33 public class TmfAttributePool {
34
35 private final ITmfStateSystemBuilder fSs;
36 private final Integer fBaseQuark;
37 private final Queue<@Nullable Integer> fAvailableQuarks;
38 private final Set<Integer> fQuarksInUse = new TreeSet<>();
39 private int fCount = 0;
40
41 /**
42 * The type of queue
43 */
44 public enum QueueType {
45 /**
46 * First In First Out, available attributes are stored and returned in
47 * the order in which they are recycled
48 */
49 FIFO,
50 /**
51 * Available attributes are returned by their number, so attributes with
52 * lower numbers will be used more often
53 */
54 PRIORITY
55 }
56
57 /**
58 * Constructor
59 *
60 * @param ss
61 * The state system
62 * @param baseQuark
63 * The base quark under which to add the recyclable attributes
64 */
65 public TmfAttributePool(ITmfStateSystemBuilder ss, Integer baseQuark) {
66 this(ss, baseQuark, QueueType.FIFO);
67 }
68
69 /**
70 * Constructor
71 *
72 * @param ss
73 * The state system
74 * @param baseQuark
75 * The base quark under which to add the recyclable attributes
76 * @param type
77 * The type of queue to use for the attribute pool
78 */
79 public TmfAttributePool(ITmfStateSystemBuilder ss, Integer baseQuark, QueueType type) {
80 fSs = ss;
81 try {
82 /* Make sure the base quark is in range */
83 ss.getParentAttributeQuark(baseQuark);
84 fBaseQuark = baseQuark;
85 } catch (IndexOutOfBoundsException e) {
86 throw new IllegalArgumentException("The quark used as base for the attribute pool does not exist"); //$NON-NLS-1$
87 }
88 switch (type) {
89 case FIFO:
90 fAvailableQuarks = new LinkedList<>();
91 break;
92 case PRIORITY:
93 fAvailableQuarks = new PriorityQueue<>();
94 break;
95 default:
96 throw new IllegalArgumentException("Wrong queue type"); //$NON-NLS-1$
97 }
98 }
99
100 /**
101 * Get an available attribute quark. If there is one available, it will be
102 * reused, otherwise a new quark will be created under the base quark. The
103 * name of the attributes is a sequential integer. So the first quark to be
104 * added will be named '0', the next one '1', etc.
105 *
106 * @return An available quark
107 */
108 public synchronized int getAvailable() {
109 Integer quark = fAvailableQuarks.poll();
110 if (quark == null) {
111 quark = fSs.getQuarkRelativeAndAdd(fBaseQuark, String.valueOf(fCount));
112 fCount++;
113 }
114 fQuarksInUse.add(quark);
115 return quark;
116 }
117
118 /**
119 * Recycle a quark so that it can be reused by calling the
120 * {@link #getAvailable()} method. The quark has to have been obtained from
121 * a previous call to {@link #getAvailable()}. It will set the quark's value
122 * in the state system to a null value.
123 *
124 * It is assumed that it will be reused in the same context each time, so
125 * all children are kept and set to null in this method. The quarks are
126 * still available for the caller, nothing prevents from re-using them
127 * without referring to this class. That means if any attribute's value need
128 * to be non-null after recycling the quark, the caller can do it after
129 * calling this method.
130 *
131 * @param quark
132 * The quark to recycle.
133 * @param ts
134 * The timestamp at which to close this attribute.
135 */
136 public synchronized void recycle(int quark, long ts) {
137 if (!fQuarksInUse.remove(quark)) {
138 throw new IllegalArgumentException();
139 }
140 try {
141 fSs.removeAttribute(ts, quark);
142 } catch (AttributeNotFoundException e) {
143 Activator.logError("Error getting sub-attributes", e); //$NON-NLS-1$
144 }
145 fAvailableQuarks.add(quark);
146 }
147
148 }
This page took 0.032821 seconds and 5 git commands to generate.