2 * Copyright (c) 2003-2005 The BISON Project
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License version 2 as
6 * published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 package peersim.reports;
21 import peersim.core.*;
22 import peersim.config.Configuration;
23 import peersim.graph.*;
24 import peersim.cdsim.CDState;
27 * Class that provides functionality for observing graphs.
28 * It can efficiently create an undirected version of the graph, making sure
29 * it is updated only when the simulation has advanced already, and provides
30 * some common parameters.
32 public abstract class GraphObserver implements Control {
35 // ===================== fields =======================================
36 // ====================================================================
39 * The protocol to operate on.
42 private static final String PAR_PROT = "protocol";
45 * If defined, the undirected version of the graph will be analyzed. Not defined
49 protected static final String PAR_UNDIR = "undir";
52 * Alias for {@value #PAR_UNDIR}.
55 private static final String PAR_UNDIR_ALT = "undirected";
58 * If defined, the undirected version of the graph will be stored using much
59 * more memory but observers will be in general a few times faster. As a
60 * consequence, it will not work with large graphs. Not defined by default. It
61 * is a static property, that is, it affects all graph observers that are used
62 * in a simulation. That is, it is not a parameter of any observer, the name
63 * should be specified as a standalone property.
66 private static final String PAR_FAST = "graphobserver.fast";
68 /** The name of this observer in the configuration */
69 protected final String name;
71 protected final int pid;
73 protected final boolean undir;
75 protected final GraphAlgorithms ga = new GraphAlgorithms();
79 // ---------------------------------------------------------------------
81 private static int lastpid = -1234;
83 private static long time = -1234;
85 private static int phase = -1234;
87 private static int ctime = -1234;
89 private static Graph dirg;
91 private static Graph undirg;
93 private static boolean fast;
95 /** If any instance of some extending class defines undir we need to
96 maintain an undir graph. Note that the graph is stored in a static
97 field so it is common to all instances. */
98 private static boolean needUndir=false;
100 // ===================== initialization ================================
101 // =====================================================================
105 * Standard constructor that reads the configuration parameters.
106 * Invoked by the simulation engine.
107 * @param name the configuration prefix for this class
109 protected GraphObserver(String name) {
112 pid = Configuration.getPid(name+"."+PAR_PROT);
113 undir = (Configuration.contains(name + "." + PAR_UNDIR) |
114 Configuration.contains(name + "." + PAR_UNDIR_ALT));
115 GraphObserver.fast = Configuration.contains(PAR_FAST);
116 GraphObserver.needUndir = (GraphObserver.needUndir || undir);
120 // ====================== methods ======================================
121 // =====================================================================
125 * It MUST be called by any implementation of {@link #execute()} before
126 * doing anything else.
127 * Attempts to initialize {@link #g} from a
128 * pre-calculated graph stored in a static field, but first it
129 * checks whether it needs to be updated.
130 * If the simulation time has progressed or it was calculated for a different
131 * protocol, then updates this static graph as well.
132 * The purpose of this mechanism is to save the time of constructing the
133 * graph if many observers are run on the same graph. Time savings can be very
134 * significant if the undirected version of the same graph is observed by many
137 protected void updateGraph() {
139 if( CommonState.getTime() != GraphObserver.time ||
140 (CDState.isCD() && (CDState.getCycleT() != GraphObserver.ctime)) ||
141 CommonState.getPhase() != GraphObserver.phase ||
142 pid != GraphObserver.lastpid )
144 // we need to update the graphs
146 GraphObserver.lastpid = pid;
147 GraphObserver.time = CommonState.getTime();
148 if( CDState.isCD() ) GraphObserver.ctime = CDState.getCycleT();
149 GraphObserver.phase = CommonState.getPhase();
151 GraphObserver.dirg = new OverlayGraph(pid);
152 if( GraphObserver.needUndir )
155 GraphObserver.undirg =
156 new FastUndirGraph(GraphObserver.dirg);
158 GraphObserver.undirg =
159 new ConstUndirGraph(GraphObserver.dirg);
163 if( undir ) g = GraphObserver.undirg;
164 else g = GraphObserver.dirg;