1 /*******************************************************************************
2 * Copyright (c) 2016 École Polytechnique de Montréal
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 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.tmf
.core
.statesystem
;
12 import java
.util
.LinkedList
;
13 import java
.util
.PriorityQueue
;
14 import java
.util
.Queue
;
16 import java
.util
.TreeSet
;
18 import org
.eclipse
.jdt
.annotation
.Nullable
;
19 import org
.eclipse
.tracecompass
.statesystem
.core
.ITmfStateSystemBuilder
;
22 * This class allows to recycle state system attributes. Instead of creating a
23 * lot of short-lived attributes, it is sometimes useful to re-use an attribute
24 * (and its whole sub-tree) that was previously used and is no longer required.
25 * This class keeps a list of children attributes of a base quark and grows that
28 * @author Geneviève Bastien
31 public class TmfAttributePool
{
33 private final ITmfStateSystemBuilder fSs
;
34 private final Integer fBaseQuark
;
35 private final Queue
<@Nullable Integer
> fAvailableQuarks
;
36 private final Set
<Integer
> fQuarksInUse
= new TreeSet
<>();
37 private int fCount
= 0;
42 public enum QueueType
{
44 * First In First Out, available attributes are stored and returned in
45 * the order in which they are recycled
49 * Available attributes are returned by their number, so attributes with
50 * lower numbers will be used more often
61 * The base quark under which to add the recyclable attributes
63 public TmfAttributePool(ITmfStateSystemBuilder ss
, Integer baseQuark
) {
64 this(ss
, baseQuark
, QueueType
.FIFO
);
73 * The base quark under which to add the recyclable attributes
75 * The type of queue to use for the attribute pool
77 public TmfAttributePool(ITmfStateSystemBuilder ss
, Integer baseQuark
, QueueType type
) {
80 /* Make sure the base quark is in range */
81 ss
.getParentAttributeQuark(baseQuark
);
82 fBaseQuark
= baseQuark
;
83 } catch (IndexOutOfBoundsException e
) {
84 throw new IllegalArgumentException("The quark used as base for the attribute pool does not exist"); //$NON-NLS-1$
88 fAvailableQuarks
= new LinkedList
<>();
91 fAvailableQuarks
= new PriorityQueue
<>();
94 throw new IllegalArgumentException("Wrong queue type"); //$NON-NLS-1$
99 * Get an available attribute quark. If there is one available, it will be
100 * reused, otherwise a new quark will be created under the base quark. The
101 * name of the attributes is a sequential integer. So the first quark to be
102 * added will be named '0', the next one '1', etc.
104 * @return An available quark
106 public synchronized int getAvailable() {
107 Integer quark
= fAvailableQuarks
.poll();
109 quark
= fSs
.getQuarkRelativeAndAdd(fBaseQuark
, String
.valueOf(fCount
));
112 fQuarksInUse
.add(quark
);
117 * Recycle a quark so that it can be reused by calling the
118 * {@link #getAvailable()} method. The quark has to have been obtained from
119 * a previous call to {@link #getAvailable()}. It will set the quark's value
120 * in the state system to a null value.
122 * It is assumed that it will be reused in the same context each time, so
123 * all children are kept and set to null in this method. The quarks are
124 * still available for the caller, nothing prevents from re-using them
125 * without referring to this class. That means if any attribute's value need
126 * to be non-null after recycling the quark, the caller can do it after
127 * calling this method.
130 * The quark to recycle.
132 * The timestamp at which to close this attribute.
134 public synchronized void recycle(int quark
, long ts
) {
135 if (!fQuarksInUse
.remove(quark
)) {
136 throw new IllegalArgumentException();
138 fSs
.removeAttribute(ts
, quark
);
139 fAvailableQuarks
.add(quark
);