Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 331467 | Differences between
and this patch

Collapse All | Expand All

(-)a/lttng/org.eclipse.linuxtools.lttng.core/META-INF/MANIFEST.MF (-1 / +4 lines)
Lines 17-22 Export-Package: org.eclipse.linuxtools.lttng.core, Link Here
17
 org.eclipse.linuxtools.lttng.core.control,
17
 org.eclipse.linuxtools.lttng.core.control,
18
 org.eclipse.linuxtools.lttng.core.event,
18
 org.eclipse.linuxtools.lttng.core.event,
19
 org.eclipse.linuxtools.lttng.core.exceptions,
19
 org.eclipse.linuxtools.lttng.core.exceptions,
20
 org.eclipse.linuxtools.lttng.core.latency.analyzer,
20
 org.eclipse.linuxtools.lttng.core.model,
21
 org.eclipse.linuxtools.lttng.core.model,
21
 org.eclipse.linuxtools.lttng.core.request,
22
 org.eclipse.linuxtools.lttng.core.request,
22
 org.eclipse.linuxtools.lttng.core.signal,
23
 org.eclipse.linuxtools.lttng.core.signal,
Lines 28-34 Export-Package: org.eclipse.linuxtools.lttng.core, Link Here
28
 org.eclipse.linuxtools.lttng.core.state.resource,
29
 org.eclipse.linuxtools.lttng.core.state.resource,
29
 org.eclipse.linuxtools.lttng.core.state.trace,
30
 org.eclipse.linuxtools.lttng.core.state.trace,
30
 org.eclipse.linuxtools.lttng.core.trace,
31
 org.eclipse.linuxtools.lttng.core.trace,
32
 org.eclipse.linuxtools.lttng.core.tracecontrol,
31
 org.eclipse.linuxtools.lttng.core.tracecontrol.model,
33
 org.eclipse.linuxtools.lttng.core.tracecontrol.model,
32
 org.eclipse.linuxtools.lttng.core.tracecontrol.model.config,
34
 org.eclipse.linuxtools.lttng.core.tracecontrol.model.config,
33
 org.eclipse.linuxtools.lttng.core.tracecontrol.service
35
 org.eclipse.linuxtools.lttng.core.tracecontrol.service,
36
 org.eclipse.linuxtools.lttng.core.util
34
Bundle-Localization: plugin
37
Bundle-Localization: plugin
(-)a/lttng/org.eclipse.linuxtools.lttng.core/src/org/eclipse/linuxtools/lttng/core/latency/analyzer/EventMatcher.java (+505 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
3
 * 
4
 * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
5
 * Public License v1.0 which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
10
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.core.latency.analyzer;
13
14
import java.util.Collection;
15
import java.util.Collections;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.Map.Entry;
19
import java.util.Set;
20
import java.util.Stack;
21
import java.util.Vector;
22
23
import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
24
import org.eclipse.linuxtools.lttng.core.util.EventsPair;
25
26
/**
27
 * <b><u>EventMatcher</u></b>
28
 * <p>
29
 * Event matching class. Saves events in a list and returns the previously saved event if the currently processed one is
30
 * its response, so that the latency can be computed by subtracting their respective timestamps.
31
 * 
32
 * @author Philippe Sawicki
33
 */
34
public class EventMatcher {
35
36
    // ------------------------------------------------------------------------
37
    // Attributes
38
    // ------------------------------------------------------------------------
39
    
40
    /**
41
     * Class instance (Singleton pattern).
42
     */
43
    private static EventMatcher fInstance = null;
44
45
    /**
46
     * Stack abstraction, used to save the events in a list.
47
     */
48
    private StackWrapper fStack;
49
50
    /**
51
     * Match table, associates a request class to a response class.
52
     */
53
    private HashMap<String, String> fMatch;
54
    /**
55
     * Inverse match table, associates a response class to a request class.
56
     */
57
    private HashMap<String, String> fInverseMatch;
58
59
    /**
60
     * The number of events processed.
61
     */
62
    private int fProcessedEvents;
63
    /**
64
     * The number of events matched.
65
     */
66
    private int fMatchedEvents;
67
	
68
	/**
69
	 * Event types identification Strings.
70
	 */
71
	@SuppressWarnings("nls")
72
    public static String
73
		ADD_TO_PAGE_CACHE         = "add_to_page_cache",
74
		BIO_BACKMERGE             = "bio_backmerge",
75
		BIO_FRONTMERGE            = "bio_frontmerge",
76
		BIO_QUEUE                 = "bio_queue",
77
		BUFFER_WAIT_END           = "buffer_wait_end",
78
		BUFFER_WAIT_START         = "buffer_wait_start",
79
		CALL                      = "call",
80
		CLOSE                     = "close",
81
		CORE_MARKER_FORMAT        = "core_marker_format",
82
		CORE_MARKER_ID            = "core_marker_id",
83
		DEV_RECEIVE               = "dev_receive",
84
		DEV_XMIT                  = "dev_xmit",
85
		END_COMMIT                = "end_commit",
86
		EXEC                      = "exec",
87
		FILE_DESCRIPTOR           = "file_descriptor",
88
		GETRQ                     = "getrq",
89
		GETRQ_BIO                 = "getrq_bio",
90
		IDT_TABLE                 = "idt_table",
91
		INTERRUPT                 = "interrupt",
92
		IOCTL                     = "ioctl",
93
		IRQ_ENTRY                 = "irq_entry",
94
		IRQ_EXIT                  = "irq_exit",
95
		LIST_MODULE               = "list_module",
96
		LLSEEK                    = "llseek",
97
		LSEEK                     = "lseek",
98
		NAPI_COMPLETE             = "napi_complete",
99
		NAPI_POLL                 = "napi_poll",
100
		NAPI_SCHEDULE             = "napi_schedule",
101
		NETWORK_IPV4_INTERFACE    = "network_ipv4_interface",
102
		NETWORK_IP_INTERFACE      = "network_ip_interface",
103
		OPEN                      = "open",
104
		PAGE_FAULT_ENTRY          = "page_fault_entry",
105
		PAGE_FAULT_EXIT           = "page_fault_exit",
106
		PAGE_FAULT_GET_USER_ENTRY = "page_fault_get_user_entry",
107
		PAGE_FAULT_GET_USER_EXIT  = "page_fault_get_user_exit",
108
		PAGE_FREE                 = "page_free",
109
		PLUG                      = "plug",
110
		POLLFD                    = "pollfd",
111
		PREAD64                   = "pread64",
112
		PRINTF                    = "printf",
113
		PRINTK                    = "printk",
114
		PROCESS_EXIT              = "process_exit",
115
		PROCESS_FORK              = "process_fork",
116
		PROCESS_FREE              = "process_free",
117
		PROCESS_STATE             = "process_state",
118
		PROCESS_WAIT              = "process_wait",
119
		READ                      = "read",
120
		REMAP                     = "remap",
121
		REMOVE_FROM_PAGE_CACHE    = "remove_from_page_cache",
122
		RQ_COMPLETE_FS            = "rq_complete_fs",
123
		RQ_COMPLETE_PC            = "rq_complete_pc",
124
		RQ_INSERT_FS              = "rq_insert_fs",
125
		RQ_INSERT_PC              = "rq_insert_pc",
126
		RQ_ISSUE_FS               = "rq_issue_fs",
127
		RQ_ISSUE_PC               = "rq_issue_pc",
128
		RQ_REQUEUE_PC             = "rq_requeue_pc",
129
		SCHED_MIGRATE_TASK        = "sched_migrate_task",
130
		SCHED_SCHEDULE            = "sched_schedule",
131
		SCHED_TRY_WAKEUP          = "sched_try_wakeup",
132
		SCHED_WAKEUP_NEW_TASK     = "sched_wakeup_new_task",
133
		SELECT                    = "select",
134
		SEM_CREATE                = "sem_create",
135
		SEND_SIGNAL               = "send_signal",
136
		SHM_CREATE                = "shm_create",
137
		SLEEPRQ_BIO               = "sleeprq_bio",
138
		SOCKET_ACCEPT             = "socket_accept",
139
		SOCKET_BIND               = "socket_bind",
140
		SOCKET_CALL               = "socket_call",
141
		SOCKET_CONNECT            = "socket_connect",
142
		SOCKET_CREATE             = "socket_create",
143
		SOCKET_GETPEERNAME        = "socket_getpeername",
144
		SOCKET_GETSOCKNAME        = "socket_getsockname",
145
		SOCKET_GETSOCKOPT         = "socket_getsockopt",
146
		SOCKET_LISTEN             = "socket_listen",
147
		SOCKET_SETSOCKOPT         = "socket_setsockopt",
148
		SOCKET_SHUTDOWN           = "socket_shutdown",
149
		SOCKET_SOCKETPAIR         = "socket_socketpair",
150
		SOFTIRQ_ENTRY             = "softirq_entry",
151
		SOFTIRQ_EXIT              = "softirq_exit",
152
		SOFTIRQ_RAISE             = "softirq_raise",
153
		SOFTIRQ_VEC               = "softirq_vec",
154
		START_COMMIT              = "start_commit",
155
		STATEDUMP_END             = "statedump_end",
156
		SYS_CALL_TABLE            = "sys_call_table",
157
	    SYSCALL_ENTRY             = "syscall_entry",
158
	    SYSCALL_EXIT              = "syscall_exit",
159
	    TASKLET_LOW_ENTRY         = "tasklet_low_entry",
160
	    TASKLET_LOW_EXIT          = "tasklet_low_exit",
161
	    TCPV4_RCV                 = "tcpv4_rcv",
162
	    TIMER_ITIMER_EXPIRED      = "timer_itimer_expired",
163
	    TIMER_ITIMER_SET          = "timer_itimer_set",
164
	    TIMER_SET                 = "timer_set",
165
	    TIMER_TIMEOUT             = "timer_timeout",
166
	    TIMER_UPDATE_TIME         = "timer_update_time",
167
	    UDPV4_RCV                 = "udpv4_rcv",
168
	    UNPLUG_IO                 = "unplug_io",
169
	    UNPLUG_TIMER              = "unplug_timer",
170
	    VM_MAP                    = "vm_map",
171
	    VPRINTK                   = "vprintk",
172
	    WAIT_ON_PAGE_END          = "wait_on_page_end",
173
	    WAIT_ON_PAGE_START        = "wait_on_page_start",
174
	    WRITE                     = "write",
175
	    WRITEV                    = "writev";
176
177
    // ------------------------------------------------------------------------
178
    // Constructor
179
    // ------------------------------------------------------------------------
180
	
181
    /**
182
     * Private constructor to defeat instantiation (Singleton pattern).
183
     */
184
    private EventMatcher() {
185
        fStack = new StackWrapper();
186
        fMatch = new HashMap<String, String>();
187
        fInverseMatch = new HashMap<String, String>();
188
189
        fProcessedEvents = 0;
190
        fMatchedEvents = 0;
191
192
        createMatchTable();
193
    }
194
195
    // ------------------------------------------------------------------------
196
    // Accessors
197
    // ------------------------------------------------------------------------
198
199
    /**
200
     * Returns an instance to the EventMatcher class (Singleton pattern).
201
     * @return An instance to the EventMatcher class (Singleton pattern).
202
     */
203
    public static EventMatcher getInstance() {
204
        if (fInstance == null)
205
            fInstance = new EventMatcher();
206
        return fInstance;
207
    }
208
209
    /**
210
     * Returns the number of events processed.
211
     * @return The number of events processed.
212
     */
213
    public int getNBProcessedEvents() {
214
        return fProcessedEvents;
215
    }
216
217
    /**
218
     * Returns the number of events matched.
219
     * @return The number of events matched.
220
     */
221
    public int getNBMatchedEvents() {
222
        return fMatchedEvents;
223
    }
224
    
225
    // ------------------------------------------------------------------------
226
    // Operations
227
    // ------------------------------------------------------------------------
228
    
229
    /**
230
     * Releases the instance to the EventMatcher class.
231
     */
232
    public static void releaseInstance() {
233
        fInstance = null;
234
    }
235
236
    /**
237
     * Creates the event matching table, linking a response class to a request class.
238
     */
239
    private void createMatchTable() {
240
        // Build the default matches
241
        fMatch.put(PAGE_FAULT_GET_USER_EXIT, PAGE_FAULT_GET_USER_ENTRY);
242
        fMatch.put(TASKLET_LOW_EXIT, TASKLET_LOW_ENTRY);
243
        fMatch.put(PAGE_FAULT_EXIT, PAGE_FAULT_ENTRY);
244
        fMatch.put(SYSCALL_EXIT, SYSCALL_ENTRY);
245
        fMatch.put(IRQ_EXIT, IRQ_ENTRY);
246
        fMatch.put(WRITE, READ);
247
        fMatch.put(CLOSE, OPEN);
248
        fMatch.put(BUFFER_WAIT_END, BUFFER_WAIT_START);
249
        fMatch.put(END_COMMIT, START_COMMIT);
250
        fMatch.put(WAIT_ON_PAGE_END, WAIT_ON_PAGE_START);
251
252
        // Build the inverse matches based on the matches
253
        Set<Entry<String, String>> pairs = fMatch.entrySet();
254
        Iterator<Entry<String, String>> it = pairs.iterator();
255
        while (it.hasNext()) {
256
            Entry<String, String> pair = it.next();
257
            fInverseMatch.put(pair.getValue(), pair.getKey());
258
        }
259
    }
260
261
    /**
262
     * Processes an event received: if it is identified as a response, try to get its request to remove it from the
263
     * list. If no request was saved, dismiss the current response. If it is a request, save it to the list of requests
264
     * waiting for a response.
265
     * @param event
266
     *            The event to identify, and maybe process if it is a response.
267
     * @return The request event associated with the current event (a response), or null if nothing was found (no
268
     *         request associated with this response, or the event to identify was a request that was added to the
269
     *         list).
270
     */
271
    public LttngEvent process(LttngEvent event) {
272
        fProcessedEvents++;
273
274
        String markerName = event.getMarkerName();
275
        if (fMatch.containsKey(markerName)) {
276
            String startEventType = fMatch.get(markerName);
277
            Stack<LttngEvent> events = fStack.getStackOf(startEventType);
278
            
279
            if (events != null) {
280
                for (int i = events.size() - 1; i >= 0; i--) {
281
                    LttngEvent request = events.get(i);
282
283
                    if (request.getCpuId() == event.getCpuId() && event.getTimestamp().getValue() > request.getTimestamp().getValue()) {
284
                        fStack.removeEvent(startEventType, request);
285
                        fMatchedEvents++;
286
                        return request;
287
                    }
288
                }
289
            }
290
            return null;
291
        } else {
292
            // Add only if there can later be a match for this request
293
            if (fMatch.containsValue(event.getMarkerName())) {
294
                fStack.put(event.clone());
295
            }
296
            return null;
297
        }
298
    }
299
300
    /**
301
     * Clears the stack content.
302
     */
303
    public void clearStack() {
304
        fStack.clear();
305
306
        // Reset the processed and matched events counter
307
        fProcessedEvents = 0;
308
        fMatchedEvents = 0;
309
    }
310
311
    /**
312
     * Resets all.
313
     */
314
    public void resetMatches() {
315
        fMatch.clear();
316
        fInverseMatch.clear();
317
318
        fStack.clear();
319
320
        // Reset the processed and matched events counter
321
        fProcessedEvents = 0;
322
        fMatchedEvents = 0;
323
    }
324
325
    /**
326
     * Returns the list of start events.
327
     * @return The list of start events.
328
     */
329
    public Collection<String> getStartEvents() {
330
        return fMatch.values();
331
    }
332
333
    /**
334
     * Returns the list of end events.
335
     * @return The list of end events.
336
     */
337
    public Set<String> getEndEvents() {
338
        return fMatch.keySet();
339
    }
340
341
    /**
342
     * Returns the alphabetically-sorted list of start/end events pairs.
343
     * @return The alphabetically-sorted list of start/end events pairs.
344
     */
345
    public EventsPair getEvents() {
346
        Vector<String> start = new Vector<String>(getStartEvents());
347
        Vector<String> end = new Vector<String>(fMatch.size());
348
349
        Collections.sort(start);
350
        for (int i = 0; i < start.size(); i++) {
351
            end.add(fInverseMatch.get(start.get(i)));
352
        }
353
        return new EventsPair(start, end);
354
    }
355
356
    /**
357
     * Adds a match to the list of events pairs.
358
     * @param startType
359
     *            The start event type.
360
     * @param endType
361
     *            The end event type.
362
     */
363
    public void addMatch(String startType, String endType) {
364
        fMatch.put(endType, startType);
365
        fInverseMatch.put(startType, endType);
366
    }
367
368
    /**
369
     * Removes a matched pair based on the their type.
370
     * 
371
     * <b>Note :</b> For now, only the pair's end type is used, since a type can only be either one start or one end.
372
     * This function takes both types to account for the future, if a pairing process ever becomes more complex.
373
     * 
374
     * @param startType
375
     *            The type of the pair's start type.
376
     * @param endType
377
     *            The type of the pair's end type.
378
     */
379
    public void removeMatch(String startType, String endType) {
380
        fMatch.remove(endType);
381
        fInverseMatch.remove(startType);
382
    }
383
384
    /**
385
     * Returns the list of all event possible types.
386
     * @return The list of all event possible types.
387
     */
388
    public Vector<String> getTypeList() {
389
        // Reserve some space for the 103 default event types.
390
        Vector<String> eventsList = new Vector<String>(103);
391
392
        eventsList.add(ADD_TO_PAGE_CACHE);
393
        eventsList.add(BIO_BACKMERGE);
394
        eventsList.add(BIO_FRONTMERGE);
395
        eventsList.add(BIO_QUEUE);
396
        eventsList.add(BUFFER_WAIT_END);
397
        eventsList.add(BUFFER_WAIT_START);
398
        eventsList.add(CALL);
399
        eventsList.add(CLOSE);
400
        eventsList.add(CORE_MARKER_FORMAT);
401
        eventsList.add(CORE_MARKER_ID);
402
        eventsList.add(DEV_RECEIVE);
403
        eventsList.add(DEV_XMIT);
404
        eventsList.add(END_COMMIT);
405
        eventsList.add(EXEC);
406
        eventsList.add(FILE_DESCRIPTOR);
407
        eventsList.add(GETRQ);
408
        eventsList.add(GETRQ_BIO);
409
        eventsList.add(IDT_TABLE);
410
        eventsList.add(INTERRUPT);
411
        eventsList.add(IOCTL);
412
        eventsList.add(IRQ_ENTRY);
413
        eventsList.add(IRQ_EXIT);
414
        eventsList.add(LIST_MODULE);
415
        eventsList.add(LLSEEK);
416
        eventsList.add(LSEEK);
417
        eventsList.add(NAPI_COMPLETE);
418
        eventsList.add(NAPI_POLL);
419
        eventsList.add(NAPI_SCHEDULE);
420
        eventsList.add(NETWORK_IPV4_INTERFACE);
421
        eventsList.add(NETWORK_IP_INTERFACE);
422
        eventsList.add(OPEN);
423
        eventsList.add(PAGE_FAULT_ENTRY);
424
        eventsList.add(PAGE_FAULT_EXIT);
425
        eventsList.add(PAGE_FAULT_GET_USER_ENTRY);
426
        eventsList.add(PAGE_FAULT_GET_USER_EXIT);
427
        eventsList.add(PAGE_FREE);
428
        eventsList.add(PLUG);
429
        eventsList.add(POLLFD);
430
        eventsList.add(PREAD64);
431
        eventsList.add(PRINTF);
432
        eventsList.add(PRINTK);
433
        eventsList.add(PROCESS_EXIT);
434
        eventsList.add(PROCESS_FORK);
435
        eventsList.add(PROCESS_FREE);
436
        eventsList.add(PROCESS_STATE);
437
        eventsList.add(PROCESS_WAIT);
438
        eventsList.add(READ);
439
        eventsList.add(REMAP);
440
        eventsList.add(REMOVE_FROM_PAGE_CACHE);
441
        eventsList.add(RQ_COMPLETE_FS);
442
        eventsList.add(RQ_COMPLETE_PC);
443
        eventsList.add(RQ_INSERT_FS);
444
        eventsList.add(RQ_INSERT_PC);
445
        eventsList.add(RQ_ISSUE_FS);
446
        eventsList.add(RQ_ISSUE_PC);
447
        eventsList.add(RQ_REQUEUE_PC);
448
        eventsList.add(SCHED_MIGRATE_TASK);
449
        eventsList.add(SCHED_SCHEDULE);
450
        eventsList.add(SCHED_TRY_WAKEUP);
451
        eventsList.add(SCHED_WAKEUP_NEW_TASK);
452
        eventsList.add(SELECT);
453
        eventsList.add(SEM_CREATE);
454
        eventsList.add(SEND_SIGNAL);
455
        eventsList.add(SHM_CREATE);
456
        eventsList.add(SLEEPRQ_BIO);
457
        eventsList.add(SOCKET_ACCEPT);
458
        eventsList.add(SOCKET_BIND);
459
        eventsList.add(SOCKET_CALL);
460
        eventsList.add(SOCKET_CONNECT);
461
        eventsList.add(SOCKET_CREATE);
462
        eventsList.add(SOCKET_GETPEERNAME);
463
        eventsList.add(SOCKET_GETSOCKNAME);
464
        eventsList.add(SOCKET_GETSOCKOPT);
465
        eventsList.add(SOCKET_LISTEN);
466
        eventsList.add(SOCKET_SETSOCKOPT);
467
        eventsList.add(SOCKET_SHUTDOWN);
468
        eventsList.add(SOCKET_SOCKETPAIR);
469
        eventsList.add(SOFTIRQ_ENTRY);
470
        eventsList.add(SOFTIRQ_EXIT);
471
        eventsList.add(SOFTIRQ_RAISE);
472
        eventsList.add(SOFTIRQ_VEC);
473
        eventsList.add(START_COMMIT);
474
        eventsList.add(STATEDUMP_END);
475
        eventsList.add(SYS_CALL_TABLE);
476
        eventsList.add(SYSCALL_ENTRY);
477
        eventsList.add(SYSCALL_EXIT);
478
        eventsList.add(TASKLET_LOW_ENTRY);
479
        eventsList.add(TASKLET_LOW_EXIT);
480
        eventsList.add(TCPV4_RCV);
481
        eventsList.add(TIMER_ITIMER_EXPIRED);
482
        eventsList.add(TIMER_ITIMER_SET);
483
        eventsList.add(TIMER_SET);
484
        eventsList.add(TIMER_TIMEOUT);
485
        eventsList.add(TIMER_UPDATE_TIME);
486
        eventsList.add(UDPV4_RCV);
487
        eventsList.add(UNPLUG_IO);
488
        eventsList.add(UNPLUG_TIMER);
489
        eventsList.add(VM_MAP);
490
        eventsList.add(VPRINTK);
491
        eventsList.add(WAIT_ON_PAGE_END);
492
        eventsList.add(WAIT_ON_PAGE_START);
493
        eventsList.add(WRITE);
494
        eventsList.add(WRITEV);
495
496
        return eventsList;
497
    }
498
499
    /**
500
     * Prints the stack content to the console.
501
     */
502
    public void print() {
503
        fStack.printContent();
504
    }
505
}
(-)a/lttng/org.eclipse.linuxtools.lttng.core/src/org/eclipse/linuxtools/lttng/core/latency/analyzer/StackWrapper.java (+152 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *******************************************************************************/
13
package org.eclipse.linuxtools.lttng.core.latency.analyzer;
14
15
import java.util.Collection;
16
import java.util.HashMap;
17
import java.util.Iterator;
18
import java.util.Set;
19
import java.util.Stack;
20
21
import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
22
23
/**
24
 * <b><u>StackWrapper</u></b>
25
 * <p>
26
 * Stack pile.
27
 * 
28
 * TODO Change the types of the HashMaps from <String,String> to <Integer,Integer>, in order to take advantage of the
29
 * compilation-time String.hashCode() speedup over execution-time String hash computation.
30
 * 
31
 * @author Philippe Sawicki
32
 */
33
public class StackWrapper {
34
35
    // ------------------------------------------------------------------------
36
    // Attributes
37
    // ------------------------------------------------------------------------
38
39
    /**
40
     * Hash map of event stacks.
41
     */
42
    private HashMap<String, Stack<LttngEvent>> fStacks = null;
43
44
    // ------------------------------------------------------------------------
45
    // Constructors
46
    // ------------------------------------------------------------------------
47
48
    /**
49
     * Constructor.
50
     */
51
    public StackWrapper() {
52
        fStacks = new HashMap<String, Stack<LttngEvent>>();
53
    }
54
55
    // ------------------------------------------------------------------------
56
    // Operations
57
    // ------------------------------------------------------------------------
58
    
59
    /**
60
     * Adds an event to the list of events of the same type.
61
     * @param event
62
     *            The event to add to the list.
63
     */
64
    public void put(LttngEvent event) {
65
        String key = event.getMarkerName();
66
67
        if (fStacks.containsKey(key)) {
68
            fStacks.get(key).add(event);
69
        } else {
70
            Stack<LttngEvent> newStack = new Stack<LttngEvent>();
71
            newStack.add(event);
72
            fStacks.put(key, newStack);
73
        }
74
    }
75
76
    /**
77
     * Checks if the stack contains a list of events of the given type.
78
     * @param key
79
     *            The type of events to check for.
80
     * @return "true" if the stack contains events of the given type, "false" otherwise.
81
     */
82
    public boolean containsKey(String key) {
83
        return fStacks.containsKey(key);
84
    }
85
86
    /**
87
     * Returns the list of events of the given type.
88
     * @param key
89
     *            The type of events to return.
90
     * @return The list of events of the given type, or null.
91
     */
92
    public Stack<LttngEvent> getStackOf(String key) {
93
        return fStacks.get(key);
94
    }
95
96
    /**
97
     * Removes the given event from the given stack list.
98
     * @param key
99
     *            The given stack type.
100
     * @param event
101
     *            The event to remove from the given stack type.
102
     * @return "true" if the event was removed, "false" otherwise.
103
     */
104
    public boolean removeEvent(String key, LttngEvent event) {
105
        Stack<LttngEvent> stack = fStacks.get(key);
106
107
        boolean removed = false;
108
109
        try {
110
            /**
111
             * TODO Correct this... Here, no matter what CPU or other content field, we always remove the last event
112
             * added to the stack. Should be something like : return stack.remove(event);
113
             */
114
            stack.pop();
115
            removed = true;
116
        } catch (Exception e) {
117
            e.printStackTrace();
118
        }
119
120
        // Remove the stack from the stack list if it is empty
121
        if (stack.isEmpty()) {
122
            fStacks.remove(key);
123
        }
124
125
        return removed;
126
    }
127
128
    /**
129
     * Clears the stack content.
130
     */
131
    public void clear() {
132
        fStacks.clear();
133
    }
134
135
    /**
136
     * Prints the content of the stack to the console.
137
     */
138
    @SuppressWarnings("nls")
139
    public void printContent() {
140
        Collection<Stack<LttngEvent>> values = fStacks.values();
141
        Iterator<Stack<LttngEvent>> valueIt = values.iterator();
142
143
        Set<String> keys = fStacks.keySet();
144
        Iterator<String> keyIt = keys.iterator();
145
146
        while (valueIt.hasNext() && keyIt.hasNext()) {
147
            Stack<LttngEvent> stack = valueIt.next();
148
149
            System.out.println("   " + keyIt.next() + " [" + stack.size() + "] : " + stack);
150
        }
151
    }
152
}
(-)a/lttng/org.eclipse.linuxtools.lttng.core/src/org/eclipse/linuxtools/lttng/core/util/EventsPair.java (+29 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
3
 * 
4
 * All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse
5
 * Public License v1.0 which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 * 
8
 * Contributors: 
9
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.linuxtools.lttng.core.util;
12
13
import java.util.Vector;
14
15
16
/**
17
 * Contains two lists of events name. The first list contains the events identified as starting request and the second list
18
 * contains the events identified as ending request
19
 */
20
public class EventsPair extends Pair<Vector<String>, Vector<String>> {
21
22
    public EventsPair() {
23
        super();
24
    }
25
26
    public EventsPair(Vector<String> startingEvents, Vector<String> endingEvents) {
27
        super(startingEvents, endingEvents);
28
    }
29
}
(-)a/lttng/org.eclipse.linuxtools.lttng.core/src/org/eclipse/linuxtools/lttng/core/util/Pair.java (+121 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *******************************************************************************/
13
package org.eclipse.linuxtools.lttng.core.util;
14
15
/**
16
 * Pair utility class, encapsulates a pair of objects.
17
 * 
18
 * @author Philippe Sawicki
19
 * 
20
 * @param <A>
21
 *            The type of the first object.
22
 * @param <B>
23
 *            The type of the second object.
24
 */
25
public abstract class Pair<A, B> {
26
27
    /**
28
     * A reference to the first object.
29
     */
30
    protected A fFirst;
31
    /**
32
     * A reference to the second object.
33
     */
34
    protected B fSecond;
35
36
    /**
37
     * Constructor.
38
     * @param first
39
     *            The pair's first object.
40
     * @param second
41
     *            The pair's second object.
42
     */
43
    public Pair(A first, B second) {
44
        fFirst = first;
45
        fSecond = second;
46
    }
47
48
    /**
49
     * Constructor.
50
     */
51
    public Pair() {
52
        this(null, null);
53
    }
54
55
    /**
56
     * Pair hash code.
57
     */
58
    @Override
59
    public int hashCode() {
60
        int hashFirst = fFirst != null ? fFirst.hashCode() : 0;
61
        int hashSecond = fSecond != null ? fSecond.hashCode() : 0;
62
63
        return (hashFirst + hashSecond) * hashSecond + hashFirst;
64
    }
65
66
    /**
67
     * Object comparison.
68
     */
69
    @Override
70
    @SuppressWarnings("unchecked")
71
    public boolean equals(Object other) {
72
        if (other instanceof Pair) {
73
            Pair<A, B> otherPair = (Pair<A, B>) other;
74
            return ((fFirst == otherPair.fFirst || (fFirst != null && otherPair.fFirst != null && fFirst.equals(otherPair.fFirst))) && (fSecond == otherPair.fSecond || (fSecond != null
75
                    && otherPair.fSecond != null && fSecond.equals(otherPair.fSecond))));
76
        }
77
        return false;
78
    }
79
80
    /**
81
     * Object to string.
82
     */
83
    @Override
84
    public String toString() {
85
        return "(" + fFirst + ", " + fSecond + ")";  //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
86
    }
87
88
    /**
89
     * Returns a reference to the pair's first object.
90
     * @return A reference to the pair's first object.
91
     */
92
    public A getFirst() {
93
        return fFirst;
94
    }
95
96
    /**
97
     * Sets the pair's first object.
98
     * @param first
99
     *            The pair's first object.
100
     */
101
    public void setFirst(A first) {
102
        fFirst = first;
103
    }
104
105
    /**
106
     * Returns a reference to the pair's second object.
107
     * @return A reference to the pair's second object.
108
     */
109
    public B getSecond() {
110
        return fSecond;
111
    }
112
113
    /**
114
     * Sets the pair's second object.
115
     * @param second
116
     *            The pair's second object.
117
     */
118
    public void setSecond(B second) {
119
        fSecond = second;
120
    }
121
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/AllLTTngUITests.java (+1 lines)
Lines 7-12 public class AllLTTngUITests { Link Here
7
    public static Test suite() {
7
    public static Test suite() {
8
        TestSuite suite = new TestSuite(AllLTTngUITests.class.getName());
8
        TestSuite suite = new TestSuite(AllLTTngUITests.class.getName());
9
        //$JUnit-BEGIN$
9
        //$JUnit-BEGIN$
10
        suite.addTest(org.eclipse.linuxtools.lttng.ui.tests.distribution.AllTests.suite());
10
        suite.addTest(org.eclipse.linuxtools.lttng.ui.tests.histogram.AllTests.suite());
11
        suite.addTest(org.eclipse.linuxtools.lttng.ui.tests.histogram.AllTests.suite());
11
        //$JUnit-END$
12
        //$JUnit-END$
12
        return suite;
13
        return suite;
(-)a/lttng/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/distribution/AllTests.java (+27 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.tests.distribution;
13
14
import junit.framework.Test;
15
import junit.framework.TestSuite;
16
17
public class AllTests {
18
19
    public static Test suite() {
20
        
21
        TestSuite suite = new TestSuite(AllTests.class.getName());
22
        //$JUnit-BEGIN$
23
        suite.addTestSuite(LatencyGraphModelTest.class);
24
        //$JUnit-END$
25
        return suite;
26
    }
27
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/distribution/LatencyGraphModelTest.java (+582 lines)
Added Link Here
1
package org.eclipse.linuxtools.lttng.ui.tests.distribution;
2
3
import junit.framework.TestCase;
4
5
import org.eclipse.linuxtools.lttng.ui.views.latency.model.Config;
6
import org.eclipse.linuxtools.lttng.ui.views.latency.model.GraphScaledData;
7
import org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener;
8
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyGraphModel;
9
10
@SuppressWarnings("nls")
11
public class LatencyGraphModelTest extends TestCase {
12
13
    // ------------------------------------------------------------------------
14
    // Test data
15
    // ------------------------------------------------------------------------
16
17
    // ------------------------------------------------------------------------
18
    // Housekeeping
19
    // ------------------------------------------------------------------------
20
    
21
    @Override
22
    public void setUp() throws Exception {
23
    }
24
25
    @Override
26
    public void tearDown() throws Exception {
27
    }
28
29
    // ------------------------------------------------------------------------
30
    // Tests
31
    // ------------------------------------------------------------------------
32
    
33
    public void testLatencyGraphModel() {
34
        LatencyGraphModel model = new LatencyGraphModel();
35
        assertEquals("nbBuckets", Config.DEFAULT_NUMBER_OF_BUCKETS, model.getNbBuckets());
36
        assertEquals("currentTime", Config.INVALID_EVENT_TIME, model.getCurrentEventTime());
37
    }
38
    
39
    public void testLatencyGraphModelInt() {
40
        LatencyGraphModel model = new LatencyGraphModel(100);
41
        assertEquals("nbBuckets", 100, model.getNbBuckets());
42
        assertEquals("currentTime", Config.INVALID_EVENT_TIME, model.getCurrentEventTime());
43
    }
44
45
    
46
    public void testGraphModelListener() {
47
        final int nbBuckets = 2000;
48
        final int nbEvents = 10 * nbBuckets + 256;
49
        final int[] count = new int[2];
50
        count [0] = 0;
51
        count [1] = 0;
52
53
        // Test add listener and call of listener
54
        IGraphModelListener listener = new IGraphModelListener() {
55
            
56
            @Override
57
            public void graphModelUpdated() {
58
                count[0]++;
59
                
60
            }
61
            
62
            @Override
63
            public void currentEventUpdated(long currentEventTime) {
64
                count[1]++;
65
            }
66
        };
67
68
        // Test that the listener interface is called every 10000 events.
69
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
70
        model.addGraphModelListener(listener);
71
        for (int i = 0; i < nbEvents; i++) {
72
            model.countEvent(i+1, i, i);
73
        }
74
        
75
        assertEquals("listener", 2, count[0]);
76
77
        // Test that the listener interface is called when complete is called.
78
        model.complete();
79
        assertEquals("listener", 3, count[0]);
80
81
        // Test that clear triggers call of listener interface
82
        model.clear();
83
        assertEquals("listener", 4, count[0]);
84
85
        // Test that clear triggers call of listener interface
86
        model.setCurrentEventNotifyListeners(100);
87
        assertEquals("listener", 1, count[1]);
88
        
89
        // Test remove listener
90
        count[0] = 0;
91
        count[1] = 0;
92
        model.removeGraphModelListener(listener);
93
        
94
        for (int i = 0; i < nbEvents; i++) {
95
            model.countEvent(i, i, i);
96
        }
97
        model.complete();
98
        assertEquals("listener", 0, count[1]);
99
        
100
        // Test that clear triggers call of listener interface
101
        model.setCurrentEventNotifyListeners(100);
102
        assertEquals("listener", 0, count[1]);
103
    }
104
    
105
    public void testConstructor() {
106
        final int nbBuckets = 2000;
107
        
108
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
109
        GraphScaledData scaledData = model.scaleTo(100, 100, 1);
110
        
111
        // Verify model parameters
112
        assertEquals("Horizontal bucket duration", 1, model.getHorBucketDuration());
113
        assertEquals("Vertical bucket duration", 1, model.getVerBucketDuration());
114
115
        assertEquals("Horizontal first bucket time", 0, model.getHorFirstBucketTime());
116
        assertEquals("Vertical first bucket time", 0, model.getVerFirstBucketTime());
117
118
        assertEquals("Horizontal last bucket ", 0, model.getHorLastBucket());
119
        assertEquals("Vertical last bucket ", 0, model.getVerLastBucket());
120
        
121
        assertEquals("Horizontal first time", 0, model.getHorFirstEventTime());
122
        assertEquals("Vertical first time", 0, model.getVerFirstEventTime());
123
124
        assertEquals("Horizontal last time", 0, model.getHorLastEventTime());
125
        assertEquals("Vertical last time", 0, model.getVerLastEventTime());
126
        
127
        assertEquals("Horizontal time limit", 2000, model.getHorTimeLimit());
128
        assertEquals("Vertical time limit", 2000, model.getVerTimeLimit());
129
     
130
        // Verify scaled data parameters
131
        scaledData = model.scaleTo(101, 100, 1);
132
        
133
        assertEquals("barWidth", 1, scaledData.getBarWidth());
134
        assertEquals("height", 100, scaledData.getHeight());
135
        assertEquals("width", 101, scaledData.getWidth());
136
        
137
        assertEquals(Config.INVALID_EVENT_TIME, scaledData.getCurrentEventTime());
138
        
139
        assertEquals("Horizontal bucket duration", 1, scaledData.getHorBucketDuration());
140
        assertEquals("Vertical bucket duration", 1, scaledData.getVerBucketDuration());
141
        
142
        assertEquals("Horizontal bucket end time", 1, scaledData.getHorBucketEndTime(0));
143
        assertEquals("Vertical bucket end time", 1, scaledData.getVerBucketEndTime(0));
144
        
145
        assertEquals("Horizontal bucket start time", 0, scaledData.getHorBucketStartTime(0));
146
        assertEquals("Vertical bucket start time", 0, scaledData.getVerBucketStartTime(0));
147
148
        assertEquals("Horizontal first time", 0, scaledData.getHorFirstEventTime());
149
        assertEquals("Vertical first time", 0, scaledData.getVerFirstEventTime());
150
        
151
        assertEquals("Horizontal first bucket time", 0, scaledData.getHorFirstBucketTime());
152
        assertEquals("Vertical first bucket time", 0, scaledData.getVerFirstBucketTime());
153
154
        assertEquals("Horizontal last bucket time", 0, scaledData.getHorLastBucketTime());
155
        assertEquals("Vertical last bucket time", 0, scaledData.getVerLastBucketTime());
156
        
157
        assertEquals("Horizontal number of buckets", 101, scaledData.getHorNbBuckets());
158
        assertEquals("Vertical nubmer of buckets", 100, scaledData.getVerNbBuckets());
159
        
160
        assertEquals("Horizontal getIndex", 100, scaledData.getHorBucketIndex(100));
161
        assertEquals("Vertical getIndex", 124, scaledData.getVerBucketIndex(124));
162
        
163
        assertEquals("Horizontal last bucket", 0, scaledData.getHorLastBucket());
164
        assertEquals("Vertical last bucket", 0, scaledData.getVerLastBucket());
165
        
166
        assertEquals("Horizontal last event time", 0, scaledData.getHorLastEventTime());
167
        assertEquals("Vertical last event time", 0, scaledData.getVerLastEventTime());
168
    }
169
    
170
    public void testClear() {
171
        final int nbBuckets = 2000;
172
        final int nbEvents = 10 * nbBuckets + 256;
173
        
174
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
175
        for (int i = 0; i < nbEvents; i++) {
176
            model.countEvent(i+1, i, i);
177
        }
178
        // make sure that we actually counted something.
179
        GraphScaledData scaledData = model.scaleTo(100, 100, 1);
180
181
        assertTrue(scaledData.getHorLastBucket() > 0);
182
        
183
        model.clear();
184
        
185
        // Verify model parameters
186
        assertEquals("Horizontal bucket duration", 1, model.getHorBucketDuration());
187
        assertEquals("Vertical bucket duration", 1, model.getVerBucketDuration());
188
189
        assertEquals("Horizontal first bucket time", 0, model.getHorFirstBucketTime());
190
        assertEquals("Vertical first bucket time", 0, model.getVerFirstBucketTime());
191
192
        assertEquals("Horizontal last bucket ", 0, model.getHorLastBucket());
193
        assertEquals("Vertical last bucket ", 0, model.getVerLastBucket());
194
        
195
        assertEquals("Horizontal first time", 0, model.getHorFirstEventTime());
196
        assertEquals("Vertical first time", 0, model.getVerFirstEventTime());
197
198
        assertEquals("Horizontal last time", 0, model.getHorLastEventTime());
199
        assertEquals("Vertical last time", 0, model.getVerLastEventTime());
200
        
201
        assertEquals("Horizontal time limit", 2000, model.getHorTimeLimit());
202
        assertEquals("Vertical time limit", 2000, model.getVerTimeLimit());
203
204
        // Verify scaled data parameters
205
        scaledData = model.scaleTo(101, 100, 1);
206
        
207
        assertEquals("barWidth", 1, scaledData.getBarWidth());
208
        assertEquals("height", 100, scaledData.getHeight());
209
        assertEquals("width", 101, scaledData.getWidth());
210
        
211
        assertEquals(Config.INVALID_EVENT_TIME, scaledData.getCurrentEventTime());
212
        
213
        assertEquals("Horizontal bucket duration", 1, scaledData.getHorBucketDuration());
214
        assertEquals("Vertical bucket duration", 1, scaledData.getVerBucketDuration());
215
        
216
        assertEquals("Horizontal bucket end time", 1, scaledData.getHorBucketEndTime(0));
217
        assertEquals("Vertical bucket end time", 1, scaledData.getVerBucketEndTime(0));
218
        
219
        assertEquals("Horizontal bucket start time", 0, scaledData.getHorBucketStartTime(0));
220
        assertEquals("Vertical bucket start time", 0, scaledData.getVerBucketStartTime(0));
221
222
        assertEquals("Horizontal first time", 0, scaledData.getHorFirstEventTime());
223
        assertEquals("Vertical first time", 0, scaledData.getVerFirstEventTime());
224
        
225
        assertEquals("Horizontal first bucket time", 0, scaledData.getHorFirstBucketTime());
226
        assertEquals("Vertical first bucket time", 0, scaledData.getVerFirstBucketTime());
227
228
        assertEquals("Horizontal last bucket time", 0, scaledData.getHorLastBucketTime());
229
        assertEquals("Vertical last bucket time", 0, scaledData.getVerLastBucketTime());
230
        
231
        assertEquals("Horizontal getIndex", 100, scaledData.getHorBucketIndex(100));
232
        assertEquals("Vertical getIndex", 124, scaledData.getVerBucketIndex(124));
233
234
        assertEquals("Horizontal number of buckets", 101, scaledData.getHorNbBuckets());
235
        assertEquals("Vertical nubmer of buckets", 100, scaledData.getVerNbBuckets());
236
        
237
        assertEquals("Horizontal last bucket", 0, scaledData.getHorLastBucket());
238
        assertEquals("Vertical last bucket", 0, scaledData.getVerLastBucket());
239
        
240
        assertEquals("Horizontal last event time", 0, scaledData.getHorLastEventTime());
241
        assertEquals("Vertical last event time", 0, scaledData.getVerLastEventTime());
242
    }
243
    
244
    public void testCountEvent() {
245
        final int nbBuckets = 2000;
246
        final int nbEvents = 10 * nbBuckets + 256;
247
        final long hOffset = 100;
248
        final long vOffset = 55;
249
        
250
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
251
        
252
        for (int i = 0; i < nbEvents; i++) {
253
            model.countEvent(i + 1, hOffset + i, vOffset + i);
254
        }
255
256
        // Verify model parameters
257
        assertEquals("Horizontal bucket duration", 16, model.getHorBucketDuration());
258
        assertEquals("Vertical bucket duration", 16, model.getVerBucketDuration());
259
260
        assertEquals("Horizontal first bucket time", hOffset, model.getHorFirstBucketTime());
261
        assertEquals("Vertical first bucket time", vOffset, model.getVerFirstBucketTime());
262
263
        assertEquals("Horizontal last bucket ", (nbEvents - 1)/16, model.getHorLastBucket());
264
        assertEquals("Vertical last bucket ", (nbEvents - 1)/16, model.getVerLastBucket());
265
        
266
        assertEquals("Horizontal first time", hOffset, model.getHorFirstEventTime());
267
        assertEquals("Vertical first time", vOffset, model.getVerFirstEventTime());
268
269
        assertEquals("Horizontal last time", nbEvents + hOffset - 1, model.getHorLastEventTime());
270
        assertEquals("Vertical last time", nbEvents + vOffset - 1, model.getVerLastEventTime());
271
        
272
        assertEquals("Horizontal time limit", 16 * nbBuckets + hOffset, model.getHorTimeLimit());
273
        assertEquals("Vertical time limit", 16 * nbBuckets + vOffset, model.getVerTimeLimit());
274
275
        // Verify scaled data parameters
276
        GraphScaledData scaledData = model.scaleTo(50, 100, 1);
277
        
278
        assertEquals("barWidth", 1, scaledData.getBarWidth());
279
        assertEquals("height", 100, scaledData.getHeight());
280
        assertEquals("width", 50, scaledData.getWidth());
281
        
282
        assertEquals(Config.INVALID_EVENT_TIME, scaledData.getCurrentEventTime());
283
284
        // nbBars = width / barWidth
285
        // bucketsPerBar = lastBucket/nbBars + 1
286
        // scaled bucket duration = bucketsPerBar * model.bucketDuration
287
        // for nbBuckets=2000 and nbEvents=20256 (means 20256 ns + offset) -> model.bucketDuration = 16
288
        assertEquals("Horizontal bucket duration", 416, scaledData.getHorBucketDuration());
289
        assertEquals("Vertical bucket duration", 208, scaledData.getVerBucketDuration());
290
        
291
        // startTime + scaledData.bucketDuration
292
        assertEquals("Horizontal bucket end time", hOffset + 416, scaledData.getHorBucketEndTime(0));
293
        assertEquals("Vertical bucket end time", 55 + 208, scaledData.getVerBucketEndTime(0));
294
        
295
        assertEquals("Horizontal bucket start time", 100, scaledData.getHorBucketStartTime(0));
296
        assertEquals("Vertical bucket start time", 55, scaledData.getVerBucketStartTime(0));
297
298
        assertEquals("Horizontal first time", 100, scaledData.getHorFirstEventTime());
299
        assertEquals("Vertical first time", 55, scaledData.getVerFirstEventTime());
300
        
301
        assertEquals("Horizontal first bucket time", hOffset, scaledData.getHorFirstBucketTime());
302
        assertEquals("Vertical first bucket time", 55, scaledData.getVerFirstBucketTime());
303
        
304
        assertEquals("Horizontal last bucket time", hOffset + 48 * 416, scaledData.getHorLastBucketTime());
305
        assertEquals("Vertical last bucket time", vOffset + 97 * 208, scaledData.getVerLastBucketTime());
306
        
307
        assertEquals("Horizontal getIndex", 47, scaledData.getHorBucketIndex(20000));
308
        assertEquals("Vertical getIndex", 47, scaledData.getVerBucketIndex(10000));
309
        
310
        // nb Buckets = nbBars
311
        assertEquals("Horizontal number of buckets", 50, scaledData.getHorNbBuckets());
312
        assertEquals("Vertical nubmer of buckets", 100, scaledData.getVerNbBuckets());
313
        
314
        assertEquals("Horizontal last bucket", 48, scaledData.getHorLastBucket());
315
        assertEquals("Vertical last bucket", 97, scaledData.getVerLastBucket());
316
        
317
        // start time of last bucket
318
        assertEquals("Horizontal last event time", hOffset + nbEvents - 1, scaledData.getHorLastEventTime());
319
        assertEquals("Vertical last event time", vOffset + nbEvents - 1 , scaledData.getVerLastEventTime());
320
    }
321
322
    public void testCountEvent2() {
323
324
        final int nbBuckets = 2000;
325
        final int nbEvents = 10 * nbBuckets + 256;
326
        final long offset = 100;
327
        final int height = 100;
328
        final int width = 100;
329
        final int barWidth = 1;
330
        
331
        int[][] expectedResults = new int[width/barWidth][height/barWidth];
332
        
333
        int total = 0;
334
        
335
        // Horizontally and vertically the same data is used
336
        
337
        // for nbBuckets=2000 and nbEvents=20256 (means 20256 ns + offset) -> model.bucketDuration = 16
338
        // nbBars = width / barWidth = 100
339
        // bucketsPerBar = lastBucket/nbBars + 1 = 13
340
        // scaled bucket duration = bucketsPerBar * model.bucketDuration =  13 * 16
341
        boolean isFinished = false;
342
        for (int i = 0; i < width/barWidth; i++) {
343
            if (isFinished) {
344
                break;
345
            }
346
            for (int j = 0; j < height/barWidth; j++) {
347
                if (i == j) {
348
                    int value = 13 * 16;
349
                    if (total + value > nbEvents) {
350
                        expectedResults[i][j] = nbEvents - total;
351
                        isFinished = true;
352
                        break;
353
                    }
354
                    else {
355
                        expectedResults[i][j] = value;
356
                        total += value;
357
                    }
358
                }
359
            }
360
        }
361
       
362
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
363
        
364
        for (int i = 0; i < nbEvents; i++) {
365
            model.countEvent(i+1, offset + i, offset + i);
366
        }
367
368
        GraphScaledData scaledData = model.scaleTo(height, width, barWidth);
369
370
        for (int i = 0; i < scaledData.getHorLastBucket(); i++) {
371
            for (int j = 0; j < scaledData.getVerLastBucket(); j++) {
372
                assertEquals(expectedResults[i][j], scaledData.getEventCount(i, j));
373
            }
374
        }
375
    }
376
    
377
    public void testCountEvent3() {
378
        // Test with barWidth > 1
379
        final int nbBuckets = 2000;
380
        final int nbEvents = 10 * nbBuckets + 256;
381
        final long offset = 100;
382
        final int height = 100;
383
        final int width = 100;
384
        final int barWidth = 4;
385
        
386
        int[][] expectedResults = new int[width/barWidth][height/barWidth];
387
        
388
        int total = 0;
389
        
390
        // Horizontally and vertically the same data is used
391
        
392
        // for nbBuckets=2000 and nbEvents=20256 (means 20256 ns + offset) -> model.bucketDuration = 16
393
        // nbBars = width / barWidth = 25
394
        // bucketsPerBar = lastBucket/nbBars + 1 = 51
395
        // scaled bucket duration = bucketsPerBar * model.bucketDuration =  51 * 16
396
        boolean isFinished = false;
397
        for (int i = 0; i < width/barWidth; i++) {
398
            if (isFinished) {
399
                break;
400
            }
401
            for (int j = 0; j < height/barWidth; j++) {
402
                if (i == j) {
403
                    int value = 51 * 16;
404
                    if (total + value > nbEvents) {
405
                        expectedResults[i][j] = nbEvents - total;
406
                        isFinished = true;
407
                        break;
408
                    }
409
                    else {
410
                        expectedResults[i][j] = value;
411
                        total += value;
412
                    }
413
                }
414
            }
415
        }
416
       
417
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
418
        
419
        for (int i = 0; i < nbEvents; i++) {
420
            model.countEvent(i+1, offset + i, offset + i);
421
        }
422
423
        GraphScaledData scaledData = model.scaleTo(height, width, barWidth);
424
425
        for (int i = 0; i < scaledData.getHorLastBucket(); i++) {
426
            for (int j = 0; j < scaledData.getVerLastBucket(); j++) {
427
                assertEquals(expectedResults[i][j], scaledData.getEventCount(i, j));
428
            }
429
        }
430
    }
431
    
432
    public void testCountEventReverse1() {
433
        // Depending on the number of buckets and events the start buckets can be different
434
        // between forward and reserve times. However, the content is correct.
435
        final int nbBuckets = 100;
436
        final int nbEvents = 256;
437
        final long hOffset = 100;
438
        final long vOffset = 55;
439
        final int height = 100;
440
        final int width = 50;
441
        final int barWidth = 1;
442
443
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
444
        
445
        for (int i = 0; i < nbEvents; i++) {
446
            model.countEvent(i + 1, hOffset + i, vOffset + i);
447
        }
448
        
449
        GraphScaledData scaledData = model.scaleTo(width, height, barWidth);
450
        
451
        model.clear();
452
        
453
        for (int i = nbEvents - 1; i >= 0; i--) {
454
            model.countEvent(nbEvents - i, hOffset + i, vOffset + i);
455
        }
456
        
457
        GraphScaledData scaledDataReverse = model.scaleTo(50, 100, 1);
458
        
459
        long count = 0;
460
        for (int i = 0; i <= scaledData.getHorLastBucket(); i++) {
461
            for (int j = 0; j <= scaledData.getVerLastBucket(); j++) {
462
                count += scaledData.getEventCount(i, j);
463
            }
464
        }
465
        
466
        long revCount = 0;
467
        for (int i = 0; i <= scaledDataReverse.getHorLastBucket(); i++) {
468
            for (int j = 0; j <= scaledDataReverse.getVerLastBucket(); j++) {
469
                revCount += scaledDataReverse.getEventCount(i, j);
470
            }
471
        }
472
473
        assertEquals(count, revCount);
474
475
        // Make sure that both scaledData have the same content
476
        assertTrue("barWidth", scaledData.getBarWidth() == scaledDataReverse.getBarWidth());
477
        assertTrue("height", scaledData.getHeight() == scaledDataReverse.getHeight());
478
        assertTrue("width", scaledData.getWidth() == scaledDataReverse.getWidth());
479
        
480
        assertTrue(scaledData.getCurrentEventTime() == scaledDataReverse.getCurrentEventTime());
481
482
        assertTrue("Horizontal bucket duration", scaledData.getHorBucketDuration() == scaledDataReverse.getHorBucketDuration());
483
        assertTrue("Vertical bucket duration", scaledData.getVerBucketDuration() == scaledDataReverse.getVerBucketDuration());
484
        
485
        // startTime + scaledData.bucketDuration
486
        assertTrue("Horizontal bucket end time", scaledData.getHorBucketEndTime(0) == scaledDataReverse.getHorBucketEndTime(0));
487
        assertTrue("Vertical bucket end time", scaledData.getVerBucketEndTime(0) == scaledDataReverse.getVerBucketEndTime(0));
488
        
489
        assertTrue("Horizontal bucket start time", scaledData.getHorBucketStartTime(0) == scaledDataReverse.getHorBucketStartTime(0));
490
        assertTrue("Vertical bucket start time", scaledData.getVerBucketStartTime(0) == scaledDataReverse.getVerBucketStartTime(0));
491
492
        assertTrue("Horizontal first time", scaledData.getHorFirstEventTime() == scaledDataReverse.getHorFirstEventTime());
493
        assertTrue("Vertical first time",  scaledData.getVerFirstEventTime() == scaledDataReverse.getVerFirstEventTime());
494
        
495
        assertTrue("Horizontal getIndex", scaledData.getHorBucketIndex(200) == scaledDataReverse.getHorBucketIndex(200));
496
        assertTrue("Vertical getIndex", scaledData.getVerBucketIndex(100) == scaledDataReverse.getVerBucketIndex(100));
497
498
        assertTrue("Horizontal last bucket", scaledData.getHorNbBuckets() == scaledDataReverse.getHorNbBuckets());
499
        assertTrue("Vertical last bucket", scaledData.getVerNbBuckets() == scaledDataReverse.getVerNbBuckets());
500
501
        assertTrue("Horizontal nubmer of buckets", scaledData.getHorLastBucket() == scaledDataReverse.getHorLastBucket());
502
        assertTrue("Vertical nubmer of buckets", scaledData.getVerLastBucket() == scaledDataReverse.getVerLastBucket());
503
        
504
        // start time of last bucket
505
        assertTrue("Horizontal last event time", scaledData.getHorLastEventTime() == scaledDataReverse.getHorLastEventTime());
506
        assertTrue("Vertical last event time", scaledData.getVerLastEventTime() == scaledDataReverse.getVerLastEventTime());
507
    }
508
509
    public void testCountEventReverse2() {
510
        // Depending on the number of buckets and events the start buckets can be different
511
        // between forward and reserve times. However, the content is correct.
512
        final int nbBuckets = 100;
513
        final int nbEvents = 256;
514
        final long hOffset = 100;
515
        final long vOffset = 55;
516
        final int height = 100;
517
        final int width = 50;
518
        final int barWidth = 1;
519
520
        LatencyGraphModel model = new LatencyGraphModel(nbBuckets);
521
        
522
        for (int i = nbEvents - 1; i >= 0; i--) {
523
            model.countEvent(nbEvents - i, hOffset + i, vOffset + i);
524
        }
525
526
        // Verify model parameters
527
        int expectedBucketDuration = 4;
528
        assertEquals("Horizontal bucket duration", expectedBucketDuration, model.getHorBucketDuration());
529
        assertEquals("Vertical bucket duration", expectedBucketDuration, model.getVerBucketDuration());
530
531
        assertEquals("Horizontal first bucket time", hOffset, model.getHorFirstBucketTime());
532
        assertEquals("Vertical first bucket time", vOffset, model.getVerFirstBucketTime());
533
534
        assertEquals("Horizontal last bucket", (nbEvents -1)/expectedBucketDuration, model.getHorLastBucket());
535
        assertEquals("Vertical last bucket", (nbEvents -1)/expectedBucketDuration, model.getVerLastBucket());
536
537
        assertEquals("Horizontal first time", hOffset, model.getHorFirstEventTime());
538
        assertEquals("Vertical first time", vOffset, model.getVerFirstEventTime());
539
540
        assertEquals("Horizontal last time", nbEvents + hOffset - 1, model.getHorLastEventTime());
541
        assertEquals("Vertical last time", nbEvents + vOffset - 1, model.getVerLastEventTime());
542
543
        assertEquals("Horizontal time limit", expectedBucketDuration * nbBuckets + hOffset, model.getHorTimeLimit());
544
        assertEquals("Vertical time limit", expectedBucketDuration * nbBuckets + vOffset, model.getVerTimeLimit());
545
546
        GraphScaledData scaledData = model.scaleTo(50, 100, 1);
547
        
548
        // Make sure that both scaledData have the same content
549
        assertEquals("barWidth", barWidth, scaledData.getBarWidth());
550
        assertEquals("height", height, scaledData.getHeight());
551
        assertEquals("width", width, scaledData.getWidth());
552
        
553
        assertEquals(-1, scaledData.getCurrentEventTime()); 
554
        
555
        assertEquals("Horizontal bucket duration", 8, scaledData.getHorBucketDuration());
556
        assertEquals("Vertical bucket duration", 4, scaledData.getVerBucketDuration());
557
        
558
        // startTime + scaledData.bucketDuration
559
        assertEquals("Horizontal bucket end time", hOffset + 8, scaledData.getHorBucketEndTime(0));
560
        assertEquals("Vertical bucket end time", vOffset + 4, scaledData.getVerBucketEndTime(0));
561
        
562
        assertEquals("Horizontal bucket start time", hOffset, scaledData.getHorBucketStartTime(0));
563
        assertEquals("Vertical bucket start time", vOffset, scaledData.getVerBucketStartTime(0));
564
565
        assertEquals("Horizontal first time", hOffset, scaledData.getHorFirstEventTime());
566
        assertEquals("Vertical first time",  vOffset, scaledData.getVerFirstEventTime());
567
        
568
        assertEquals("Horizontal getIndex", 12, scaledData.getHorBucketIndex(200));
569
        assertEquals("Vertical getIndex", 11, scaledData.getVerBucketIndex(100));
570
571
        // nb Buckets = nbBars
572
        assertEquals("Horizontal number of buckets", 50, scaledData.getHorNbBuckets());
573
        assertEquals("Vertical number of buckets", 100, scaledData.getVerNbBuckets());
574
        
575
        assertEquals("Horizontal last bucket", 31, scaledData.getHorLastBucket());
576
        assertEquals("Vertical last bucket", 63, scaledData.getVerLastBucket());
577
 
578
        // start time of last bucket
579
        assertEquals("Horizontal last event time", 355, scaledData.getHorLastEventTime());
580
        assertEquals("Vertical last event time", 310, scaledData.getVerLastEventTime());
581
    }
582
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui.tests/src/org/eclipse/linuxtools/lttng/ui/tests/histogram/HistogramDataModelTest.java (-28 / +228 lines)
Lines 17-22 import junit.framework.TestCase; Link Here
17
17
18
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramDataModel;
18
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramDataModel;
19
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramScaledData;
19
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramScaledData;
20
import org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramModelListener;
20
21
21
/**
22
/**
22
 * <b><u>HistogramDataModelTest</u></b>
23
 * <b><u>HistogramDataModelTest</u></b>
Lines 55-60 public class HistogramDataModelTest extends TestCase { Link Here
55
        assertTrue(model.getNbBuckets() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
56
        assertTrue(model.getNbBuckets() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
56
        assertTrue(model.getNbEvents() == 0);
57
        assertTrue(model.getNbEvents() == 0);
57
        assertTrue(model.getBucketDuration() == 1);
58
        assertTrue(model.getBucketDuration() == 1);
59
        assertTrue(model.getFirstBucketTime() == 0);
58
        assertTrue(model.getStartTime() == 0);
60
        assertTrue(model.getStartTime() == 0);
59
        assertTrue(model.getEndTime() == 0);
61
        assertTrue(model.getEndTime() == 0);
60
        assertTrue(model.getTimeLimit() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
62
        assertTrue(model.getTimeLimit() == HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS);
Lines 71-76 public class HistogramDataModelTest extends TestCase { Link Here
71
        assertTrue(model.getNbEvents() == 0);
73
        assertTrue(model.getNbEvents() == 0);
72
        assertTrue(model.getNbBuckets() == nbBuckets);
74
        assertTrue(model.getNbBuckets() == nbBuckets);
73
        assertTrue(model.getBucketDuration() == 1);
75
        assertTrue(model.getBucketDuration() == 1);
76
        assertTrue(model.getFirstBucketTime() == 0);
74
        assertTrue(model.getStartTime() == 0);
77
        assertTrue(model.getStartTime() == 0);
75
        assertTrue(model.getEndTime() == 0);
78
        assertTrue(model.getEndTime() == 0);
76
        assertTrue(model.getTimeLimit() == nbBuckets);
79
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 84-94 public class HistogramDataModelTest extends TestCase { Link Here
84
    public void testClear() {
87
    public void testClear() {
85
        final int nbBuckets = 100;
88
        final int nbBuckets = 100;
86
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
89
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
87
        model.countEvent(-1);
90
        model.countEvent(0, -1);
88
91
89
        assertTrue(model.getNbEvents() == 0);
92
        assertTrue(model.getNbEvents() == 0);
90
        assertTrue(model.getNbBuckets() == nbBuckets);
93
        assertTrue(model.getNbBuckets() == nbBuckets);
91
        assertTrue(model.getBucketDuration() == 1);
94
        assertTrue(model.getBucketDuration() == 1);
95
        assertTrue(model.getFirstBucketTime() == 0);
92
        assertTrue(model.getStartTime() == 0);
96
        assertTrue(model.getStartTime() == 0);
93
        assertTrue(model.getEndTime() == 0);
97
        assertTrue(model.getEndTime() == 0);
94
        assertTrue(model.getTimeLimit() == nbBuckets);
98
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 102-112 public class HistogramDataModelTest extends TestCase { Link Here
102
    public void testCountEvent_0() {
106
    public void testCountEvent_0() {
103
        final int nbBuckets = 100;
107
        final int nbBuckets = 100;
104
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
108
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
105
        model.countEvent(-1);
109
        model.countEvent(0, -1);
106
110
107
        assertTrue(model.getNbEvents() == 0);
111
        assertTrue(model.getNbEvents() == 0);
108
        assertTrue(model.getNbBuckets() == nbBuckets);
112
        assertTrue(model.getNbBuckets() == nbBuckets);
109
        assertTrue(model.getBucketDuration() == 1);
113
        assertTrue(model.getBucketDuration() == 1);
114
        assertTrue(model.getFirstBucketTime() == 0);
110
        assertTrue(model.getStartTime() == 0);
115
        assertTrue(model.getStartTime() == 0);
111
        assertTrue(model.getEndTime() == 0);
116
        assertTrue(model.getEndTime() == 0);
112
        assertTrue(model.getTimeLimit() == nbBuckets);
117
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 118-124 public class HistogramDataModelTest extends TestCase { Link Here
118
123
119
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
124
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
120
125
121
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
126
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
122
        for (int i = 0; i < result.fData.length; i++) {
127
        for (int i = 0; i < result.fData.length; i++) {
123
            assertTrue(result.fData[i] == 0);
128
            assertTrue(result.fData[i] == 0);
124
        }
129
        }
Lines 126-131 public class HistogramDataModelTest extends TestCase { Link Here
126
        assertTrue(model.getNbEvents() == 0);
131
        assertTrue(model.getNbEvents() == 0);
127
        assertTrue(model.getNbBuckets() == nbBuckets);
132
        assertTrue(model.getNbBuckets() == nbBuckets);
128
        assertTrue(model.getBucketDuration() == 1);
133
        assertTrue(model.getBucketDuration() == 1);
134
        assertTrue(model.getFirstBucketTime() == 0);
129
        assertTrue(model.getStartTime() == 0);
135
        assertTrue(model.getStartTime() == 0);
130
        assertTrue(model.getEndTime() == 0);
136
        assertTrue(model.getEndTime() == 0);
131
        assertTrue(model.getTimeLimit() == nbBuckets);
137
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 136-144 public class HistogramDataModelTest extends TestCase { Link Here
136
        final int maxHeight = 10;
142
        final int maxHeight = 10;
137
143
138
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
144
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
139
        model.countEvent(1);
145
        model.countEvent(0, 1);
140
146
141
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
147
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
142
        assertTrue(result.fData[0] == 1);
148
        assertTrue(result.fData[0] == 1);
143
        for (int i = 1; i < result.fData.length; i++) {
149
        for (int i = 1; i < result.fData.length; i++) {
144
            assertTrue(result.fData[i] == 0);
150
            assertTrue(result.fData[i] == 0);
Lines 147-152 public class HistogramDataModelTest extends TestCase { Link Here
147
        assertTrue(model.getNbEvents() == 1);
153
        assertTrue(model.getNbEvents() == 1);
148
        assertTrue(model.getNbBuckets() == nbBuckets);
154
        assertTrue(model.getNbBuckets() == nbBuckets);
149
        assertTrue(model.getBucketDuration() == 1);
155
        assertTrue(model.getBucketDuration() == 1);
156
        assertTrue(model.getFirstBucketTime() == 1);
150
        assertTrue(model.getStartTime() == 1);
157
        assertTrue(model.getStartTime() == 1);
151
        assertTrue(model.getEndTime() == 1);
158
        assertTrue(model.getEndTime() == 1);
152
        assertTrue(model.getTimeLimit() == nbBuckets + 1);
159
        assertTrue(model.getTimeLimit() == nbBuckets + 1);
Lines 158-167 public class HistogramDataModelTest extends TestCase { Link Here
158
165
159
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
166
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
160
        for (int i = 0; i < nbBuckets; i++) {
167
        for (int i = 0; i < nbBuckets; i++) {
161
            model.countEvent(i);
168
            model.countEvent(i, i);
162
        }
169
        }
163
170
164
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
171
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
165
        for (int i = 0; i < result.fData.length; i++) {
172
        for (int i = 0; i < result.fData.length; i++) {
166
            assertTrue(result.fData[i] == 1);
173
            assertTrue(result.fData[i] == 1);
167
        }
174
        }
Lines 169-174 public class HistogramDataModelTest extends TestCase { Link Here
169
        assertTrue(model.getNbEvents() == nbBuckets);
176
        assertTrue(model.getNbEvents() == nbBuckets);
170
        assertTrue(model.getNbBuckets() == nbBuckets);
177
        assertTrue(model.getNbBuckets() == nbBuckets);
171
        assertTrue(model.getBucketDuration() == 1);
178
        assertTrue(model.getBucketDuration() == 1);
179
        assertTrue(model.getFirstBucketTime() == 0);
172
        assertTrue(model.getStartTime() == 0);
180
        assertTrue(model.getStartTime() == 0);
173
        assertTrue(model.getEndTime() == nbBuckets - 1);
181
        assertTrue(model.getEndTime() == nbBuckets - 1);
174
        assertTrue(model.getTimeLimit() == nbBuckets);
182
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 180-190 public class HistogramDataModelTest extends TestCase { Link Here
180
188
181
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
189
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
182
        for (int i = 0; i < nbBuckets; i++) {
190
        for (int i = 0; i < nbBuckets; i++) {
183
            model.countEvent(i);
191
            model.countEvent(i, i);
184
            model.countEvent(i);
192
            model.countEvent(i+1, i);
185
        }
193
        }
186
194
187
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
195
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
188
        for (int i = 0; i < result.fData.length; i++) {
196
        for (int i = 0; i < result.fData.length; i++) {
189
            assertTrue(result.fData[i] == 2);
197
            assertTrue(result.fData[i] == 2);
190
        }
198
        }
Lines 192-197 public class HistogramDataModelTest extends TestCase { Link Here
192
        assertTrue(model.getNbEvents() == 2 * nbBuckets);
200
        assertTrue(model.getNbEvents() == 2 * nbBuckets);
193
        assertTrue(model.getNbBuckets() == nbBuckets);
201
        assertTrue(model.getNbBuckets() == nbBuckets);
194
        assertTrue(model.getBucketDuration() == 1);
202
        assertTrue(model.getBucketDuration() == 1);
203
        assertTrue(model.getFirstBucketTime() == 0);
195
        assertTrue(model.getStartTime() == 0);
204
        assertTrue(model.getStartTime() == 0);
196
        assertTrue(model.getEndTime() == nbBuckets - 1);
205
        assertTrue(model.getEndTime() == nbBuckets - 1);
197
        assertTrue(model.getTimeLimit() == nbBuckets);
206
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 204-213 public class HistogramDataModelTest extends TestCase { Link Here
204
213
205
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
214
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
206
        for (int i = startTime; i < startTime + nbBuckets; i++) {
215
        for (int i = startTime; i < startTime + nbBuckets; i++) {
207
            model.countEvent(i);
216
            model.countEvent(i, i);
208
        }
217
        }
209
218
210
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
219
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
211
        for (int i = 0; i < result.fData.length; i++) {
220
        for (int i = 0; i < result.fData.length; i++) {
212
            assertTrue(result.fData[i] == 1);
221
            assertTrue(result.fData[i] == 1);
213
        }
222
        }
Lines 215-220 public class HistogramDataModelTest extends TestCase { Link Here
215
        assertTrue(model.getNbEvents() == nbBuckets);
224
        assertTrue(model.getNbEvents() == nbBuckets);
216
        assertTrue(model.getNbBuckets() == nbBuckets);
225
        assertTrue(model.getNbBuckets() == nbBuckets);
217
        assertTrue(model.getBucketDuration() == 1);
226
        assertTrue(model.getBucketDuration() == 1);
227
        assertTrue(model.getFirstBucketTime() == startTime);
218
        assertTrue(model.getStartTime() == startTime);
228
        assertTrue(model.getStartTime() == startTime);
219
        assertTrue(model.getEndTime() == startTime + nbBuckets - 1);
229
        assertTrue(model.getEndTime() == startTime + nbBuckets - 1);
220
        assertTrue(model.getTimeLimit() == startTime + nbBuckets);
230
        assertTrue(model.getTimeLimit() == startTime + nbBuckets);
Lines 228-242 public class HistogramDataModelTest extends TestCase { Link Here
228
    public void testScaleTo_0() {
238
    public void testScaleTo_0() {
229
        HistogramDataModel model = new HistogramDataModel(10);
239
        HistogramDataModel model = new HistogramDataModel(10);
230
        try {
240
        try {
231
            model.scaleTo(10, 0);
241
            model.scaleTo(10, 0, 1);
232
        }
242
        }
233
        catch (AssertionError e1) {
243
        catch (AssertionError e1) {
234
            try {
244
            try {
235
                model.scaleTo(0, 10);
245
                model.scaleTo(0, 10, 1);
236
            }
246
            }
237
            catch (AssertionError e2) {
247
            catch (AssertionError e2) {
238
                try {
248
                try {
239
                    model.scaleTo(0, 0);
249
                    model.scaleTo(0, 0, 1);
240
                }
250
                }
241
                catch (AssertionError e3) {
251
                catch (AssertionError e3) {
242
                    return;
252
                    return;
Lines 255-264 public class HistogramDataModelTest extends TestCase { Link Here
255
265
256
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
266
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
257
        for (int i = 0; i < nbEvents; i++) {
267
        for (int i = 0; i < nbEvents; i++) {
258
            model.countEvent(i);
268
            model.countEvent(i, i);
259
        }
269
        }
260
270
261
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
271
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
262
        for (int i = 0; i < result.fData.length; i++) {
272
        for (int i = 0; i < result.fData.length; i++) {
263
            assertTrue(result.fData[i] == expectedResult[i]);
273
            assertTrue(result.fData[i] == expectedResult[i]);
264
        }
274
        }
Lines 266-271 public class HistogramDataModelTest extends TestCase { Link Here
266
        assertTrue(model.getNbEvents() == nbEvents);
276
        assertTrue(model.getNbEvents() == nbEvents);
267
        assertTrue(model.getNbBuckets() == nbBuckets);
277
        assertTrue(model.getNbBuckets() == nbBuckets);
268
        assertTrue(model.getBucketDuration() == 1);
278
        assertTrue(model.getBucketDuration() == 1);
279
        assertTrue(model.getFirstBucketTime() == 0);
269
        assertTrue(model.getStartTime() == 0);
280
        assertTrue(model.getStartTime() == 0);
270
        assertTrue(model.getEndTime() == nbEvents - 1);
281
        assertTrue(model.getEndTime() == nbEvents - 1);
271
        assertTrue(model.getTimeLimit() == nbBuckets);
282
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 279-288 public class HistogramDataModelTest extends TestCase { Link Here
279
290
280
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
291
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
281
        for (int i = 0; i < nbEvents; i++) {
292
        for (int i = 0; i < nbEvents; i++) {
282
            model.countEvent(i);
293
            model.countEvent(i, i);
283
        }
294
        }
284
295
285
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
296
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
286
        for (int i = 0; i < result.fData.length; i++) {
297
        for (int i = 0; i < result.fData.length; i++) {
287
            assertTrue(result.fData[i] == expectedResult[i]);
298
            assertTrue(result.fData[i] == expectedResult[i]);
288
        }
299
        }
Lines 290-295 public class HistogramDataModelTest extends TestCase { Link Here
290
        assertTrue(model.getNbEvents() == nbEvents);
301
        assertTrue(model.getNbEvents() == nbEvents);
291
        assertTrue(model.getNbBuckets() == nbBuckets);
302
        assertTrue(model.getNbBuckets() == nbBuckets);
292
        assertTrue(model.getBucketDuration() == 1);
303
        assertTrue(model.getBucketDuration() == 1);
304
        assertTrue(model.getFirstBucketTime() == 0);
293
        assertTrue(model.getStartTime() == 0);
305
        assertTrue(model.getStartTime() == 0);
294
        assertTrue(model.getEndTime() == nbEvents - 1);
306
        assertTrue(model.getEndTime() == nbEvents - 1);
295
        assertTrue(model.getTimeLimit() == nbBuckets);
307
        assertTrue(model.getTimeLimit() == nbBuckets);
Lines 303-312 public class HistogramDataModelTest extends TestCase { Link Here
303
315
304
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
316
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
305
        for (int i = 0; i < nbEvents; i++) {
317
        for (int i = 0; i < nbEvents; i++) {
306
            model.countEvent(i);
318
            model.countEvent(i, i);
307
        }
319
        }
308
320
309
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
321
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
310
        for (int i = 0; i < result.fData.length; i++) {
322
        for (int i = 0; i < result.fData.length; i++) {
311
            assertTrue(result.fData[i] == expectedResult[i]);
323
            assertTrue(result.fData[i] == expectedResult[i]);
312
        }
324
        }
Lines 314-319 public class HistogramDataModelTest extends TestCase { Link Here
314
        assertTrue(model.getNbEvents() == nbEvents);
326
        assertTrue(model.getNbEvents() == nbEvents);
315
        assertTrue(model.getNbBuckets() == nbBuckets);
327
        assertTrue(model.getNbBuckets() == nbBuckets);
316
        assertTrue(model.getBucketDuration() == 2);
328
        assertTrue(model.getBucketDuration() == 2);
329
        assertTrue(model.getFirstBucketTime() == 0);
317
        assertTrue(model.getStartTime() == 0);
330
        assertTrue(model.getStartTime() == 0);
318
        assertTrue(model.getEndTime() == nbEvents - 1);
331
        assertTrue(model.getEndTime() == nbEvents - 1);
319
        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
332
        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
Lines 327-336 public class HistogramDataModelTest extends TestCase { Link Here
327
340
328
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
341
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
329
        for (int i = 0; i < nbEvents; i++) {
342
        for (int i = 0; i < nbEvents; i++) {
330
            model.countEvent(i);
343
            model.countEvent(i, i);
331
        }
344
        }
332
345
333
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight);
346
        HistogramScaledData result = model.scaleTo(nbBuckets, maxHeight, 1);
334
        for (int i = 0; i < result.fData.length; i++) {
347
        for (int i = 0; i < result.fData.length; i++) {
335
            assertTrue(result.fData[i] == expectedResult[i]);
348
            assertTrue(result.fData[i] == expectedResult[i]);
336
        }
349
        }
Lines 338-343 public class HistogramDataModelTest extends TestCase { Link Here
338
        assertTrue(model.getNbEvents() == nbEvents);
351
        assertTrue(model.getNbEvents() == nbEvents);
339
        assertTrue(model.getNbBuckets() == nbBuckets);
352
        assertTrue(model.getNbBuckets() == nbBuckets);
340
        assertTrue(model.getBucketDuration() == 4);
353
        assertTrue(model.getBucketDuration() == 4);
354
        assertTrue(model.getFirstBucketTime() == 0);
341
        assertTrue(model.getStartTime() == 0);
355
        assertTrue(model.getStartTime() == 0);
342
        assertTrue(model.getEndTime() == nbEvents - 1);
356
        assertTrue(model.getEndTime() == nbEvents - 1);
343
        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
357
        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
Lines 351-360 public class HistogramDataModelTest extends TestCase { Link Here
351
365
352
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
366
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
353
        for (int i = 0; i < nbEvents; i++) {
367
        for (int i = 0; i < nbEvents; i++) {
354
            model.countEvent(i);
368
            model.countEvent(i, i);
355
        }
369
        }
356
370
357
        HistogramScaledData result = model.scaleTo(10, maxHeight);
371
        HistogramScaledData result = model.scaleTo(10, maxHeight, 1);
358
        for (int i = 0; i < result.fData.length; i++) {
372
        for (int i = 0; i < result.fData.length; i++) {
359
            assertTrue(result.fData[i] == expectedResult[i]);
373
            assertTrue(result.fData[i] == expectedResult[i]);
360
        }
374
        }
Lines 362-368 public class HistogramDataModelTest extends TestCase { Link Here
362
        assertTrue(model.getNbEvents() == nbEvents);
376
        assertTrue(model.getNbEvents() == nbEvents);
363
        assertTrue(model.getNbBuckets() == nbBuckets);
377
        assertTrue(model.getNbBuckets() == nbBuckets);
364
        assertTrue(model.getBucketDuration() == 2);
378
        assertTrue(model.getBucketDuration() == 2);
365
        assertTrue(model.getStartTime() == 0);
379
        assertTrue(model.getFirstBucketTime() == 0);
366
        assertTrue(model.getEndTime() == nbEvents - 1);
380
        assertTrue(model.getEndTime() == nbEvents - 1);
367
        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
381
        assertTrue(model.getTimeLimit() == 2 * nbBuckets);
368
    }
382
    }
Lines 375-384 public class HistogramDataModelTest extends TestCase { Link Here
375
389
376
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
390
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
377
        for (int i = 0; i < nbEvents; i++) {
391
        for (int i = 0; i < nbEvents; i++) {
378
            model.countEvent(i);
392
            model.countEvent(i, i);
379
        }
393
        }
380
394
381
        HistogramScaledData result = model.scaleTo(10, maxHeight);
395
        HistogramScaledData result = model.scaleTo(10, maxHeight, 1);
382
        for (int i = 0; i < result.fData.length; i++) {
396
        for (int i = 0; i < result.fData.length; i++) {
383
            assertTrue(result.fData[i] == expectedResult[i]);
397
            assertTrue(result.fData[i] == expectedResult[i]);
384
        }
398
        }
Lines 386-394 public class HistogramDataModelTest extends TestCase { Link Here
386
        assertTrue(model.getNbEvents() == nbEvents);
400
        assertTrue(model.getNbEvents() == nbEvents);
387
        assertTrue(model.getNbBuckets() == nbBuckets);
401
        assertTrue(model.getNbBuckets() == nbBuckets);
388
        assertTrue(model.getBucketDuration() == 4);
402
        assertTrue(model.getBucketDuration() == 4);
403
        assertTrue(model.getFirstBucketTime() == 0);
389
        assertTrue(model.getStartTime() == 0);
404
        assertTrue(model.getStartTime() == 0);
390
        assertTrue(model.getEndTime() == nbEvents - 1);
405
        assertTrue(model.getEndTime() == nbEvents - 1);
391
        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
406
        assertTrue(model.getTimeLimit() == 4 * nbBuckets);
392
    }
407
    }
408
    
409
    public void testScaleTo_7() {
410
        // verify scaleTo with barWidth > 1
411
        final int nbBuckets = 100;
412
        final int maxHeight = 24;
413
        final int width = 10;
414
        final int barWidth = 4;
415
        final int nbEvents = 2 * nbBuckets + 1;
416
        
417
        // (int)(width / barWith) = 2 
418
        // -> 2 bars -> expected result needs two buckets (scaled data) 
419
        // 
420
        // buckets (in model) per bar = last bucket id / nbBars + 1 (plus 1 to cover all used buckets)
421
        // -> buckets per bar = 50 / 2 + 1 = 26 
422
        // -> first entry in expected result is 26 * 4 = 104
423
        // -> second entry in expected result is 22 * 4 + 9 = 97
424
        final int[] expectedResult = new int[] { 104, 97 };
425
        
426
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
427
        for (int i = 0; i < nbEvents; i++) {
428
            model.countEvent(i, i);
429
        }
430
431
        // verify scaled data
432
        HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth);
433
        
434
        assertEquals(4 * 26, result.fBucketDuration);
435
        assertEquals(0, result.fCurrentBucket);
436
        assertEquals(0, result.fFirstBucketTime);
437
        assertEquals(0, result.fFirstEventTime);
438
        assertEquals(1, result.fLastBucket);
439
        assertEquals(104, result.fMaxValue);
440
        assertEquals((double)maxHeight/104, result.fScalingFactor);
441
        assertEquals(maxHeight, result.fHeight);
442
        assertEquals(width, result.fWidth);
443
        assertEquals(barWidth, result.fBarWidth);
444
445
        for (int i = 0; i < result.fData.length; i++) {
446
            assertEquals(expectedResult[i], result.fData[i]);
447
        }
448
        
449
        // verify model
450
        assertEquals(nbEvents, model.getNbEvents());
451
        assertEquals(nbBuckets, model.getNbBuckets());
452
        assertEquals(4, model.getBucketDuration());
453
        assertEquals(0, model.getFirstBucketTime());
454
        assertEquals(0, model.getStartTime());
455
        assertEquals(nbEvents - 1, model.getEndTime());
456
        assertEquals(4 * nbBuckets, model.getTimeLimit());
457
    }
393
458
459
    public void testScaleToReverse_1() {
460
        final int nbBuckets = 100;
461
        final int maxHeight = 24;
462
        final int width = 10;
463
        final int barWidth = 1;
464
        final int nbEvents = 2 * nbBuckets + 1;
465
        
466
        // (int)(width / barWith) = 10 
467
        // -> 10 bars -> expected result needs 10 buckets (scaled data) 
468
        // 
469
        // buckets in (model) per bar = last bucket id / nbBars + 1 (plus 1 to cover all used buckets)
470
        // -> buckets per bar = 50 / 10 + 1 = 6 
471
        final int[] expectedResult = new int[] { 21, 24, 24, 24, 24, 24, 24, 24, 12, 0 };
472
        
473
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
474
        for (int i = nbEvents - 1; i >= 0; i--) {
475
            model.countEvent(i, i);
476
        }
477
478
        // verify scaled data
479
        HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth);
480
        
481
        assertEquals(4 * 6, result.fBucketDuration);
482
        assertEquals(0, result.fCurrentBucket);
483
        assertEquals(-3, result.fFirstBucketTime); // negative is correct, can happen when reverse
484
        assertEquals(0, result.fFirstEventTime);
485
        assertEquals(9, result.fLastBucket);
486
        assertEquals(24, result.fMaxValue);
487
        assertEquals((double)maxHeight/24, result.fScalingFactor);
488
        assertEquals(maxHeight, result.fHeight);
489
        assertEquals(width, result.fWidth);
490
        assertEquals(barWidth, result.fBarWidth);
491
492
        for (int i = 0; i < result.fData.length; i++) {
493
            assertEquals(expectedResult[i], result.fData[i]);
494
        }
495
        
496
        // verify model
497
        assertEquals(nbEvents, model.getNbEvents());
498
        assertEquals(nbBuckets, model.getNbBuckets());
499
        assertEquals(4, model.getBucketDuration());
500
        assertEquals(-3, model.getFirstBucketTime());
501
        assertEquals(0, model.getStartTime());
502
        assertEquals(nbEvents - 1, model.getEndTime());
503
        assertEquals(-3 + 4 * nbBuckets, model.getTimeLimit());
504
    }
505
506
    
507
    public void testScaleToReverse_2() { 
508
        final int nbBuckets = 100;
509
        final int maxHeight = 24;
510
        final int width = 10;
511
        final int barWidth = 1;
512
        
513
        final int nbEvents = 2 * nbBuckets;
514
515
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
516
        for (int i = 0; i < nbEvents; i++) {
517
            model.countEvent(i, i);
518
        }
519
520
        HistogramScaledData result = model.scaleTo(width, maxHeight, barWidth);
521
522
        model.clear();
523
        
524
        for (int i = nbEvents -1; i >= 0; i--) {
525
            model.countEvent(i, i);
526
        }
527
        
528
        HistogramScaledData revResult = model.scaleTo(width, maxHeight, barWidth);
529
        
530
        assertEquals(nbEvents, model.getNbEvents());
531
        assertEquals(nbBuckets, model.getNbBuckets());
532
        assertEquals(2, model.getBucketDuration());
533
        assertEquals(0, model.getFirstBucketTime());
534
        assertEquals(0, model.getStartTime());
535
        assertEquals(nbEvents - 1, model.getEndTime());
536
        assertEquals(2 * nbBuckets, model.getTimeLimit());
537
        
538
        // For the above number of events, result and revResult are exactly the same. 
539
        assertEquals(result.fBucketDuration, revResult.fBucketDuration);
540
        assertEquals(result.fCurrentBucket, revResult.fCurrentBucket);
541
        assertEquals(result.fFirstBucketTime, revResult.fFirstBucketTime);
542
        assertEquals(result.fMaxValue, revResult.fMaxValue);
543
        assertEquals(result.fScalingFactor, revResult.fScalingFactor);
544
        assertEquals(result.fLastBucket, revResult.fLastBucket);
545
        assertEquals(result.getBucketEndTime(0), revResult.getBucketEndTime(0));
546
        assertEquals(result.getBucketStartTime(0), revResult.getBucketStartTime(0));
547
        
548
        for (int i = 0; i < result.fData.length; i++) {
549
            assertTrue(result.fData[i] == revResult.fData[i]);
550
        }
551
    }
552
    
553
    public void testModelListener() {
554
        final int nbBuckets = 2000;
555
        final int nbEvents = 10 * nbBuckets + 256;
556
        final int[] count = new int[1];
557
        count [0] = 0;
558
559
        // Test add listener and call of listener
560
        IHistogramModelListener listener = new IHistogramModelListener() {
561
            @Override
562
            public void modelUpdated() {
563
                count[0]++;
564
            }
565
        };
566
567
        // Test that the listener interface is called every 16000 events.
568
        HistogramDataModel model = new HistogramDataModel(nbBuckets);
569
        model.addHistogramListener(listener);
570
        for (int i = 0; i < nbEvents; i++) {
571
            model.countEvent(i+1, i);
572
        }
573
574
        assertTrue(count[0] == 1);
575
576
        // Test that the listener interface is called when complete is called.
577
        model.complete();
578
        assertTrue(count[0] == 2);
579
580
        // Test that clear triggers call of listener interface
581
        model.clear();
582
        assertTrue(count[0] == 3);
583
584
        // Test remove listener
585
        count[0] = 0;
586
        model.removeHistogramListener(listener);
587
        
588
        for (int i = 0; i < nbEvents; i++) {
589
            model.countEvent(i, i);
590
        }
591
        model.complete();
592
        assertTrue(count[0] == 0);
593
    }
394
}
594
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/META-INF/MANIFEST.MF (+5 lines)
Lines 38-45 Export-Package: org.eclipse.linuxtools.lttng.ui;x-friends:="org.eclipse.linuxtoo Link Here
38
 org.eclipse.linuxtools.lttng.ui.views.controlflow;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
38
 org.eclipse.linuxtools.lttng.ui.views.controlflow;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
39
 org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
39
 org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
40
 org.eclipse.linuxtools.lttng.ui.views.controlflow.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
40
 org.eclipse.linuxtools.lttng.ui.views.controlflow.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
41
 org.eclipse.linuxtools.lttng.ui.views.distribution.model,
41
 org.eclipse.linuxtools.lttng.ui.views.events;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
42
 org.eclipse.linuxtools.lttng.ui.views.events;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
42
 org.eclipse.linuxtools.lttng.ui.views.histogram;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
43
 org.eclipse.linuxtools.lttng.ui.views.histogram;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
44
 org.eclipse.linuxtools.lttng.ui.views.latency;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
45
 org.eclipse.linuxtools.lttng.ui.views.latency.dialogs;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
46
 org.eclipse.linuxtools.lttng.ui.views.latency.listeners;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
47
 org.eclipse.linuxtools.lttng.ui.views.latency.model;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
43
 org.eclipse.linuxtools.lttng.ui.views.project;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
48
 org.eclipse.linuxtools.lttng.ui.views.project;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
44
 org.eclipse.linuxtools.lttng.ui.views.project.dialogs;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
49
 org.eclipse.linuxtools.lttng.ui.views.project.dialogs;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
45
 org.eclipse.linuxtools.lttng.ui.views.project.handlers;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
50
 org.eclipse.linuxtools.lttng.ui.views.project.handlers;x-friends:="org.eclipse.linuxtools.lttng.ui.tests",
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/plugin.properties (+1 lines)
Lines 14-19 controlflow.view.name = Control Flow Link Here
14
resources.view.name = Resources
14
resources.view.name = Resources
15
statistics.view.name = Statistics
15
statistics.view.name = Statistics
16
histogram.view.name = Histogram
16
histogram.view.name = Histogram
17
latency.view.name = Latency View
17
18
18
wizard.category.name = LTTng
19
wizard.category.name = LTTng
19
project.new.wizard.name = LTTng Project
20
project.new.wizard.name = LTTng Project
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/plugin.xml (+9 lines)
Lines 90-95 Link Here
90
            name="%histogram.view.name"
90
            name="%histogram.view.name"
91
            restorable="true">
91
            restorable="true">
92
      </view>
92
      </view>
93
      <view
94
            allowMultiple="false"
95
            category="org.eclipse.linuxtools.lttng.ui.views.category"
96
            class="org.eclipse.linuxtools.lttng.ui.views.latency.LatencyView"
97
            icon="icons/eview16/graph.gif"
98
            id="org.eclipse.linuxtools.lttng.ui.views.latency"
99
            name="%latency.view.name"
100
            restorable="true">
101
      </view>
93
   </extension>
102
   </extension>
94
   <extension
103
   <extension
95
         point="org.eclipse.ui.newWizards">
104
         point="org.eclipse.ui.newWizards">
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/distribution/model/BaseDistributionData.java (+142 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 ******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.distribution.model;
13
14
15
/**
16
 * <b><u>BaseDistributionData</u></b>
17
 * <p>
18
 */
19
public class BaseDistributionData {
20
21
    // ------------------------------------------------------------------------
22
    // Attributes
23
    // ------------------------------------------------------------------------
24
    public final static int OUT_OF_RANGE_BUCKET = -1;
25
26
    /**
27
     *  Number of buckets
28
     */
29
    protected final int fNbBuckets;
30
    
31
    /**
32
     * Duration of each bucket
33
     */
34
    protected long fBucketDuration;
35
    
36
    /**
37
     * Bucket index of last event time
38
     */
39
    protected int fLastBucket;
40
41
    /**
42
     * Timestamp of the first bucket. (could be negative when analyzing events with descending time!!!)
43
     */
44
    protected long fFirstBucketTime;
45
    
46
    /**
47
     * Timestamp of the first event
48
     */
49
    protected long fFirstEventTime;
50
    
51
    /**
52
     *  Timestamp of the last event
53
     */
54
    protected long fLastEventTime;
55
56
    // ------------------------------------------------------------------------
57
    // Constructors
58
    // ------------------------------------------------------------------------
59
    public BaseDistributionData(int nbBuckets) {
60
        fNbBuckets = nbBuckets;
61
        clear();
62
    }
63
    
64
    // ------------------------------------------------------------------------
65
    // Accessors
66
    // ------------------------------------------------------------------------
67
    
68
    public int getNbBuckets() {
69
        return fNbBuckets;
70
    }
71
72
    public long getBucketDuration() {
73
        return fBucketDuration;
74
    }
75
76
    public void setBucketDuration(long bucketDuration) {
77
        fBucketDuration = bucketDuration;
78
    }
79
80
    public int getLastBucket() {
81
        return fLastBucket;
82
    }
83
84
    public void setLastBucket(int lastBucket) {
85
        fLastBucket = lastBucket;
86
    }
87
88
    public long getFirstBucketTime() {
89
        return fFirstBucketTime;
90
    }
91
92
    public void setFirstBucketTime(long firstBucketTime) {
93
        fFirstBucketTime = firstBucketTime;
94
    }
95
96
    public long getLastBucketTime() {
97
        return getBucketStartTime(fLastBucket);
98
    }
99
100
    public long getFirstEventTime() {
101
        return fFirstEventTime;
102
    }
103
104
    public void setFirstEventTime(long firstEventTime) {
105
        fFirstEventTime = firstEventTime;
106
    }
107
108
    public long getLastEventTime() {
109
        return fLastEventTime;
110
    }
111
    
112
    public void setLastEventTime(long lastEventTime) {
113
        fLastEventTime = lastEventTime;
114
    }
115
    
116
    public long getBucketStartTime(int index) {
117
        return fFirstBucketTime + index * fBucketDuration;
118
    }
119
    
120
    public long getBucketEndTime(int index) {
121
        return getBucketStartTime(index) + fBucketDuration;
122
    }
123
    
124
    public int getIndex(long time) {
125
        return (int)((time - fFirstBucketTime) / fBucketDuration); 
126
    }
127
    
128
    public boolean isIndexValid(int index) {
129
        return ((index >= 0) && (index <= fNbBuckets - 1));
130
    }
131
    
132
    // ------------------------------------------------------------------------
133
    // Operations
134
    // ------------------------------------------------------------------------
135
    public void clear() {
136
        fFirstBucketTime = 0;
137
        fFirstEventTime = 0;
138
        fLastEventTime = 0;
139
        fLastBucket = 0;
140
        fBucketDuration = 1; // 1ns
141
    }
142
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/distribution/model/DistributionData.java (+179 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 ******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.distribution.model;
13
14
import org.eclipse.linuxtools.lttng.ui.views.latency.model.Config;
15
16
/**
17
 * <b><u>DistributionData</u></b>
18
 * <p>
19
 * The algorithm is based on the algorithm for the Histogram. The difference is that
20
 * it supports two dimensions. For more details about the model principle 
21
 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramDataModel 
22
 * <p>
23
 */
24
abstract public class DistributionData extends BaseDistributionData {
25
26
    // ------------------------------------------------------------------------
27
    // Attributes
28
    // ------------------------------------------------------------------------
29
30
    /**
31
     * Flag to indicate if given timestamp is the first one to count 
32
     */
33
    protected boolean fIsFirst;
34
    
35
    /**
36
     *  reference to fBuckets
37
     */
38
    protected final int [][] fBuckets;
39
    
40
    /**
41
     * Time limit (current available longest time)
42
     */
43
    protected long fTimeLimit;
44
45
    // ------------------------------------------------------------------------
46
    // Constructors
47
    // ------------------------------------------------------------------------
48
    public DistributionData(int[][] buckets) {
49
        this(Config.DEFAULT_NUMBER_OF_BUCKETS, buckets);
50
    }
51
52
    public DistributionData(int nbBuckets, int[][] buckets) {
53
        super(nbBuckets);
54
        fBuckets = buckets;
55
        clear();
56
    }
57
58
    // ------------------------------------------------------------------------
59
    // Accessors
60
    // ------------------------------------------------------------------------
61
   
62
    public long getTimeLimit() {
63
        return fTimeLimit;
64
    }
65
    
66
    // ------------------------------------------------------------------------
67
    // Operations
68
    // ------------------------------------------------------------------------
69
70
    /*
71
     * (non-Javadoc)
72
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.BaseDistributionData#clear()
73
     */
74
    @Override
75
    public void clear() {
76
        super.clear();
77
        fIsFirst = true;
78
        updateEndTime();
79
    }
80
81
    public boolean isFirst() {
82
        return fIsFirst;
83
    }
84
85
    public int countEvent(long timestamp) {
86
87
        // Set the start/end time if not already done
88
        if (fIsFirst) {
89
            fIsFirst = false;
90
            fFirstBucketTime = timestamp;
91
            fFirstEventTime = timestamp;
92
93
            updateEndTime();
94
        }
95
96
        // save first event time if necessary 
97
        if (timestamp < fFirstEventTime) {
98
            fFirstEventTime = timestamp;
99
        }
100
101
        // save last event time if necessary
102
        if (fLastEventTime < timestamp) {
103
            fLastEventTime = timestamp;
104
        }
105
106
        
107
        if (timestamp >= fFirstBucketTime) {
108
            // Compact as needed
109
            while (timestamp >= fTimeLimit) {
110
                mergeBuckets();
111
            }
112
113
        } else {
114
115
            // Get offset for buckets adjustment
116
            int offset = getOffset(timestamp);
117
118
            // Compact as needed
119
            while (fLastBucket + offset >= fNbBuckets) {
120
                mergeBuckets();
121
                offset = getOffset(timestamp);
122
            }
123
124
            // Move buckets with offset (to right)
125
            moveBuckets(offset);
126
127
            // Adjust start/end time and index 
128
            fLastBucket = fLastBucket + offset;
129
            fFirstBucketTime = fFirstBucketTime - offset * fBucketDuration;
130
            updateEndTime();
131
        }
132
133
        // Increment the right bucket
134
        int index = (int) ((timestamp - fFirstBucketTime) / fBucketDuration);
135
136
        if (fLastBucket < index) {
137
            fLastBucket = index;
138
        }
139
140
        return index;
141
    }
142
143
    // ------------------------------------------------------------------------
144
    // Abstract 
145
    // ------------------------------------------------------------------------
146
    
147
    /**
148
     * Moves content of buckets with the given offset in positive direction. 
149
     * It has to be implemented accordingly in the relevant sub-classes for 
150
     * horizontal and vertical direction.  
151
     * 
152
     * @param buckets - 2-dimensional array of buckets 
153
     * @param offset - offset to move
154
     */
155
    abstract protected void moveBuckets(int offset);
156
    
157
    /**
158
     * Merges buckets if end time is exceeded. It has to be implemented 
159
     * accordingly in the relevant sub-classes for horizontal and 
160
     * vertical direction.
161
     * @param buckets
162
     */
163
    abstract protected void mergeBuckets();
164
165
    // ------------------------------------------------------------------------
166
    // Helper Functions
167
    // ------------------------------------------------------------------------
168
    protected int getOffset(long timestamp) {
169
        int offset = (int) ((fFirstBucketTime - timestamp) / fBucketDuration);
170
        if ((fFirstBucketTime - timestamp) % fBucketDuration != 0) {
171
            offset++;
172
        }
173
        return offset;
174
    }
175
    
176
    protected void updateEndTime() {
177
        fTimeLimit = fFirstBucketTime + fNbBuckets * fBucketDuration;
178
    }
179
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/distribution/model/HorDistributionData.java (+70 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 ******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.distribution.model;
13
14
/**
15
 * <b><u>HorDistributionData</u></b>
16
 * <p>
17
 * Implementation of DistributionData for horizontal direction.
18
 */
19
public class HorDistributionData extends DistributionData {
20
21
    // ------------------------------------------------------------------------
22
    // Constructor
23
    // ------------------------------------------------------------------------
24
25
    public HorDistributionData(int nbBuckets, int[][] buckets) {
26
        super(nbBuckets, buckets);
27
    }
28
29
    // ------------------------------------------------------------------------
30
    // Abstract function implementation
31
    // ------------------------------------------------------------------------
32
    /*
33
     * (non-Javadoc)
34
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.DistributionData#moveBuckets(int)
35
     */
36
    @Override
37
    protected void moveBuckets(int offset) {
38
        for (int j = 0; j < fNbBuckets; j++) {
39
40
            for(int i = fNbBuckets - 1; i >= offset; i--) {
41
                fBuckets[i][j] = fBuckets[i-offset][j]; 
42
            }
43
44
            for (int i = 0; i < offset; i++) {
45
                fBuckets[i][j] = 0;
46
            }
47
        }
48
    }
49
50
    /*
51
     * (non-Javadoc)
52
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.DistributionData#mergeBuckets()
53
     */
54
    @Override
55
    protected void mergeBuckets() {
56
57
        for (int y = 0; y < fNbBuckets; y++) {
58
            for (int i = 0; i < fNbBuckets / 2; i++) {
59
                fBuckets[i][y] = fBuckets[2 * i][y] + fBuckets[2 * i + 1][y];
60
            }
61
62
            for (int i = fNbBuckets / 2; i < fNbBuckets; i++) {
63
                fBuckets[i][y] = 0;
64
            }
65
        }
66
        fBucketDuration = fBucketDuration * 2;
67
        updateEndTime();
68
        fLastBucket = fNbBuckets / 2 - 1;
69
    }
70
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/distribution/model/IBaseDistributionModel.java (+25 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
13
package org.eclipse.linuxtools.lttng.ui.views.distribution.model;
14
15
public interface IBaseDistributionModel {
16
    /**
17
     * Interface to complete the model
18
     */
19
    public void complete();
20
    
21
    /**
22
     * Interface to clear the model
23
     */
24
    public void clear();
25
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/distribution/model/VerDistributionData.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 ******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.distribution.model;
13
14
/**
15
 * <b><u>VerDistributionData</u></b>
16
 * 
17
 * Implementation of DistributionData for vertical direction. 
18
 * <p>
19
 */
20
public class VerDistributionData extends DistributionData {
21
    
22
    // ------------------------------------------------------------------------
23
    // Constructor
24
    // ------------------------------------------------------------------------
25
    public VerDistributionData(int nbBuckets, int[][] buckets) {
26
        super(nbBuckets, buckets);
27
    }
28
29
    // ------------------------------------------------------------------------
30
    // Abstract function implementation
31
    // ------------------------------------------------------------------------
32
33
    /*
34
     * (non-Javadoc)
35
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.DistributionData#moveBuckets(int)
36
     */
37
    @Override
38
    protected void moveBuckets(int offset) {
39
        for (int j = 0; j < fNbBuckets; j++) {
40
41
            for(int i = fNbBuckets - 1; i >= offset; i--) {
42
                fBuckets[j][i] = fBuckets[j][i-offset]; 
43
            }
44
45
            for (int i = 0; i < offset; i++) {
46
                fBuckets[j][i] = 0;
47
            }
48
        }
49
    }
50
51
    /*
52
     * (non-Javadoc)
53
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.DistributionData#mergeBuckets()
54
     */
55
    @Override
56
    protected void mergeBuckets() {
57
        for (int x = 0; x < fNbBuckets; x++) {
58
            for (int i = 0; i < fNbBuckets / 2; i++) {
59
                fBuckets[x][i] = fBuckets[x][2 * i] + fBuckets[x][2 * i + 1];
60
            }
61
            for (int i = fNbBuckets / 2; i < fNbBuckets; i++) {
62
                fBuckets[x][i] = 0;
63
            }
64
        }
65
        fBucketDuration = fBucketDuration * 2;
66
        updateEndTime();
67
        fLastBucket = fNbBuckets / 2 - 1;
68
    }
69
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/FullTraceHistogram.java (-3 / +4 lines)
Lines 8-13 Link Here
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *   Francois Chouinard - Initial API and implementation
10
 *   Francois Chouinard - Initial API and implementation
11
 *   Bernd Hufmann - Changed to updated histogram data model
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.linuxtools.lttng.ui.views.histogram;
14
package org.eclipse.linuxtools.lttng.ui.views.histogram;
Lines 75-81 public class FullTraceHistogram extends Histogram implements MouseMoveListener { Link Here
75
        fRangeStartTime = startTime;
76
        fRangeStartTime = startTime;
76
        fRangeDuration = duration;
77
        fRangeDuration = duration;
77
        fZoom.setNewRange(fRangeStartTime, fRangeDuration);
78
        fZoom.setNewRange(fRangeStartTime, fRangeDuration);
78
        refresh();
79
        fDataModel.complete();
79
    }
80
    }
80
81
81
    @Override
82
    @Override
Lines 131-137 public class FullTraceHistogram extends Histogram implements MouseMoveListener { Link Here
131
                newStart = newEnd - fZoom.getDuration();
132
                newStart = newEnd - fZoom.getDuration();
132
            }
133
            }
133
            fRangeStartTime = newStart;
134
            fRangeStartTime = newStart;
134
            refresh();
135
            fDataModel.complete();
135
        }
136
        }
136
    }
137
    }
137
138
Lines 166-172 public class FullTraceHistogram extends Histogram implements MouseMoveListener { Link Here
166
        long bucketSpan = fScaledData.fBucketDuration;
167
        long bucketSpan = fScaledData.fBucketDuration;
167
        int rangeWidth = (int) (fRangeDuration / bucketSpan);
168
        int rangeWidth = (int) (fRangeDuration / bucketSpan);
168
169
169
        int left = (int) ((fRangeStartTime - fDataModel.getStartTime()) / bucketSpan);
170
        int left = (int) ((fRangeStartTime - fDataModel.getFirstBucketTime()) / bucketSpan);
170
        int right = left + rangeWidth;
171
        int right = left + rangeWidth;
171
        int center = (left + right) / 2;
172
        int center = (left + right) / 2;
172
        int height = fCanvas.getSize().y - 2;
173
        int height = fCanvas.getSize().y - 2;
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/Histogram.java (-25 / +29 lines)
Lines 8-13 Link Here
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *   Francois Chouinard - Initial API and implementation
10
 *   Francois Chouinard - Initial API and implementation
11
 *   Bernd Hufmann - Changed to updated histogram data model
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.linuxtools.lttng.ui.views.histogram;
14
package org.eclipse.linuxtools.lttng.ui.views.histogram;
Lines 69-83 import org.eclipse.swt.widgets.Text; Link Here
69
 * <li>number of events in that time range
70
 * <li>number of events in that time range
70
 * </ul>
71
 * </ul>
71
 */
72
 */
72
public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseTrackListener {
73
public abstract class Histogram implements ControlListener, PaintListener, KeyListener, MouseListener, MouseTrackListener, IHistogramModelListener {
73
74
74
    // ------------------------------------------------------------------------
75
    // ------------------------------------------------------------------------
75
    // Constants
76
    // Constants
76
    // ------------------------------------------------------------------------
77
    // ------------------------------------------------------------------------
77
78
78
    // Histogram refresh frequency
79
    private final static int REFRESH_FREQUENCY = HistogramDataModel.DEFAULT_NUMBER_OF_BUCKETS;
80
81
    // Histogram colors
79
    // Histogram colors
82
    private final Color fBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
80
    private final Color fBackgroundColor = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
83
    private final Color fCurrentEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
81
    private final Color fCurrentEventColor = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
Lines 86-91 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
86
84
87
    // Timestamp scale (nanosecond)
85
    // Timestamp scale (nanosecond)
88
    public static final byte TIME_SCALE = -9;
86
    public static final byte TIME_SCALE = -9;
87
    
88
    public static final int HISTOGRAM_BAR_WIDTH = 1;
89
89
90
    // ------------------------------------------------------------------------
90
    // ------------------------------------------------------------------------
91
    // Attributes
91
    // Attributes
Lines 118-123 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
118
118
119
        createWidget(parent);
119
        createWidget(parent);
120
        fDataModel = new HistogramDataModel();
120
        fDataModel = new HistogramDataModel();
121
        fDataModel.addHistogramListener(this);
121
        clear();
122
        clear();
122
123
123
        fCanvas.addControlListener(this);
124
        fCanvas.addControlListener(this);
Lines 129-134 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
129
130
130
    public void dispose() {
131
    public void dispose() {
131
        fHistoBarColor.dispose();
132
        fHistoBarColor.dispose();
133
        fDataModel.removeHistogramListener(this);
132
    }
134
    }
133
135
134
    private void createWidget(Composite parent) {
136
    private void createWidget(Composite parent) {
Lines 238-244 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
238
    // ------------------------------------------------------------------------
240
    // ------------------------------------------------------------------------
239
241
240
    public long getStartTime() {
242
    public long getStartTime() {
241
        return fDataModel.getStartTime();
243
        return fDataModel.getFirstBucketTime();
242
    }
244
    }
243
245
244
    public long getEndTime() {
246
    public long getEndTime() {
Lines 248-253 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
248
    public long getTimeLimit() {
250
    public long getTimeLimit() {
249
        return fDataModel.getTimeLimit();
251
        return fDataModel.getTimeLimit();
250
    }
252
    }
253
    
254
    public HistogramDataModel getDataModel() {
255
        return fDataModel;
256
    }
251
257
252
    // ------------------------------------------------------------------------
258
    // ------------------------------------------------------------------------
253
    // Operations
259
    // Operations
Lines 261-267 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
261
    public void clear() {
267
    public void clear() {
262
        fDataModel.clear();
268
        fDataModel.clear();
263
        fScaledData = null;
269
        fScaledData = null;
264
        refresh();
265
    }
270
    }
266
271
267
    /**
272
    /**
Lines 269-280 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
269
     * 
274
     * 
270
     * @param timestamp
275
     * @param timestamp
271
     */
276
     */
272
    public void countEvent(long timestamp) {
277
    public void countEvent(long eventCount, long timestamp) {
273
        fDataModel.countEvent(timestamp);
278
        fDataModel.countEvent(eventCount, timestamp);
274
        if (fDataModel.getNbEvents() % REFRESH_FREQUENCY == 0) {
275
            refresh();
276
            refresh(); // This is intentional. Exercise left to the reader :-)
277
        }
278
    }
279
    }
279
280
280
    /**
281
    /**
Lines 284-291 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
284
     */
285
     */
285
    public void setCurrentEvent(long timestamp) {
286
    public void setCurrentEvent(long timestamp) {
286
        fCurrentEventTime = (timestamp > 0) ? timestamp : 0;
287
        fCurrentEventTime = (timestamp > 0) ? timestamp : 0;
287
        fDataModel.setCurrentEvent(timestamp);
288
        fDataModel.setCurrentEventNotifyListeners(timestamp);
288
        refresh();
289
    }
289
    }
290
290
291
    /**
291
    /**
Lines 297-303 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
297
    public synchronized long getTimestamp(int offset) {
297
    public synchronized long getTimestamp(int offset) {
298
        assert offset > 0 && offset < fScaledData.fWidth;
298
        assert offset > 0 && offset < fScaledData.fWidth;
299
        try {
299
        try {
300
            return fDataModel.getStartTime() + fScaledData.fBucketDuration * offset;
300
            return fDataModel.getFirstBucketTime() + fScaledData.fBucketDuration * offset;
301
        } catch (Exception e) {
301
        } catch (Exception e) {
302
            return 0; // TODO: Fix that racing condition (NPE)
302
            return 0; // TODO: Fix that racing condition (NPE)
303
        }
303
        }
Lines 310-318 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
310
     * @return the offset of the corresponding bucket (-1 if invalid)
310
     * @return the offset of the corresponding bucket (-1 if invalid)
311
     */
311
     */
312
    public synchronized int getOffset(long timestamp) {
312
    public synchronized int getOffset(long timestamp) {
313
        if (timestamp < fDataModel.getStartTime() || timestamp > fDataModel.getEndTime())
313
        if (timestamp < fDataModel.getFirstBucketTime() || timestamp > fDataModel.getEndTime())
314
            return -1;
314
            return -1;
315
        return (int) ((timestamp - fDataModel.getStartTime()) / fScaledData.fBucketDuration);
315
        return (int) ((timestamp - fDataModel.getFirstBucketTime()) / fScaledData.fBucketDuration);
316
    }
316
    }
317
317
318
    /**
318
    /**
Lines 370-376 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
370
    /**
370
    /**
371
     * Refresh the histogram display
371
     * Refresh the histogram display
372
     */
372
     */
373
    protected void refresh() {
373
    @Override
374
    public void modelUpdated() {
374
        if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) {
375
        if (!fCanvas.isDisposed() && fCanvas.getDisplay() != null) {
375
            fCanvas.getDisplay().asyncExec(new Runnable() {
376
            fCanvas.getDisplay().asyncExec(new Runnable() {
376
                @Override
377
                @Override
Lines 382-391 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
382
                        if (canvasWidth <= 0 || canvasHeight <= 0)
383
                        if (canvasWidth <= 0 || canvasHeight <= 0)
383
                            return;
384
                            return;
384
                        fDataModel.setCurrentEvent(fCurrentEventTime);
385
                        fDataModel.setCurrentEvent(fCurrentEventTime);
385
                        fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight);
386
                        fScaledData = fDataModel.scaleTo(canvasWidth, canvasHeight, HISTOGRAM_BAR_WIDTH);
386
                        fCanvas.redraw();
387
                        fCanvas.redraw();
387
                        // Display histogram and update X-,Y-axis labels
388
                        // Display histogram and update X-,Y-axis labels
388
                        fTimeRangeStartText.setText(HistogramUtils.nanosecondsToString(fDataModel.getStartTime()));
389
                        fTimeRangeStartText.setText(HistogramUtils.nanosecondsToString(fDataModel.getFirstBucketTime()));
389
                        fTimeRangeEndText.setText(HistogramUtils.nanosecondsToString(fDataModel.getEndTime()));
390
                        fTimeRangeEndText.setText(HistogramUtils.nanosecondsToString(fDataModel.getEndTime()));
390
                        fMaxNbEventsText.setText(Long.toString(fScaledData.fMaxValue));
391
                        fMaxNbEventsText.setText(Long.toString(fScaledData.fMaxValue));
391
                        // The Y-axis area might need to be re-sized
392
                        // The Y-axis area might need to be re-sized
Lines 540-547 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
540
    }
541
    }
541
542
542
    private String formatToolTipLabel(int index) {
543
    private String formatToolTipLabel(int index) {
543
        long startTime = fDataModel.getStartTime() + fScaledData.fCurrentBucket * fScaledData.fBucketDuration;
544
        long startTime = fScaledData.getBucketStartTime(fScaledData.fCurrentBucket);
544
        long endTime = startTime + fScaledData.fBucketDuration;
545
        // negative values are possible if time values came into the model in decreasing order 
546
        if (startTime < 0) {
547
            startTime = 0;
548
        }
549
        long endTime = fScaledData.getBucketEndTime(fScaledData.fCurrentBucket);
545
        int nbEvents = (index >= 0) ? fScaledData.fData[index] : 0;
550
        int nbEvents = (index >= 0) ? fScaledData.fData[index] : 0;
546
551
547
        StringBuffer buffer = new StringBuffer();
552
        StringBuffer buffer = new StringBuffer();
Lines 561-572 public abstract class Histogram implements ControlListener, PaintListener, KeyLi Link Here
561
566
562
    @Override
567
    @Override
563
    public void controlMoved(ControlEvent event) {
568
    public void controlMoved(ControlEvent event) {
564
        refresh();
569
        fDataModel.complete();
565
    }
570
    }
566
571
567
    @Override
572
    @Override
568
    public void controlResized(ControlEvent event) {
573
    public void controlResized(ControlEvent event) {
569
        refresh();
574
        fDataModel.complete();
570
    }
575
    }
571
572
}
576
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramDataModel.java (-31 / +153 lines)
Lines 8-19 Link Here
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *   Francois Chouinard - Initial API and implementation
10
 *   Francois Chouinard - Initial API and implementation
11
 *   Bernd Hufmann - Implementation of new interfaces /listeners and support for 
12
 *                   time stamp in any order
11
 *******************************************************************************/
13
 *******************************************************************************/
12
14
13
package org.eclipse.linuxtools.lttng.ui.views.histogram;
15
package org.eclipse.linuxtools.lttng.ui.views.histogram;
14
16
15
import java.util.Arrays;
17
import java.util.Arrays;
16
18
19
import org.eclipse.core.runtime.ListenerList;
17
import org.eclipse.linuxtools.lttng.core.exceptions.EventOutOfSequenceException;
20
import org.eclipse.linuxtools.lttng.core.exceptions.EventOutOfSequenceException;
18
import org.eclipse.linuxtools.lttng.ui.LTTngUILogger;
21
import org.eclipse.linuxtools.lttng.ui.LTTngUILogger;
19
22
Lines 41-46 import org.eclipse.linuxtools.lttng.ui.LTTngUILogger; Link Here
41
 * <i>timespan</i> (<i>timespan'</i> = <i>n</i> * <i>d'</i>, where <i>d'</i> =
44
 * <i>timespan</i> (<i>timespan'</i> = <i>n</i> * <i>d'</i>, where <i>d'</i> =
42
 * 2<i>d</i>). This compaction happens as needed as the trace is read.
45
 * 2<i>d</i>). This compaction happens as needed as the trace is read.
43
 * <p>
46
 * <p>
47
 * The model allows for timestamps in not increasing order. The timestamps can
48
 * be fed to the model in any order. If an event has a timestamp less than the 
49
 * <i>basetime</i>, the buckets will be moved to the right to account for the
50
 * new smaller timestamp. The new <i>basetime</i> is a multiple of the bucket 
51
 * duration smaller then the previous <i>basetime</i>. Note that the <i>basetime</i>
52
 * might not be anymore a timestamp of an event. If necessary, the buckets will
53
 * be compacted before moving to the right. This might be necessary to not 
54
 * loose any event counts at the end of the buckets array.
55
 * <p>
44
 * The mapping from the model to the UI is performed by the <i>scaleTo()</i>
56
 * The mapping from the model to the UI is performed by the <i>scaleTo()</i>
45
 * method. By keeping the number of buckets <i>n</i> relatively large with
57
 * method. By keeping the number of buckets <i>n</i> relatively large with
46
 * respect to to the number of pixels in the actual histogram, we should achieve
58
 * respect to to the number of pixels in the actual histogram, we should achieve
Lines 51-57 import org.eclipse.linuxtools.lttng.ui.LTTngUILogger; Link Here
51
 * <p>
63
 * <p>
52
 * TODO: Cut-off eccentric values? TODO: Support for going back in time?
64
 * TODO: Cut-off eccentric values? TODO: Support for going back in time?
53
 */
65
 */
54
public class HistogramDataModel {
66
public class HistogramDataModel implements IHistogramDataModel {
55
67
56
    // ------------------------------------------------------------------------
68
    // ------------------------------------------------------------------------
57
    // Constants
69
    // Constants
Lines 60-65 public class HistogramDataModel { Link Here
60
    // The default number of buckets
72
    // The default number of buckets
61
    public static final int DEFAULT_NUMBER_OF_BUCKETS = 16 * 1000;
73
    public static final int DEFAULT_NUMBER_OF_BUCKETS = 16 * 1000;
62
74
75
    public static final int REFRESH_FREQUENCY = DEFAULT_NUMBER_OF_BUCKETS;
76
    
63
//    // The ratio where an eccentric value will be truncated
77
//    // The ratio where an eccentric value will be truncated
64
//    private static final int MAX_TO_AVERAGE_CUTOFF_RATIO = 5;
78
//    private static final int MAX_TO_AVERAGE_CUTOFF_RATIO = 5;
65
79
Lines 75-89 public class HistogramDataModel { Link Here
75
    private int fLastBucket;
89
    private int fLastBucket;
76
90
77
    // Timestamps
91
    // Timestamps
92
    private long fFirstBucketTime; // could be negative when analyzing events with descending order!!!
78
    private long fFirstEventTime;
93
    private long fFirstEventTime;
79
    private long fLastEventTime;
94
    private long fLastEventTime;
80
    private long fCurrentEventTime;
95
    private long fCurrentEventTime;
81
    private long fTimeLimit;
96
    private long fTimeLimit;
82
97
    
83
    // ------------------------------------------------------------------------
98
    // private listener lists
84
    // Constructors
99
    private final ListenerList fModelListeners;
85
    // ------------------------------------------------------------------------
100
    
86
87
    public HistogramDataModel() {
101
    public HistogramDataModel() {
88
        this(DEFAULT_NUMBER_OF_BUCKETS);
102
        this(DEFAULT_NUMBER_OF_BUCKETS);
89
    }
103
    }
Lines 91-96 public class HistogramDataModel { Link Here
91
    public HistogramDataModel(int nbBuckets) {
105
    public HistogramDataModel(int nbBuckets) {
92
        fNbBuckets = nbBuckets;
106
        fNbBuckets = nbBuckets;
93
        fBuckets = new long[nbBuckets];
107
        fBuckets = new long[nbBuckets];
108
        fModelListeners = new ListenerList();
94
        clear();
109
        clear();
95
    }
110
    }
96
111
Lines 100-109 public class HistogramDataModel { Link Here
100
        fBucketDuration = other.fBucketDuration;
115
        fBucketDuration = other.fBucketDuration;
101
        fNbEvents = other.fNbEvents;
116
        fNbEvents = other.fNbEvents;
102
        fLastBucket = other.fLastBucket;
117
        fLastBucket = other.fLastBucket;
118
        fFirstBucketTime = other.fFirstBucketTime;
103
        fFirstEventTime = other.fFirstEventTime;
119
        fFirstEventTime = other.fFirstEventTime;
104
        fLastEventTime = other.fLastEventTime;
120
        fLastEventTime = other.fLastEventTime;
105
        fCurrentEventTime = other.fCurrentEventTime;
121
        fCurrentEventTime = other.fCurrentEventTime;
106
        fTimeLimit = other.fTimeLimit;
122
        fTimeLimit = other.fTimeLimit;
123
        fModelListeners = new ListenerList();
124
        Object[] listeners = other.fModelListeners.getListeners();
125
        for (Object listener : listeners) {
126
            fModelListeners.add(listener);
127
        }
107
    }
128
    }
108
129
109
    // ------------------------------------------------------------------------
130
    // ------------------------------------------------------------------------
Lines 121-131 public class HistogramDataModel { Link Here
121
    public long getBucketDuration() {
142
    public long getBucketDuration() {
122
        return fBucketDuration;
143
        return fBucketDuration;
123
    }
144
    }
145
    
146
    public long getFirstBucketTime() {
147
        return fFirstBucketTime;
148
    }
124
149
125
    public long getStartTime() {
150
    public long getStartTime() {
126
        return fFirstEventTime;
151
        return fFirstEventTime;
127
    }
152
    }
128
153
    
129
    public long getEndTime() {
154
    public long getEndTime() {
130
        return fLastEventTime;
155
        return fLastEventTime;
131
    }
156
    }
Lines 137-159 public class HistogramDataModel { Link Here
137
    public long getTimeLimit() {
162
    public long getTimeLimit() {
138
        return fTimeLimit;
163
        return fTimeLimit;
139
    }
164
    }
165
    
166
    // ------------------------------------------------------------------------
167
    // Listener handling
168
    // ------------------------------------------------------------------------
169
    
170
    public void addHistogramListener(IHistogramModelListener listener) {
171
        fModelListeners.add(listener);        
172
    }
173
    
174
    public void removeHistogramListener(IHistogramModelListener listener) {
175
        fModelListeners.remove(listener);
176
    }
140
177
178
    private void fireModelUpdateNotification() {
179
        fireModelUpdateNotification(0);
180
    }
181
    
182
    private void fireModelUpdateNotification(long count) {
183
        if (count % REFRESH_FREQUENCY == 0) {
184
            Object[] listeners = fModelListeners.getListeners();
185
            for (int i = 0; i < listeners.length; i++) {
186
                IHistogramModelListener listener = (IHistogramModelListener) listeners[i];
187
                listener.modelUpdated();
188
            }
189
        }
190
    }
191
    
141
    // ------------------------------------------------------------------------
192
    // ------------------------------------------------------------------------
142
    // Operations
193
    // Operations
143
    // ------------------------------------------------------------------------
194
    // ------------------------------------------------------------------------
195
    @Override
196
    public void complete() {
197
        fireModelUpdateNotification();
198
    }
144
199
145
    /**
200
    /**
146
     * Clear the histogram model.
201
     * Clear the histogram model.
147
     */
202
     */
203
    @Override
148
    public void clear() {
204
    public void clear() {
149
        Arrays.fill(fBuckets, 0);
205
        Arrays.fill(fBuckets, 0);
150
        fNbEvents = 0;
206
        fNbEvents = 0;
151
        fFirstEventTime = 0;
207
        fFirstBucketTime = 0;
152
        fLastEventTime = 0;
208
        fLastEventTime = 0;
153
        fCurrentEventTime = 0;
209
        fCurrentEventTime = 0;
154
        fLastBucket = 0;
210
        fLastBucket = 0;
155
        fBucketDuration = 1; // 1ns
211
        fBucketDuration = 1; // 1ns
156
        updateEndTime();
212
        updateEndTime();
213
        fireModelUpdateNotification();
157
    }
214
    }
158
215
159
    /**
216
    /**
Lines 166-227 public class HistogramDataModel { Link Here
166
    }
223
    }
167
224
168
    /**
225
    /**
226
     * Sets the current event time
227
     * 
228
     * @param timestamp
229
     */
230
    public void setCurrentEventNotifyListeners(long timestamp) {
231
        fCurrentEventTime = timestamp;
232
        fireModelUpdateNotification();
233
    }
234
    
235
    /**
169
     * Add event to the correct bucket, compacting the if needed.
236
     * Add event to the correct bucket, compacting the if needed.
170
     * 
237
     * 
171
     * @param timestamp the timestamp of the event to count
238
     * @param timestamp the timestamp of the event to count
172
     */
239
     */
173
    public void countEvent(long timestamp) {
240
    @Override
241
    public void countEvent(long eventCount, long timestamp) {
242
        
243
        // Validate
244
        if (timestamp < 0) {
245
            String message = "Negative time value"; //$NON-NLS-1$
246
            EventOutOfSequenceException exception = new EventOutOfSequenceException(message);
247
            LTTngUILogger.logError(message, exception);
248
            return;
249
        }
250
        
174
        // Set the start/end time if not already done
251
        // Set the start/end time if not already done
175
        if (fLastBucket == 0 && fBuckets[0] == 0 && timestamp > 0) {
252
        if (fLastBucket == 0 && fBuckets[0] == 0 && timestamp > 0) {
253
            fFirstBucketTime = timestamp;
176
            fFirstEventTime = timestamp;
254
            fFirstEventTime = timestamp;
177
            updateEndTime();
255
            updateEndTime();
178
        }
256
        }
257
        
258
        if (timestamp < fFirstEventTime) {
259
            fFirstEventTime = timestamp;
260
        }
261
        
179
        if (fLastEventTime < timestamp) {
262
        if (fLastEventTime < timestamp) {
180
            fLastEventTime = timestamp;
263
            fLastEventTime = timestamp;
181
        }
264
        }
265
        
266
        if (timestamp >= fFirstBucketTime) {
182
267
183
        // Compact as needed
268
            // Compact as needed
184
        while (timestamp >= fTimeLimit) {
269
            while (timestamp >= fTimeLimit) {
185
            mergeBuckets();
270
                mergeBuckets();
186
        }
271
            }
187
272
188
        // Validate
273
        } else {
189
        if (timestamp < fFirstEventTime) {
274
            
190
            String message = "Out of order timestamp. Going back in time?"; //$NON-NLS-1$
275
            // get offset for adjustment
191
            EventOutOfSequenceException exception = new EventOutOfSequenceException(message);
276
            int offset = getOffset(timestamp);
192
            LTTngUILogger.logError(message, exception);
277
193
            return;
278
            // Compact as needed
194
        }
279
            while(fLastBucket + offset >= fNbBuckets) {
280
                mergeBuckets();
281
                offset = getOffset(timestamp);
282
            }
283
            
284
            moveBuckets(offset);
285
286
            fLastBucket = fLastBucket + offset;
195
287
288
            fFirstBucketTime = fFirstBucketTime - offset*fBucketDuration;
289
            updateEndTime();
290
        }
291
        
196
        // Increment the right bucket
292
        // Increment the right bucket
197
        int index = (int) ((timestamp - fFirstEventTime) / fBucketDuration);
293
        int index = (int) ((timestamp - fFirstBucketTime) / fBucketDuration);
198
        fBuckets[index]++;
294
        fBuckets[index]++;
199
        fNbEvents++;
295
        fNbEvents++;
200
        if (fLastBucket < index)
296
        if (fLastBucket < index)
201
            fLastBucket = index;
297
            fLastBucket = index;
298
        
299
        fireModelUpdateNotification(eventCount);
202
    }
300
    }
203
301
204
    /**
302
    /**
205
     * Scale the model data to the width and height requested.
303
     * Scale the model data to the width, height and bar width requested.
206
     * 
304
     * 
207
     * @param width
305
     * @param width
208
     * @param height
306
     * @param height
307
     * @param bar width
209
     * @return the result array of size [width] and where the highest value
308
     * @return the result array of size [width] and where the highest value
210
     *         doesn't exceed [height]
309
     *         doesn't exceed [height]
211
     */
310
     */
212
    public HistogramScaledData scaleTo(int width, int height) {
311
    @Override
312
    public HistogramScaledData scaleTo(int width, int height, int barWidth) {
213
        // Basic validation
313
        // Basic validation
214
        if (width <= 0 ||  height <= 0)
314
        if (width <= 0 ||  height <= 0 || barWidth <= 0)
215
            throw new AssertionError("Invalid histogram dimensions (" + width + "x" + height + ")");
315
            throw new AssertionError("Invalid histogram dimensions (" + width + "x" + height + ", barWidth=" + barWidth + ")"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
216
316
217
        // The result structure
317
        // The result structure
218
        HistogramScaledData result = new HistogramScaledData(width, height);
318
        HistogramScaledData result = new HistogramScaledData(width, height, barWidth);
219
319
220
        // Scale horizontally
320
        // Scale horizontally
221
        result.fMaxValue = 0;
321
        result.fMaxValue = 0;
222
        int bucketsPerBar = fLastBucket / width + 1;
322
        
323
        int nbBars = width / barWidth;
324
        int bucketsPerBar = fLastBucket / nbBars + 1;
223
        result.fBucketDuration = bucketsPerBar * fBucketDuration;
325
        result.fBucketDuration = bucketsPerBar * fBucketDuration;
224
        for (int i = 0; i < width; i++) {
326
        for (int i = 0; i < nbBars; i++) {
225
            int count = 0;
327
            int count = 0;
226
            for (int j = i * bucketsPerBar; j < (i + 1) * bucketsPerBar; j++) {
328
            for (int j = i * bucketsPerBar; j < (i + 1) * bucketsPerBar; j++) {
227
                if (fNbBuckets <= j)
329
                if (fNbBuckets <= j)
Lines 240-250 public class HistogramDataModel { Link Here
240
        }
342
        }
241
343
242
        // Set the current event index in the scaled histogram
344
        // Set the current event index in the scaled histogram
243
        if (fCurrentEventTime >= fFirstEventTime && fCurrentEventTime <= fLastEventTime)
345
        if (fCurrentEventTime >= fFirstBucketTime && fCurrentEventTime <= fLastEventTime)
244
            result.fCurrentBucket = (int) ((fCurrentEventTime - fFirstEventTime) / fBucketDuration) / bucketsPerBar;
346
            result.fCurrentBucket = (int) ((fCurrentEventTime - fFirstBucketTime) / fBucketDuration) / bucketsPerBar;
245
        else
347
        else
246
            result.fCurrentBucket = HistogramScaledData.OUT_OF_RANGE_BUCKET;
348
            result.fCurrentBucket = HistogramScaledData.OUT_OF_RANGE_BUCKET;
247
349
350
        result.fFirstBucketTime = fFirstBucketTime;
351
        result.fFirstEventTime = fFirstEventTime;
248
        return result;
352
        return result;
249
    }
353
    }
250
354
Lines 253-259 public class HistogramDataModel { Link Here
253
    // ------------------------------------------------------------------------
357
    // ------------------------------------------------------------------------
254
358
255
    private void updateEndTime() {
359
    private void updateEndTime() {
256
        fTimeLimit = fFirstEventTime + fNbBuckets * fBucketDuration;
360
        fTimeLimit = fFirstBucketTime + fNbBuckets * fBucketDuration;
257
    }
361
    }
258
362
259
    private void mergeBuckets() {
363
    private void mergeBuckets() {
Lines 265-269 public class HistogramDataModel { Link Here
265
        updateEndTime();
369
        updateEndTime();
266
        fLastBucket = fNbBuckets / 2 - 1;
370
        fLastBucket = fNbBuckets / 2 - 1;
267
    }
371
    }
372
    
373
    private void moveBuckets(int offset) {
374
        for(int i = fNbBuckets - 1; i >= offset; i--) {
375
            fBuckets[i] = fBuckets[i-offset]; 
376
        }
377
378
        for (int i = 0; i < offset; i++) {
379
            fBuckets[i] = 0;
380
        }
381
    }
382
383
    private int getOffset(long timestamp) {
384
        int offset = (int) ((fFirstBucketTime - timestamp) / fBucketDuration);
385
        if ((fFirstBucketTime - timestamp) % fBucketDuration != 0) {
386
            offset++;
387
        }
388
        return offset;
389
    }
268
390
269
}
391
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramRequest.java (-7 / +7 lines)
Lines 30-51 public class HistogramRequest extends TmfEventRequest<LttngEvent> { Link Here
30
    // Attributes
30
    // Attributes
31
    // ------------------------------------------------------------------------
31
    // ------------------------------------------------------------------------
32
32
33
    private final Histogram fHistogram;
33
    protected final HistogramDataModel fHistogram;
34
34
35
    // ------------------------------------------------------------------------
35
    // ------------------------------------------------------------------------
36
    // Constructor
36
    // Constructor
37
    // ------------------------------------------------------------------------
37
    // ------------------------------------------------------------------------
38
38
39
    public HistogramRequest(Histogram histogram, TmfTimeRange range, int rank, int nbEvents, ITmfDataRequest.ExecutionType execType) {
39
    public HistogramRequest(HistogramDataModel histogram, TmfTimeRange range, int rank, int nbEvents, ITmfDataRequest.ExecutionType execType) {
40
        super(LttngEvent.class, range, rank, nbEvents, LttngConstants.DEFAULT_BLOCK_SIZE, execType);
40
        super(LttngEvent.class, range, rank, nbEvents, LttngConstants.DEFAULT_BLOCK_SIZE, execType);
41
        fHistogram = histogram;
41
        fHistogram = histogram;
42
    }
42
    }
43
43
44
    public HistogramRequest(Histogram histogram, TmfTimeRange range, ITmfDataRequest.ExecutionType execType) {
44
    public HistogramRequest(HistogramDataModel histogram, TmfTimeRange range, ITmfDataRequest.ExecutionType execType) {
45
        this(histogram, range, 0, ALL_DATA, execType);
45
        this(histogram, range, 0, ALL_DATA, execType);
46
    }
46
    }
47
47
48
    public HistogramRequest(Histogram histogram, TmfTimeRange range, int rank, ITmfDataRequest.ExecutionType execType) {
48
    public HistogramRequest(HistogramDataModel histogram, TmfTimeRange range, int rank, ITmfDataRequest.ExecutionType execType) {
49
        this(histogram, range, rank, ALL_DATA, execType);
49
        this(histogram, range, rank, ALL_DATA, execType);
50
    }
50
    }
51
51
Lines 58-76 public class HistogramRequest extends TmfEventRequest<LttngEvent> { Link Here
58
        super.handleData(event);
58
        super.handleData(event);
59
        if (event != null) {
59
        if (event != null) {
60
            long timestamp = event.getTimestamp().getValue();
60
            long timestamp = event.getTimestamp().getValue();
61
            fHistogram.countEvent(timestamp);
61
            fHistogram.countEvent(getNbRead(), timestamp);
62
        }
62
        }
63
    }
63
    }
64
64
65
    @Override
65
    @Override
66
    public void handleCompleted() {
66
    public void handleCompleted() {
67
        fHistogram.refresh();
67
        fHistogram.complete();
68
        super.handleCompleted();
68
        super.handleCompleted();
69
    }
69
    }
70
70
71
    @Override
71
    @Override
72
    public void handleCancel() {
72
    public void handleCancel() {
73
        fHistogram.refresh();
73
        fHistogram.clear();
74
        super.handleCancel();
74
        super.handleCancel();
75
    }
75
    }
76
76
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramScaledData.java (-2 / +32 lines)
Lines 8-13 Link Here
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *   Francois Chouinard - Initial API and implementation
10
 *   Francois Chouinard - Initial API and implementation
11
 *   Bernd Hufmann - Added setter and getter
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.linuxtools.lttng.ui.views.histogram;
14
package org.eclipse.linuxtools.lttng.ui.views.histogram;
Lines 33-70 public class HistogramScaledData { Link Here
33
34
34
    public int fWidth;
35
    public int fWidth;
35
    public int fHeight;
36
    public int fHeight;
37
    public int fBarWidth;
36
    public int[] fData;
38
    public int[] fData;
37
    public long fBucketDuration;
39
    public long fBucketDuration;
38
    public long fMaxValue;
40
    public long fMaxValue;
39
    public int fCurrentBucket;
41
    public int fCurrentBucket;
40
    public int fLastBucket;
42
    public int fLastBucket;
41
    public double fScalingFactor;
43
    public double fScalingFactor;
44
    public long fFirstBucketTime;
45
    public long fFirstEventTime;
42
46
43
    // ------------------------------------------------------------------------
47
    // ------------------------------------------------------------------------
44
    // Constructor
48
    // Constructor
45
    // ------------------------------------------------------------------------
49
    // ------------------------------------------------------------------------
46
50
47
    public HistogramScaledData(int width, int height) {
51
    public HistogramScaledData(int width, int height, int barWidth) {
48
        fWidth = width;
52
        fWidth = width;
49
        fHeight = height;
53
        fHeight = height;
50
        fData = new int[width];
54
        fBarWidth = barWidth;
55
        fData = new int[width/fBarWidth];
51
        Arrays.fill(fData, 0);
56
        Arrays.fill(fData, 0);
52
        fBucketDuration = 1;
57
        fBucketDuration = 1;
53
        fMaxValue = 0;
58
        fMaxValue = 0;
54
        fCurrentBucket = 0;
59
        fCurrentBucket = 0;
55
        fLastBucket = 0;
60
        fLastBucket = 0;
56
        fScalingFactor = 1;
61
        fScalingFactor = 1;
62
        fFirstBucketTime = 0;
57
    }
63
    }
58
64
59
    public HistogramScaledData(HistogramScaledData other) {
65
    public HistogramScaledData(HistogramScaledData other) {
60
        fWidth = other.fWidth;
66
        fWidth = other.fWidth;
61
        fHeight = other.fHeight;
67
        fHeight = other.fHeight;
68
        fBarWidth = other.fBarWidth;
62
        fData = Arrays.copyOf(other.fData, fWidth);
69
        fData = Arrays.copyOf(other.fData, fWidth);
63
        fBucketDuration = other.fBucketDuration;
70
        fBucketDuration = other.fBucketDuration;
64
        fMaxValue = other.fMaxValue;
71
        fMaxValue = other.fMaxValue;
65
        fCurrentBucket = other.fCurrentBucket;
72
        fCurrentBucket = other.fCurrentBucket;
66
        fLastBucket = other.fLastBucket;
73
        fLastBucket = other.fLastBucket;
67
        fScalingFactor = other.fScalingFactor;
74
        fScalingFactor = other.fScalingFactor;
75
        fFirstBucketTime = other.fFirstBucketTime;
76
    }
77
    
78
    // ------------------------------------------------------------------------
79
    // Setter and Getter
80
    // ------------------------------------------------------------------------
81
    public long getFirstBucketTime() {
82
        return fFirstBucketTime;
68
    }
83
    }
69
84
85
    public void setFirstBucketTime(long firstEventTime) {
86
        fFirstBucketTime = firstEventTime;
87
    }
88
    
89
    public long getLastBucketTime() {
90
        return getBucketStartTime(fLastBucket);
91
    }
92
    
93
    public long getBucketStartTime(int index) {
94
        return fFirstBucketTime + index * fBucketDuration;
95
    }
96
    
97
    public long getBucketEndTime(int index) {
98
        return getBucketStartTime(index) + fBucketDuration;
99
    }
70
}
100
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/HistogramView.java (-5 / +4 lines)
Lines 265-272 public class HistogramView extends TmfView { Link Here
265
    public void updateCurrentEventTime(long newTime) {
265
    public void updateCurrentEventTime(long newTime) {
266
        if (fCurrentExperiment != null) {
266
        if (fCurrentExperiment != null) {
267
            TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BigCrunch);
267
            TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(newTime, TIME_SCALE), TmfTimestamp.BigCrunch);
268
            HistogramRequest request = new HistogramRequest(fTimeRangeHistogram, timeRange, 0, 1,
268
            HistogramRequest request = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, 0, 1, ExecutionType.FOREGROUND) {
269
                    ExecutionType.FOREGROUND) {
270
                @Override
269
                @Override
271
                public void handleData(LttngEvent event) {
270
                public void handleData(LttngEvent event) {
272
                    if (event != null) {
271
                    if (event != null) {
Lines 445-451 public class HistogramView extends TmfView { Link Here
445
444
446
        fTimeRangeHistogram.clear();
445
        fTimeRangeHistogram.clear();
447
        fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
446
        fTimeRangeHistogram.setTimeRange(startTime, endTime - startTime);
448
        fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram, timeRange, ExecutionType.FOREGROUND);
447
        fTimeRangeRequest = new HistogramRequest(fTimeRangeHistogram.getDataModel(), timeRange, ExecutionType.FOREGROUND);
449
        fCurrentExperiment.sendRequest(fTimeRangeRequest);
448
        fCurrentExperiment.sendRequest(fTimeRangeRequest);
450
    }
449
    }
451
450
Lines 453-460 public class HistogramView extends TmfView { Link Here
453
        if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
452
        if (fFullTraceRequest != null && !fFullTraceRequest.isCompleted()) {
454
            fFullTraceRequest.cancel();
453
            fFullTraceRequest.cancel();
455
        }
454
        }
456
        fFullTraceRequest = new HistogramRequest(fFullTraceHistogram, fullRange,
455
        fFullTraceRequest = new HistogramRequest(fFullTraceHistogram.getDataModel(), fullRange, (int) fFullTraceHistogram.fDataModel.getNbEvents(),
457
                (int) fFullTraceHistogram.fDataModel.getNbEvents(), ExecutionType.BACKGROUND);
456
                ExecutionType.BACKGROUND);
458
        fCurrentExperiment.sendRequest(fFullTraceRequest);
457
        fCurrentExperiment.sendRequest(fFullTraceRequest);
459
    }
458
    }
460
459
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/IHistogramDataModel.java (+38 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.histogram;
13
14
/**
15
 * <b><u>IHistogramDataModel</u></b>
16
 * <p>
17
 */
18
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDistributionModel;
19
20
public interface IHistogramDataModel extends IBaseDistributionModel {
21
    /**
22
     * Add event to the correct bucket, compacting the if needed.
23
     * 
24
     * @param timestamp the timestamp of the event to count
25
     */
26
    public void countEvent(long eventCount, long timestamp);
27
    
28
    /**
29
     * Scale the model data to the width, height and bar width requested.
30
     * 
31
     * @param width
32
     * @param height
33
     * @param bar width
34
     * @return the result array of size [width] and where the highest value
35
     *         doesn't exceed [height] considering the bar width [barWidth]
36
     */
37
    public HistogramScaledData scaleTo(int width, int height, int barWidth);
38
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/IHistogramModelListener.java (+23 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.histogram;
13
14
/**
15
 * <b><u>IHistogramModelListener</u></b>
16
 * <p>
17
 */
18
public interface IHistogramModelListener {
19
    /**
20
     * Method to notify listeners about model updates 
21
     */
22
    public void modelUpdated();
23
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/histogram/TimeRangeHistogram.java (-1 / +2 lines)
Lines 1-6 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
3
 * 
2
 * 
3
 * Copyright (c) 2011 Ericsson
4
 * All rights reserved. This program and the accompanying materials are
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
5
 * made available under the terms of the Eclipse Public License v1.0 which
6
 * accompanies this distribution, and is available at
6
 * accompanies this distribution, and is available at
Lines 8-13 Link Here
8
 * 
8
 * 
9
 * Contributors:
9
 * Contributors:
10
 *   Francois Chouinard - Initial API and implementation
10
 *   Francois Chouinard - Initial API and implementation
11
 *   Bernd Hufmann - Changed to updated histogram data model   
11
 *******************************************************************************/
12
 *******************************************************************************/
12
13
13
package org.eclipse.linuxtools.lttng.ui.views.histogram;
14
package org.eclipse.linuxtools.lttng.ui.views.histogram;
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/AbstractViewer.java (+255 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency;
15
16
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDistributionModel;
17
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractMouseListener;
18
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractMouseTrackListener;
19
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener;
20
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.ZoomListener;
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.SWTException;
23
import org.eclipse.swt.widgets.Canvas;
24
import org.eclipse.swt.widgets.Composite;
25
import org.eclipse.swt.widgets.Display;
26
27
/**
28
 * <b><u>AbstractViewer</u></b>
29
 * <p>
30
 * Abstract viewer.
31
 * 
32
 * @author Philippe Sawicki
33
 */
34
public abstract class AbstractViewer extends Canvas {
35
36
    // ------------------------------------------------------------------------
37
    // Attributes
38
    // ------------------------------------------------------------------------
39
40
    /**
41
     * Parent composite node.
42
     */
43
    protected Composite fParent;
44
45
    /**
46
     * Paint listener.
47
     */
48
    protected AbstractPaintListener fPaintListener;
49
50
    /**
51
     * Zoom listener, to zoom in and out of a graph using the scroll wheel.
52
     */
53
    protected ZoomListener fZoomListener;
54
55
    /**
56
     * Tool tip listener.
57
     */
58
    protected AbstractMouseTrackListener fMouseTraceListener;
59
60
    /**
61
     * Mouse listener
62
     */
63
    protected AbstractMouseListener fMouseListener;
64
65
    // ------------------------------------------------------------------------
66
    // Constructor
67
    // ------------------------------------------------------------------------
68
    
69
    /**
70
     * Constructor.
71
     * @param parent
72
     *            The parent composite node.
73
     * @param style
74
     *            The SWT style to use to render the view.
75
     */
76
    public AbstractViewer(Composite parent, int style) {
77
        super(parent, style);
78
79
        fParent = parent;
80
    }
81
82
    // ------------------------------------------------------------------------
83
    // Abstract interface
84
    // ------------------------------------------------------------------------
85
    
86
    /**
87
     * Clears the view.
88
     */
89
    abstract public void clear();
90
91
    /**
92
     * Clears the background of the view but keeps min and max values.
93
     */
94
    abstract public void clearBackground();
95
96
    /**
97
     * Method to increase bar width
98
     */
99
    abstract public void increaseBarWidth();
100
    
101
    /**
102
     * Method to decrease bar width
103
     */
104
    abstract public void decreaseBarWidth();
105
106
    /**
107
     * Return data model
108
     */
109
    abstract public IBaseDistributionModel getModel();
110
    
111
    
112
    // ------------------------------------------------------------------------
113
    // Accessors
114
    // ------------------------------------------------------------------------
115
116
    /**
117
     * Returns the zoom factor for the canvas.
118
     * @return The zoom factor for the canvas.
119
     */
120
    public int getZoomFactor() {
121
        if (fZoomListener != null) {
122
            return fZoomListener.getZoomFactor();
123
        } else {
124
            return 1;
125
        }
126
    }
127
128
    /**
129
     * Returns the zoom increment for the canvas.
130
     * @return The zoom increment for the canvas.
131
     */
132
    public int getZoomIncrement() {
133
        if (fZoomListener != null) {
134
            return fZoomListener.getZoomIncrement();
135
        } else {
136
            return 1;
137
        }
138
    }
139
140
    
141
    // ------------------------------------------------------------------------
142
    // Operations
143
    // ------------------------------------------------------------------------
144
    
145
    /**
146
     * Draw horizontal label each "nbTicks" ticks.
147
     * @param nbTicks
148
     *            The draw interval.
149
     */
150
    public void setDrawLabelEachNTicks(int nbTicks) {
151
        fPaintListener.setDrawLabelEachNTicks(nbTicks);
152
    }
153
154
    /**
155
     * Sets the title of the graph.
156
     * @param graphTitle
157
     *            The title of the graph.
158
     */
159
    public void setGraphTitle(String graphTitle) {
160
        fPaintListener.setGraphTitle(graphTitle);
161
    }
162
163
    /**
164
     * Sets the horizontal axis label.
165
     * @param xLabel
166
     *            The horizontal axis label.
167
     * @param offset
168
     *            The horizontal axis draw offset (in pixels).
169
     */
170
    public void setXAxisLabel(String xLabel, int offset) {
171
        fPaintListener.setXAxisLabel(xLabel, offset);
172
    }
173
174
    /**
175
     * Sets the vertical axis label.
176
     * @param yLabel
177
     *            The vertical axis label.
178
     */
179
    public void setYAxisLabel(String yLabel) {
180
        fPaintListener.setYAxisLabel(yLabel);
181
    }
182
183
    /**
184
     * Asks for the view to be redrawn, synchronously or asynchronously.
185
     * @param asyncRedraw
186
     *            If "true", the view will be redrawn asynchronously, otherwise it will be redraw synchronously.
187
     */
188
    public void askForRedraw(boolean asyncRedraw) {
189
        if (asyncRedraw == true) {
190
            Display.getDefault().asyncExec(new Runnable() {
191
                @Override
192
                public void run() {
193
                    try {
194
                        redraw();
195
                    } catch (SWTException e) {
196
                        // ...
197
                    }
198
                }
199
            });
200
        } else {
201
            Display.getDefault().syncExec(new Runnable() {
202
                @Override
203
                public void run() {
204
                    try {
205
                        redraw();
206
                    } catch (SWTException e) {
207
                        // ...
208
                    }
209
                }
210
            });
211
        }
212
    }
213
214
    /**
215
     * Asks for the view to be redrawn (asynchronously).
216
     */
217
    public void askForRedraw() {
218
        askForRedraw(true);
219
    }
220
221
    /**
222
     * Redraws the title after a zoom to display the new zoom factor.
223
     */
224
    public void redrawTitle() {
225
        fPaintListener.paintGraphTitle();
226
    }
227
228
    /**
229
     * Removes the view's listeners before disposing of it.
230
     */
231
    @Override
232
    public void dispose() {
233
        try {
234
            if (fPaintListener != null) {
235
                removePaintListener(fPaintListener);
236
                fPaintListener = null;
237
            }
238
            if (fZoomListener != null) {
239
                removeListener(SWT.MouseWheel, fZoomListener);
240
                fZoomListener = null;
241
            }
242
            if (fMouseTraceListener != null) {
243
                removeListener(SWT.MouseMove, fMouseTraceListener);
244
                fMouseTraceListener = null;
245
            }
246
        } catch (SWTException e) {
247
            // This exception will be thrown if the user closes the view
248
            // while it is receiving data from the Analyzer.
249
250
            // ...
251
        }
252
253
        super.dispose();
254
    }
255
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/GraphViewer.java (+158 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency;
15
16
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.GraphMouseListener;
17
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.GraphPaintListener;
18
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.TimePointerListener;
19
import org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphDataModel;
20
import org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener;
21
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyGraphModel;
22
import org.eclipse.swt.widgets.Composite;
23
24
/**
25
 * <b><u>GraphViewer</u></b>
26
 * <p>
27
 * Graph viewer.
28
 * 
29
 * @author Philippe Sawicki
30
 */
31
public class GraphViewer extends AbstractViewer implements IGraphModelListener {
32
33
    // ------------------------------------------------------------------------
34
    // Attributes
35
    // ------------------------------------------------------------------------
36
37
    /**
38
     * Latency graph model
39
     */
40
    private LatencyGraphModel fModel;
41
42
    // ------------------------------------------------------------------------
43
    // Constructors
44
    // ------------------------------------------------------------------------
45
46
	/**
47
	 * Constructor.
48
	 * @param parent The parent composite node.
49
	 * @param style The SWT style to use to render the view.
50
	 */
51
	public GraphViewer(Composite parent, int style) {
52
		super(parent, style);
53
54
		// Register the paint listener
55
		fPaintListener = new GraphPaintListener(this);
56
		addPaintListener(fPaintListener);
57
58
		// Register the mouse track listener
59
		fMouseTraceListener = new TimePointerListener(this, (GraphPaintListener)fPaintListener);
60
		addMouseTrackListener(fMouseTraceListener);
61
62
		// Register mouse listener
63
		fMouseListener = new GraphMouseListener(this, (GraphPaintListener)fPaintListener);
64
		addMouseListener(fMouseListener);
65
66
		fModel = new LatencyGraphModel();
67
        fModel.addGraphModelListener(this);
68
	}
69
70
    // ------------------------------------------------------------------------
71
    // Operations
72
    // ------------------------------------------------------------------------
73
	
74
	/*
75
	 * (non-Javadoc)
76
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#dispose()
77
	 */
78
	@Override
79
	public void dispose() {
80
	    fModel.removeGraphModelListener(this);
81
	    fPaintListener.dispose();
82
	    super.dispose();
83
	}
84
	
85
	/*
86
	 * (non-Javadoc)
87
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#clear()
88
	 */
89
	@Override
90
	public void clear() {
91
		fPaintListener.clear();
92
	}
93
	
94
	/*
95
	 * (non-Javadoc)
96
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#clearBackground()
97
	 */
98
	@Override
99
	public void clearBackground() {
100
		fPaintListener.clear();
101
	}
102
103
    /*
104
     * (non-Javadoc)
105
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#increaseBarWidth()
106
     */
107
    @Override
108
    public void increaseBarWidth() {
109
        fPaintListener.increaseBarWitdh();
110
        graphModelUpdated();
111
    }
112
    
113
    /*
114
     * (non-Javadoc)
115
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#decreaseBarWidth()
116
     */
117
    @Override
118
    public void decreaseBarWidth() {
119
        fPaintListener.decreaseBarWitdh();
120
        graphModelUpdated();
121
    }
122
    
123
    /*
124
     * (non-Javadoc)
125
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#getModel()
126
     */
127
    @Override
128
    public IGraphDataModel getModel() {
129
        return fModel;
130
    }
131
    
132
    /*
133
     * (non-Javadoc)
134
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#graphModelUpdated()
135
     */
136
    @Override
137
    public void graphModelUpdated() {
138
        if (!isDisposed() && getDisplay() != null) {
139
            getDisplay().asyncExec(new Runnable() {
140
                @Override
141
                public void run() {
142
                    if (!isDisposed()) {
143
                        redraw();
144
                    }
145
                }
146
            });
147
        }
148
    }
149
150
    /*
151
     * (non-Javadoc)
152
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#currentEventUpdated()
153
     */
154
    @Override
155
    public void currentEventUpdated(long currentEventTime) {
156
        graphModelUpdated();
157
    }
158
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/HistogramViewer.java (+157 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency;
15
16
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramDataModel;
17
import org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramDataModel;
18
import org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramModelListener;
19
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.HistogramPaintListener;
20
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.TooltipListener;
21
import org.eclipse.linuxtools.lttng.ui.views.latency.listeners.ZoomListener;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.widgets.Composite;
24
25
/**
26
 * <b><u>HistogramViewer</u></b>
27
 * <p>
28
 * 
29
 * Histogram viewer.
30
 * 
31
 * @author Philippe Sawicki
32
 */
33
public class HistogramViewer extends AbstractViewer implements IHistogramModelListener {
34
35
    // ------------------------------------------------------------------------
36
    // Attributes
37
    // ------------------------------------------------------------------------
38
39
	/**
40
	 * Usable width for data plotting.
41
	 */
42
	protected int fUsableWidth;
43
44
	/**
45
	 * Latency histogram model.
46
	 */
47
	private HistogramDataModel fModel;
48
49
    // ------------------------------------------------------------------------
50
    // Constructors
51
    // ------------------------------------------------------------------------
52
53
	/**
54
	 * Constructor.
55
	 * @param parent The parent composite node.
56
	 * @param style The SWT style to use to render the view.
57
	 */
58
	public HistogramViewer(Composite parent, int style) {
59
		super(parent, style);
60
		
61
		// Register the paint listener
62
		fPaintListener = new HistogramPaintListener(this);
63
		addPaintListener(fPaintListener);
64
		
65
		// Register the zoom listener
66
		fZoomListener = new ZoomListener(this);
67
		addListener(SWT.MouseWheel, fZoomListener);
68
		
69
		// Register the mouse click listener
70
		fMouseTraceListener = new TooltipListener(this, (HistogramPaintListener)fPaintListener);
71
		addMouseTrackListener(fMouseTraceListener);
72
		
73
		fModel = new HistogramDataModel();
74
		fModel.addHistogramListener(this);
75
	}
76
77
    // ------------------------------------------------------------------------
78
    // Operations
79
    // ------------------------------------------------------------------------
80
81
	/*
82
	 * (non-Javadoc)
83
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#dispose()
84
	 */
85
	@Override
86
	public void dispose() {
87
	    fModel.removeHistogramListener(this);
88
	    fPaintListener.dispose();
89
	    super.dispose();
90
	}
91
92
	/*
93
	 * (non-Javadoc)
94
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#clear()
95
	 */
96
	@Override
97
	public void clear() {
98
		fPaintListener.clear();
99
	}
100
101
	/*
102
	 * (non-Javadoc)
103
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#clearBackground()
104
	 */
105
	@Override
106
	public void clearBackground() {
107
		fPaintListener.clear();
108
	}
109
110
	/*
111
	 * (non-Javadoc)
112
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#increaseBarWidth()
113
	 */
114
	@Override
115
    public void increaseBarWidth() {
116
	    fPaintListener.increaseBarWitdh();
117
	    modelUpdated();
118
	}
119
120
	/*
121
	 * (non-Javadoc)
122
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#decreaseBarWidth()
123
	 */
124
	@Override
125
    public void decreaseBarWidth() {
126
	    fPaintListener.decreaseBarWitdh();
127
	    modelUpdated();
128
	}
129
130
	/*
131
	 * (non-Javadoc)
132
	 * @see org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer#getModel()
133
	 */
134
	@Override
135
    public IHistogramDataModel getModel() {
136
        return fModel;
137
    }
138
139
	/*
140
	 * (non-Javadoc)
141
	 * @see org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramModelListener#modelUpdated()
142
	 */
143
    @Override
144
    public void modelUpdated() {
145
        
146
        if (!isDisposed() && getDisplay() != null) {
147
            getDisplay().asyncExec(new Runnable() {
148
                @Override
149
                public void run() {
150
                    if (!isDisposed()) {
151
                        redraw();
152
                    }
153
                }
154
            });
155
        }
156
    }
157
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/LatencyView.java (+477 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency;
15
16
import org.eclipse.jface.action.Action;
17
import org.eclipse.jface.action.IMenuManager;
18
import org.eclipse.jface.action.IToolBarManager;
19
import org.eclipse.jface.action.Separator;
20
import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
21
import org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AddDialog;
22
import org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.DeleteDialog;
23
import org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.ListDialog;
24
import org.eclipse.linuxtools.lttng.ui.views.latency.model.Config;
25
import org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener;
26
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyController;
27
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyGraphModel;
28
import org.eclipse.linuxtools.tmf.core.event.TmfEvent;
29
import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
30
import org.eclipse.linuxtools.tmf.core.event.TmfTimestamp;
31
import org.eclipse.linuxtools.tmf.core.experiment.TmfExperiment;
32
import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
33
import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
34
import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentDisposedSignal;
35
import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentRangeUpdatedSignal;
36
import org.eclipse.linuxtools.tmf.core.signal.TmfExperimentSelectedSignal;
37
import org.eclipse.linuxtools.tmf.core.signal.TmfRangeSynchSignal;
38
import org.eclipse.linuxtools.tmf.core.signal.TmfSignalHandler;
39
import org.eclipse.linuxtools.tmf.core.signal.TmfTimeSynchSignal;
40
import org.eclipse.linuxtools.tmf.ui.views.TmfView;
41
import org.eclipse.swt.SWT;
42
import org.eclipse.swt.events.ControlEvent;
43
import org.eclipse.swt.events.ControlListener;
44
import org.eclipse.swt.layout.FillLayout;
45
import org.eclipse.swt.widgets.Composite;
46
import org.eclipse.ui.IActionBars;
47
import org.eclipse.ui.plugin.AbstractUIPlugin;
48
49
/**
50
 * <b><u>LatencyView</u></b>
51
 * <p>
52
 * TmfView displaying the latency views (i.e. the two latency charts).
53
 * 
54
 * @author Philippe Sawicki
55
 */
56
public class LatencyView extends TmfView implements IGraphModelListener {
57
58
    // ------------------------------------------------------------------------
59
    // Attributes
60
    // ------------------------------------------------------------------------
61
    
62
    // The initial window span (in nanoseconds)
63
    public static long INITIAL_WINDOW_SPAN = (1L * 100 * 1000 * 1000); // .1sec
64
65
    /**
66
     * The view's unique ID.
67
     */
68
    public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.latency.LatencyView"; //$NON-NLS-1$
69
70
    /**
71
     * A reference to the currently selected experiment.
72
     */
73
    protected TmfExperiment<LttngEvent> fExperiment = null;
74
75
    /**
76
     * Parent composite.
77
     */
78
    protected Composite fParent;
79
80
    /**
81
     * Graph view.
82
     */
83
    protected GraphViewer fGraphViewer;
84
    
85
    /**
86
     * Histogram view.
87
     */
88
    protected HistogramViewer fHistogramViewer;
89
90
    /**
91
     * Action executed when the user wants to see the list of matching events.
92
     */
93
    protected Action fListMatchingEvents;
94
    
95
    /**
96
     * Action executed when the user wants to add matching events.
97
     */
98
    protected Action fAddMatchingEvents;
99
    
100
    /**
101
     * Action executed when the user wants to delete matching events.
102
     */
103
    protected Action fDeleteMatchingEvents;
104
    
105
    /**
106
     * Action executed when the user wants to increase the width of the histogram bars.
107
     */
108
    protected Action fIncreaseBarWidth;
109
    
110
    /**
111
     * Action executed when the user wants to decrease the width of the histogram bars.
112
     */
113
    protected Action fDecreaseBarWidth;
114
115
    /**
116
     * The current histogram window time range.
117
     */
118
    protected TmfTimeRange fTimeRange = null;
119
120
    /**
121
     * Controller of the latency model which is responsible to retrieve data from the trace
122
     */
123
    final private LatencyController fController;
124
125
    /**
126
     * Flag to notify that TimeSyncSignal was received and is being processed.
127
     */
128
    private boolean fSyncSignalReceived = false;
129
130
    // ------------------------------------------------------------------------
131
    // Constructor
132
    // ------------------------------------------------------------------------
133
134
    /**
135
     * Constructor.
136
     */
137
    public LatencyView() {
138
        super(Messages.LatencyView_ViewName);
139
        fController = LatencyController.getInstance();
140
    }
141
142
    // ------------------------------------------------------------------------
143
    // Operations
144
    // ------------------------------------------------------------------------
145
    
146
    /**
147
     * Create the UI controls of this view.
148
     * 
149
     * @param parent
150
     *            The composite parent of this view.
151
     */
152
    @Override
153
    public void createPartControl(Composite parent) {
154
        // Save the parent
155
        fParent = parent;
156
157
        makeActions();
158
        contributeToActionBars();
159
160
        // Add a control listener to handle the view resize events (to redraw the canvas)
161
        fParent.addControlListener(new ControlListener() {
162
            @Override
163
            public void controlMoved(ControlEvent event) {
164
                fHistogramViewer.clearBackground();
165
                fGraphViewer.clearBackground();
166
                fController.handleCompleted();
167
            }
168
169
            @Override
170
            public void controlResized(ControlEvent event) {
171
                fHistogramViewer.clearBackground();
172
                fGraphViewer.clearBackground();
173
                fController.handleCompleted();
174
            }
175
        });
176
177
        // ///////////////////////////////////////////////////////////////////////////////////
178
        // Layout for the whole view, other elements will be in a child composite of this one
179
        // Contains :
180
        // Composite layoutSelectionWindow
181
        // Composite layoutTimesSpinner
182
        // Composite layoutExperimentHistogram
183
        // ///////////////////////////////////////////////////////////////////////////////////
184
        Composite layoutFullView = new Composite(fParent, SWT.FILL);
185
        FillLayout gridFullView = new FillLayout();
186
        gridFullView.marginHeight = 0;
187
        gridFullView.marginWidth = 0;
188
        layoutFullView.setLayout(gridFullView);
189
190
        // Create the graph views
191
        fGraphViewer = new GraphViewer(layoutFullView, SWT.DOUBLE_BUFFERED);
192
        fGraphViewer.setDrawLabelEachNTicks(2);
193
        fGraphViewer.setGraphTitle(Messages.LatencyView_Graphs_Graph_Title);
194
        fGraphViewer.setXAxisLabel(Messages.LatencyView_Graphs_Graph_XAxisLabel, 40);
195
        fGraphViewer.setYAxisLabel(Messages.LatencyView_Graphs_Graph_YAxisLabel);
196
197
        fHistogramViewer = new HistogramViewer(layoutFullView, SWT.DOUBLE_BUFFERED);
198
        fHistogramViewer.setDrawLabelEachNTicks(2);
199
        fHistogramViewer.setGraphTitle(Messages.LatencyView_Graphs_Histogram_Title);
200
        fHistogramViewer.setXAxisLabel(Messages.LatencyView_Graphs_Histogram_XAxisLabel, 55);
201
        fHistogramViewer.setYAxisLabel(Messages.LatencyView_Graphs_Histogram_YAxisLabel);
202
203
        fController.registerModel(fGraphViewer.getModel());
204
        fController.registerModel(fHistogramViewer.getModel());
205
        
206
        ((LatencyGraphModel)fGraphViewer.getModel()).addGraphModelListener(this);
207
        
208
        @SuppressWarnings("unchecked")
209
        TmfExperiment<TmfEvent> experiment = (TmfExperiment<TmfEvent>) TmfExperiment.getCurrentExperiment();
210
        if (experiment != null) {
211
212
            TmfTimeRange experimentTRange = experiment.getTimeRange();
213
214
            if (experimentTRange != TmfTimeRange.Null) {
215
                TmfExperimentSelectedSignal<TmfEvent> signal = new TmfExperimentSelectedSignal<TmfEvent>(this, experiment);
216
                experimentSelected(signal);
217
            }
218
        }
219
    }
220
221
    @SuppressWarnings("nls")
222
    @Override
223
    public String toString() {
224
        return "["+ Messages.LatencyView_ViewName+"]";
225
    }
226
227
    // ------------------------------------------------------------------------
228
    // Signal handlers
229
    // ------------------------------------------------------------------------
230
231
    @SuppressWarnings("unchecked")
232
    @TmfSignalHandler
233
    public void experimentSelected(TmfExperimentSelectedSignal<TmfEvent> signal) {
234
        // Clear the views
235
        fGraphViewer.clear();
236
        fHistogramViewer.clear();
237
238
        if (fParent != null) {
239
            // Update the trace reference
240
            fExperiment = (TmfExperiment<LttngEvent>) signal.getExperiment();
241
242
            fTimeRange = TmfTimeRange.Null;
243
            TmfTimeRange experimentTRange = fExperiment.getTimeRange();
244
245
            if (!experimentTRange.equals(TmfTimeRange.Null)) {
246
                fTimeRange = new TmfTimeRange(experimentTRange.getStartTime(), 
247
                        new TmfTimestamp(experimentTRange.getStartTime().getValue() + INITIAL_WINDOW_SPAN, experimentTRange.getStartTime().getScale(), experimentTRange.getStartTime().getPrecision()));
248
                fController.refreshModels(fExperiment, fTimeRange);
249
            }
250
        }
251
    }    
252
    @TmfSignalHandler
253
    public void experimentRangeUpdated(TmfExperimentRangeUpdatedSignal signal) {
254
        if (fTimeRange == TmfTimeRange.Null && signal.getExperiment().equals(fExperiment)) {
255
            TmfTimeRange experimentTRange = signal.getRange();
256
257
            if (experimentTRange != TmfTimeRange.Null) {
258
                fTimeRange = new TmfTimeRange(experimentTRange.getStartTime(), 
259
                        new TmfTimestamp(experimentTRange.getStartTime().getValue() + INITIAL_WINDOW_SPAN, experimentTRange.getStartTime().getScale(), experimentTRange.getStartTime().getPrecision()));
260
                fController.refreshModels(fExperiment, fTimeRange);
261
            }
262
        }
263
    }
264
    
265
    @TmfSignalHandler
266
    public void experimentDisposed(TmfExperimentDisposedSignal<TmfEvent> signal) {
267
        fTimeRange = TmfTimeRange.Null;
268
        fExperiment = null;
269
        fController.clear();
270
    }
271
272
    /**
273
     * Called when the LatencyView is closed: disposes of the canvas and unregisters models from views.
274
     */
275
    @Override
276
    public void dispose() {
277
        fController.dispose();
278
        fController.deregisterModel(fGraphViewer.getModel());
279
        fController.deregisterModel(fHistogramViewer.getModel());
280
        ((LatencyGraphModel)fGraphViewer.getModel()).removeGraphModelListener(this);
281
282
        fGraphViewer.dispose();
283
        fHistogramViewer.dispose();
284
285
        super.dispose();
286
    }
287
288
    /**
289
     * Method called when synchronization is active and that the user select an event.
290
     * 
291
     * The models will be updated with the new current selected time.
292
     * 
293
     * @param signal
294
     *            Signal received from the framework. Contain the event.
295
     */
296
    @TmfSignalHandler
297
    public void currentTimeUpdated(TmfTimeSynchSignal signal) {
298
        if (signal.getSource() != this) {
299
            fSyncSignalReceived = true;
300
            fController.setCurrentEventTime(signal.getCurrentTime().getValue());
301
            fSyncSignalReceived = false;
302
        }
303
    }
304
305
    /**
306
     * Method called when synchronization is active and that the user changed the current time range.
307
308
     * The models will be updated with the new time range.
309
     * 
310
     * @param signal
311
     *            Signal received from the framework. Contain the new time range.
312
     */
313
    @TmfSignalHandler
314
    public void synchToTimeRange(TmfRangeSynchSignal signal) {
315
        if (signal.getSource() != this) {
316
            // Erase the graph views
317
            fGraphViewer.clear();
318
            fHistogramViewer.clear();
319
            
320
            TmfTimestamp startTime = signal.getCurrentRange().getStartTime();
321
            TmfTimestamp endTime = signal.getCurrentRange().getEndTime();
322
            fTimeRange = new TmfTimeRange(startTime, endTime);
323
324
            fController.refreshModels(fExperiment, fTimeRange);
325
        }
326
    }
327
    
328
    /*
329
     * (non-Javadoc)
330
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#graphModelUpdated()
331
     */
332
    @Override
333
    public void graphModelUpdated() {
334
        // Nothing to do - update of viewers will be done in the viewers
335
    }
336
337
    /*
338
     * (non-Javadoc)
339
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphModelListener#currentEventUpdated(long)
340
     */
341
    @Override
342
    public void currentEventUpdated(final long currentEventTime) {
343
        if (fExperiment != null && 
344
                !fSyncSignalReceived && // Don't broadcast the current time that was received just before with a time sync signal
345
                currentEventTime != Config.INVALID_EVENT_TIME) {
346
347
            // Queue update in the event request queue 
348
            TmfTimeRange timeRange = new TmfTimeRange(new TmfTimestamp(currentEventTime, Config.TIME_SCALE), TmfTimestamp.BigCrunch);
349
            TmfEventRequest<LttngEvent> request = new TmfEventRequest<LttngEvent>(LttngEvent.class, timeRange, 0, 1, ExecutionType.FOREGROUND) {
350
                @Override
351
                public void handleCompleted() {
352
                    broadcast(new TmfTimeSynchSignal(this, new TmfTimestamp(currentEventTime, Config.TIME_SCALE)));
353
                }
354
            };
355
            fExperiment.sendRequest(request);
356
        }
357
    }
358
    
359
    // ------------------------------------------------------------------------
360
    // Helper functions
361
    // ------------------------------------------------------------------------
362
    
363
    /**
364
     * Fills the local pull down menu.
365
     * @param manager
366
     *            The menu manager.
367
     */
368
    private void fillLocalPullDown(IMenuManager manager) {
369
        manager.add(new Separator());
370
        manager.add(fIncreaseBarWidth);
371
        manager.add(fDecreaseBarWidth);
372
        manager.add(new Separator());
373
        manager.add(fListMatchingEvents);
374
        manager.add(fAddMatchingEvents);
375
        manager.add(fDeleteMatchingEvents);
376
        manager.add(new Separator());
377
    }
378
379
    /**
380
     * Fills the local toolbar.
381
     * @param manager
382
     *            The toolbar manager
383
     */
384
    private void fillLocalToolBar(IToolBarManager manager) {
385
        manager.add(new Separator());
386
        manager.add(fIncreaseBarWidth);
387
        manager.add(fDecreaseBarWidth);
388
        manager.add(new Separator());
389
        manager.add(fListMatchingEvents);
390
        manager.add(fAddMatchingEvents);
391
        manager.add(fDeleteMatchingEvents);
392
        manager.add(new Separator());
393
    }
394
395
    /**
396
     * Creates the actions required by the dialog events.
397
     */
398
    private void makeActions() {
399
        // Increase the histogram bar width
400
        fIncreaseBarWidth = new Action() {
401
            @Override
402
            public void run() {
403
                fHistogramViewer.increaseBarWidth();
404
                fGraphViewer.increaseBarWidth();
405
            }
406
        };
407
        String tooltipText = Messages.LatencyView_Action_IncreaseBarWidth_Tooltip;
408
        fIncreaseBarWidth.setText(tooltipText);
409
        fIncreaseBarWidth.setToolTipText(tooltipText);
410
        fIncreaseBarWidth.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/increasebar_button.gif")); //$NON-NLS-1$
411
412
        // Decrease the histogram bar width
413
        fDecreaseBarWidth = new Action() {
414
            @Override
415
            public void run() {
416
                fHistogramViewer.decreaseBarWidth();
417
                fGraphViewer.decreaseBarWidth();
418
            }
419
        };
420
        tooltipText = Messages.LatencyView_Action_DecreaseBarWidth_Tooltip;
421
        fDecreaseBarWidth.setText(tooltipText);
422
        fDecreaseBarWidth.setToolTipText(tooltipText);
423
        fDecreaseBarWidth.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/decreasebar_button.gif")); //$NON-NLS-1$
424
425
        // List matching events dialog
426
        fListMatchingEvents = new Action() {
427
            @Override
428
            public void run() {
429
                ListDialog listDialog = new ListDialog(fParent.getShell(), Messages.LatencyView_Dialogs_ListEvents_Title, Messages.LatencyView_Dialogs_ListEvents_Message);
430
                listDialog.create();
431
                listDialog.open();
432
            }
433
        };
434
        tooltipText = Messages.LatencyView_Action_ListEvents_Tooltip;
435
        fListMatchingEvents.setText(tooltipText);
436
        fListMatchingEvents.setToolTipText(tooltipText);
437
        fListMatchingEvents.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/eview16/events_view.gif")); //$NON-NLS-1$
438
439
        // Add matching events dialog
440
        fAddMatchingEvents = new Action() {
441
            @Override
442
            public void run() {
443
                AddDialog addDialog = new AddDialog(fParent.getShell(), Messages.LatencyView_Dialogs_AddEvents_Title, Messages.LatencyView_Dialogs_AddEvents_Message);
444
                addDialog.create();
445
                addDialog.open();
446
            }
447
        };
448
        tooltipText = Messages.LatencyView_Action_AddEvents_Tooltip;
449
        fAddMatchingEvents.setText(tooltipText);
450
        fAddMatchingEvents.setToolTipText(tooltipText);
451
        fAddMatchingEvents.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/add_button.gif")); //$NON-NLS-1$
452
453
        // Remove matching events dialog
454
        fDeleteMatchingEvents = new Action() {
455
            @Override
456
            public void run() {
457
                DeleteDialog deleteDialog = new DeleteDialog(fParent.getShell(), Messages.LatencyView_Dialogs_DeleteEvents_Title,
458
                        Messages.LatencyView_Dialogs_DeleteEvents_Message);
459
                deleteDialog.create();
460
                deleteDialog.open();
461
            }
462
        };
463
        tooltipText = Messages.LatencyView_Action_DeleteEvents_Tooltip;
464
        fDeleteMatchingEvents.setText(tooltipText);
465
        fDeleteMatchingEvents.setToolTipText(tooltipText);
466
        fDeleteMatchingEvents.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/delete_button.gif")); //$NON-NLS-1$
467
    }
468
469
    /**
470
     * Build the toolbar and menu by adding action buttons for dialogs.
471
     */
472
    private void contributeToActionBars() {
473
        IActionBars bars = getViewSite().getActionBars();
474
        fillLocalPullDown(bars.getMenuManager());
475
        fillLocalToolBar(bars.getToolBarManager());
476
    }
477
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/Messages.java (+85 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Updated    
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency;
15
16
import org.eclipse.osgi.util.NLS;
17
18
/**
19
 * Returns localized strings from the resource bundle (i.e. "messages.properties").
20
 * 
21
 * @author Philippe Sawicki
22
 */
23
public class Messages {
24
25
    public static String LatencyView_ViewName;
26
    public static String LatencyView_Action_IncreaseBarWidth_Tooltip;
27
    public static String LatencyView_Action_DecreaseBarWidth_Tooltip;
28
    public static String LatencyView_Action_AddEvents_Tooltip;
29
    public static String LatencyView_Action_DeleteEvents_Tooltip;
30
    public static String LatencyView_Action_ListEvents_Tooltip;
31
    public static String LatencyView_Dialogs_AddEvents_Title;
32
    public static String LatencyView_Dialogs_AddEvents_Message;
33
    public static String LatencyView_Dialogs_AddEvents_Buttons_Add;
34
    public static String LatencyView_Dialogs_AddEvents_Buttons_Close;
35
    public static String LatencyView_Dialogs_AddEvents_Columns_Start;
36
    public static String LatencyView_Dialogs_AddEvents_Columns_End;
37
    public static String LatencyView_Dialogs_AddEvents_Columns_List_Trigger;
38
    public static String LatencyView_Dialogs_AddEvents_Columns_List_End;
39
    public static String LatencyView_Dialogs_AddEvents_Errors_NoSelection;
40
    public static String LatencyView_Dialogs_AddEvents_Errors_StartNotSelected;
41
    public static String LatencyView_Dialogs_AddEvents_Errors_EndNotSelected;
42
    public static String LatencyView_Dialogs_AddEvents_Errors_SameSelected;
43
    public static String LatencyView_Dialogs_AddEvents_Errors_AlreadyMatched;
44
    public static String LatencyView_Dialogs_AddEvents_Errors_StartAlreadyMatched;
45
    public static String LatencyView_Dialogs_AddEvents_Errors_EndAlreadyMatched;
46
    public static String LatencyView_Dialogs_AddEvents_Errors_StartAsEnd;
47
    public static String LatencyView_Dialogs_AddEvents_Errors_EndAsStart;
48
    public static String LatencyView_Dialogs_DeleteEvents_Title;
49
    public static String LatencyView_Dialogs_DeleteEvents_Message;
50
    public static String LatencyView_Dialogs_DeleteEvents_Buttons_Close;
51
    public static String LatencyView_Dialogs_DeleteEvents_Buttons_Delete;
52
    public static String LatencyView_Dialogs_DeleteEvents_Confirm_Title;
53
    public static String LatencyView_Dialogs_DeleteEvents_Confirm_Message;
54
    public static String LatencyView_Dialogs_ListEvents_Title;
55
    public static String LatencyView_Dialogs_ListEvents_Message;
56
    public static String LatencyView_Dialogs_ListEvents_Buttons_Close;
57
    public static String LatencyView_Dialogs_ListEvents_Buttons_Reset;
58
    public static String LatencyView_Dialogs_ListEvents_Columns_Trigger;
59
    public static String LatencyView_Dialogs_ListEvents_Columns_End;
60
    public static String LatencyView_Dialogs_ListEvents_Confirm_Title;
61
    public static String LatencyView_Dialogs_ListEvents_Confirm_Message;
62
    public static String LatencyView_Graphs_Graph_Title;
63
    public static String LatencyView_Graphs_Graph_XAxisLabel;
64
    public static String LatencyView_Graphs_Graph_YAxisLabel;
65
    public static String LatencyView_Graphs_Histogram_Title;
66
    public static String LatencyView_Graphs_Histogram_XAxisLabel;
67
    public static String LatencyView_Graphs_Histogram_YAxisLabel;
68
    public static String LatencyView_msgSlogan;
69
    public static String LatencyView_tmf_UI;
70
    public static String LatencyView_ClippingWarning;
71
    
72
73
    /**
74
     * Bundle name.
75
     */
76
    private static final String BUNDLE_NAME = "org.eclipse.linuxtools.lttng.ui.views.latency.messages"; //$NON-NLS-1$
77
78
    static {
79
        // initialize resource bundle
80
        NLS.initializeMessages(BUNDLE_NAME, Messages.class);
81
    }
82
83
    private Messages() {
84
    }
85
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/dialogs/AbstractDialog.java (+240 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new messages file, fixed warnings
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.dialogs;
15
16
import java.util.Vector;
17
18
import org.eclipse.jface.dialogs.IDialogSettings;
19
import org.eclipse.jface.dialogs.IMessageProvider;
20
import org.eclipse.jface.dialogs.TitleAreaDialog;
21
import org.eclipse.linuxtools.lttng.core.latency.analyzer.EventMatcher;
22
import org.eclipse.linuxtools.lttng.core.util.EventsPair;
23
import org.eclipse.linuxtools.lttng.ui.LTTngUiPlugin;
24
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyController;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.swt.widgets.Control;
27
import org.eclipse.swt.widgets.Display;
28
import org.eclipse.swt.widgets.Shell;
29
30
/**
31
 * <b><u>AbstractDialog</u></b>
32
 * <p> 
33
 * Includes the main functions shared by all the different dialogs.
34
 * 
35
 * @author Philippe Sawicki
36
 */
37
public abstract class AbstractDialog extends TitleAreaDialog {
38
39
    // ------------------------------------------------------------------------
40
    // Attributes
41
    // ------------------------------------------------------------------------
42
    
43
    /**
44
     * The dialog window title.
45
     */
46
    protected String fDialogTitle;
47
    /**
48
     * The dialog window message.
49
     */
50
    protected String fDialogMessage;
51
52
    /**
53
     * The code returned by the dialog when the user closes the "Add" dialog.
54
     */
55
    public static final int ADD = 53445;
56
    /**
57
     * The code returned by the dialog when the user closes the "Delete" dialog.
58
     */
59
    public static final int DELETE = ADD + 1;
60
    /**
61
     * The code returned by the dialog when the user resets the latency pair to default.
62
     */
63
    public static final int RESET = DELETE + 1;
64
65
    /**
66
     * String ID of the number of pairs saved in the settings file.
67
     */
68
    protected static final String LATENCY_NB_MATCH_PAIRS = "NB_LATENCY_MATCH_PAIRS"; //$NON-NLS-1$
69
    /**
70
     * String ID of the start event pairs saved in the settings file.
71
     */
72
    protected static final String LATENCY_PAIRS_START = "LATENCY_PAIRS_START"; //$NON-NLS-1$
73
    /**
74
     * String ID of the end event pairs saved in the settings file.
75
     */
76
    protected static final String LATENCY_PAIRS_END = "LATENCY_PAIRS_END"; //$NON-NLS-1$
77
78
    /**
79
     * Dialog settings, saves the event pairs across sessions.
80
     */
81
    protected IDialogSettings fSettings;
82
83
    /**
84
     * Do the graphs canvas need to be redrawn due to latency pairs changes ?
85
     */
86
    protected boolean fRedrawGraphs = false;
87
    
88
    // ------------------------------------------------------------------------
89
    // Constructors
90
    // ------------------------------------------------------------------------
91
92
    /**
93
     * Constructor.
94
     * @param parentShell
95
     *            The parent shell.
96
     * @param title
97
     *            The dialog window's title.
98
     * @param message
99
     *            The dialog window's message.
100
     */
101
    public AbstractDialog(Shell parentShell, String title, String message) {
102
        super(parentShell);
103
        fDialogTitle = title;
104
        fDialogMessage = message;
105
106
        fSettings = LTTngUiPlugin.getDefault().getDialogSettings();
107
    }
108
109
    /**
110
     * Constructor
111
     * @param parentShell
112
     *            The parent shell.
113
     * @param title
114
     *            The dialog window's title.
115
     */
116
    @SuppressWarnings("nls")
117
    public AbstractDialog(Shell parentShell, String title) {
118
        this(parentShell, title, "");
119
    }
120
121
    /**
122
     * Constructor.
123
     * @param parentShell
124
     *            The parent shell.
125
     */
126
    @SuppressWarnings("nls")
127
    public AbstractDialog(Shell parentShell) {
128
        this(parentShell, "", "");
129
    }
130
131
    // ------------------------------------------------------------------------
132
    // Operations
133
    // ------------------------------------------------------------------------
134
135
    /**
136
     * Creates the dialog.
137
     * 
138
     * <b>Note :</b> Since there is an issue with the table's vertical scroll bar, this dialog "resize" is necessary to
139
     * ensure a minimal height for the window.
140
     */
141
    @Override
142
    public void create() {
143
        super.create();
144
        // Set the title
145
        setTitle(fDialogTitle);
146
        // Set the message
147
        setMessage(fDialogMessage, IMessageProvider.INFORMATION);
148
149
        // Position the dialog at the center of the screen
150
        int windowWidth = Display.getCurrent().getPrimaryMonitor().getBounds().width;
151
        int windowHeight = Display.getCurrent().getPrimaryMonitor().getBounds().height;
152
        int dialogWidth = getShell().getSize().x;
153
        int dialogHeight = windowHeight / 2;
154
155
        int x = (windowWidth - dialogWidth) / 2;
156
        int y = (windowHeight - dialogHeight) / 2;
157
158
        getShell().setSize(getShell().getSize().x, dialogHeight);
159
        getShell().setLocation(x, y);
160
    }
161
162
    /**
163
     * Formats the "#" of the event in the table by adding "00" before it.
164
     * @param number
165
     *            The number to format.
166
     * @param max
167
     *            The maximum number of event pairs in the list.
168
     * @return The formatted string.
169
     */
170
    @SuppressWarnings("nls")
171
    protected String formatListNumber(int number, int max) {
172
        return String.format("%0" + max + "d", number);
173
    }
174
175
    /**
176
     * Returns the match pairs saved in the settings file.
177
     * @return The match pairs saved in the settings file.
178
     */
179
    protected EventsPair getMatchPairs() {
180
        try {
181
            // Check if the settings file has already some data (i.e. try provoking an exception)
182
            fSettings.getInt(LATENCY_NB_MATCH_PAIRS);
183
184
            String[] starts = fSettings.getArray(LATENCY_PAIRS_START);
185
            String[] ends = fSettings.getArray(LATENCY_PAIRS_END);
186
187
            EventMatcher.getInstance().resetMatches();
188
            for (int i = 0; i < starts.length; i++) {
189
                EventMatcher.getInstance().addMatch(starts[i], ends[i]);
190
            }
191
192
            return EventMatcher.getInstance().getEvents();
193
        } catch (NumberFormatException e) {
194
            return EventMatcher.getInstance().getEvents();
195
        }
196
    }
197
198
    /**
199
     * Saves the event match pairs to a settings file.
200
     * @param start
201
     *            The start event types.
202
     * @param end
203
     *            The end event types.
204
     */
205
    protected void saveMatchPairs(Vector<String> start, Vector<String> end) {
206
        fSettings.put(LATENCY_NB_MATCH_PAIRS, start.size());
207
        fSettings.put(LATENCY_PAIRS_START, start.toArray(new String[] {}));
208
        fSettings.put(LATENCY_PAIRS_END, end.toArray(new String[] {}));
209
    }
210
211
    /**
212
     * Ask the LatencyView to send a new analysis request to the views, so that they can be redrawn.
213
     */
214
    protected void redrawGraphs() {
215
        LatencyController.getInstance().refreshModels();
216
    }
217
218
    /*
219
     * (non-Javadoc)
220
     * @see org.eclipse.jface.dialogs.TitleAreaDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
221
     */
222
    @Override
223
    protected abstract Control createDialogArea(Composite parent);
224
225
    /*
226
     * (non-Javadoc)
227
     * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
228
     */
229
    @Override
230
    protected abstract void createButtonsForButtonBar(Composite parent);
231
    
232
    /*
233
     * (non-Javadoc)
234
     * @see org.eclipse.jface.dialogs.Dialog#isResizable()
235
     */
236
    @Override
237
    protected boolean isResizable() {
238
        return true;
239
    }
240
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/dialogs/AddDialog.java (+488 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new messages file, fixed warnings
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.dialogs;
15
16
import java.util.Vector;
17
18
import org.eclipse.linuxtools.lttng.core.latency.analyzer.EventMatcher;
19
import org.eclipse.linuxtools.lttng.core.util.EventsPair;
20
import org.eclipse.linuxtools.lttng.ui.views.latency.Messages;
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.layout.GridData;
23
import org.eclipse.swt.layout.GridLayout;
24
import org.eclipse.swt.widgets.Button;
25
import org.eclipse.swt.widgets.Composite;
26
import org.eclipse.swt.widgets.Control;
27
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Shell;
30
import org.eclipse.swt.widgets.Table;
31
import org.eclipse.swt.widgets.TableColumn;
32
import org.eclipse.swt.widgets.TableItem;
33
34
/**
35
 * <b><u>AddDialog</u></b>
36
 * <p>
37
 * Add dialog, lets the user add custom start/end event pairs.
38
 * 
39
 * @author Philippe Sawicki
40
 */
41
public class AddDialog extends AbstractDialog {
42
43
    // ------------------------------------------------------------------------
44
    // Attributes
45
    // ------------------------------------------------------------------------
46
47
    /**
48
     * The dialog's start table.
49
     */
50
    protected Table fStartTable;
51
52
    /**
53
     * The dialog's end table.
54
     */
55
    protected Table fEndTable;
56
57
    /**
58
     * The dialog's list table.
59
     */
60
    protected Table fListTable;
61
62
    /**
63
     * Start table columns.
64
     */
65
    protected TableColumn[] fStartColumns;
66
67
    /**
68
     * End table columns.
69
     */
70
    protected TableColumn[] fEndColumns;
71
72
    /**
73
     * List table columns.
74
     */
75
    protected TableColumn[] fListColumns;
76
77
    /**
78
     * Start table column names (header titles).
79
     */
80
    protected static final String[] START_COLUMN_NAMES = { "", Messages.LatencyView_Dialogs_AddEvents_Columns_Start }; //$NON-NLS-1$
81
82
    /**
83
     * End table column names (header titles).
84
     */
85
    protected static final String[] END_COLUMN_NAMES = { "", Messages.LatencyView_Dialogs_AddEvents_Columns_End }; //$NON-NLS-1$
86
87
    /**
88
     * List table column names (header titles).
89
     */
90
    protected static final String[] LIST_COLUMN_NAMES = {
91
            "#", //$NON-NLS-1$
92
            Messages.LatencyView_Dialogs_AddEvents_Columns_List_Trigger,
93
            Messages.LatencyView_Dialogs_AddEvents_Columns_List_End };
94
95
    /**
96
     * Column widths.
97
     */
98
    protected static final int[] COLUMN_WIDTHS = { 25, 250, 250 };
99
100
    /**
101
     * Possible event types.
102
     */
103
    protected Vector<String> fEventTypes = new Vector<String>();
104
105
    /**
106
     * Start event types.
107
     */
108
    protected Vector<String> fEventStartTypes;
109
110
    /**
111
     * End event types.
112
     */
113
    protected Vector<String> fEventEndTypes;
114
115
    /**
116
     * Selected start type.
117
     */
118
    protected String fStartType;
119
120
    /**
121
     * Selected end type.
122
     */
123
    protected String fEndType;
124
125
    // ------------------------------------------------------------------------
126
    // Constructors
127
    // ------------------------------------------------------------------------
128
129
    /**
130
     * Constructor.
131
     * @param parentShell
132
     *            The parent shell.
133
     * @param title
134
     *            The dialog's window title.
135
     * @param message
136
     *            The dialog's window message.
137
     */
138
    public AddDialog(Shell parentShell, String title, String message) {
139
        super(parentShell, title, message);
140
141
        // Get the possible events from the list
142
        fEventTypes = EventMatcher.getInstance().getTypeList();
143
144
        // Get the list of start and end types from the EventMatcher
145
        EventsPair pair = getMatchPairs();
146
        fEventStartTypes = pair.getFirst();
147
        fEventEndTypes = pair.getSecond();
148
    }
149
150
    // ------------------------------------------------------------------------
151
    // Operations
152
    // ------------------------------------------------------------------------
153
154
    /**
155
     * Creates the start table's columns (i.e. the table header).
156
     */
157
    protected void createStartColumns() {
158
        fStartColumns = new TableColumn[START_COLUMN_NAMES.length];
159
        for (int i = 0; i < START_COLUMN_NAMES.length; i++) {
160
            fStartColumns[i] = new TableColumn(fStartTable, SWT.LEFT);
161
            fStartColumns[i].setText(START_COLUMN_NAMES[i]);
162
            fStartColumns[i].setWidth(COLUMN_WIDTHS[i]);
163
        }
164
    }
165
166
    /**
167
     * Creates the end table's columns (i.e. the table header).
168
     */
169
    protected void createEndColumns() {
170
        fEndColumns = new TableColumn[END_COLUMN_NAMES.length];
171
        for (int i = 0; i < END_COLUMN_NAMES.length; i++) {
172
            fEndColumns[i] = new TableColumn(fEndTable, SWT.LEFT);
173
            fEndColumns[i].setText(END_COLUMN_NAMES[i]);
174
            fEndColumns[i].setWidth(COLUMN_WIDTHS[i]);
175
        }
176
    }
177
178
    /**
179
     * Creates the list table's columns (i.e. the table header).
180
     */
181
    protected void createListColumns() {
182
        fListColumns = new TableColumn[LIST_COLUMN_NAMES.length];
183
        for (int i = 0; i < LIST_COLUMN_NAMES.length; i++) {
184
            fListColumns[i] = new TableColumn(fListTable, SWT.LEFT);
185
            fListColumns[i].setText(LIST_COLUMN_NAMES[i]);
186
            fListColumns[i].setWidth(COLUMN_WIDTHS[i]);
187
        }
188
    }
189
190
    /**
191
     * Creates the start column list.
192
     * @param parent
193
     *            The parent composite.
194
     */
195
    protected void createStartColumn(Composite parent) {
196
        final int style = SWT.SINGLE | SWT.CHECK | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL;
197
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
198
        fStartTable = new Table(parent, style);
199
        fStartTable.setLayoutData(layoutData);
200
201
        // Some cosmetic enhancements
202
        fStartTable.setHeaderVisible(true);
203
        fStartTable.setLinesVisible(true);
204
205
        createStartColumns();
206
207
        for (int i = 0; i < fEventTypes.size(); i++) {
208
            TableItem item = new TableItem(fStartTable, SWT.RIGHT);
209
210
            String[] columns = { fEventTypes.get(i), fEventTypes.get(i) };
211
212
            item.setText(columns);
213
        }
214
215
        fStartTable.setItemCount(fEventTypes.size());
216
217
        fStartTable.addListener(SWT.Selection, new Listener() {
218
            @Override
219
            public void handleEvent(Event event) {
220
                if (event.detail == SWT.CHECK) {
221
                    TableItem[] items = fStartTable.getItems();
222
                    for (TableItem item : items) {
223
                        if (item != event.item) {
224
                            item.setChecked(false);
225
                        }
226
                    }
227
                }
228
            }
229
        });
230
    }
231
232
    /**
233
     * Creates the end column list.
234
     * @param parent
235
     *            The parent composite.
236
     */
237
    protected void createEndColumn(Composite parent) {
238
        final int style = SWT.SINGLE | SWT.CHECK | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL;
239
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
240
        fEndTable = new Table(parent, style);
241
        fEndTable.setLayoutData(layoutData);
242
243
        // Some cosmetic enhancements
244
        fEndTable.setHeaderVisible(true);
245
        fEndTable.setLinesVisible(true);
246
247
        createEndColumns();
248
249
        for (int i = 0; i < fEventTypes.size(); i++) {
250
            TableItem item = new TableItem(fEndTable, SWT.RIGHT);
251
252
            String[] columns = { fEventTypes.get(i), fEventTypes.get(i) };
253
254
            item.setText(columns);
255
        }
256
257
        fEndTable.setItemCount(fEventTypes.size());
258
259
        fEndTable.addListener(SWT.Selection, new Listener() {
260
            @Override
261
            public void handleEvent(Event event) {
262
                if (event.detail == SWT.CHECK) {
263
                    TableItem[] items = fEndTable.getItems();
264
                    for (TableItem item : items) {
265
                        if (item != event.item) {
266
                            item.setChecked(false);
267
                        }
268
                    }
269
                }
270
            }
271
        });
272
    }
273
274
    /**
275
     * Creates the list column for already existing event pairs.
276
     * @param parent
277
     *            The parent composite.
278
     */
279
    protected void createListColumn(Composite parent) {
280
        final int style = SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL;
281
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
282
        layoutData.horizontalSpan = 2;
283
        fListTable = new Table(parent, style);
284
        fListTable.setLayoutData(layoutData);
285
286
        // Some cosmetic enhancements
287
        fListTable.setHeaderVisible(true);
288
        fListTable.setLinesVisible(true);
289
290
        createListColumns();
291
292
        for (int i = 0; i < fEventStartTypes.size(); i++) {
293
            TableItem item = new TableItem(fListTable, SWT.RIGHT);
294
295
            String max = String.valueOf(fEventStartTypes.size());
296
            String number = formatListNumber(i + 1, max.length());
297
298
            String[] columns = { number, fEventStartTypes.get(i), fEventEndTypes.get(i) };
299
300
            item.setText(columns);
301
        }
302
303
        fListTable.setItemCount(103);
304
        fListTable.remove(fEventTypes.size(), 103 - 1);
305
    }
306
307
    /*
308
     * (non-Javadoc)
309
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
310
     */
311
    @Override
312
    protected Control createDialogArea(Composite parent) {
313
        GridLayout layout = new GridLayout(2, true);
314
        parent.setLayout(layout);
315
316
        createStartColumn(parent);
317
        createEndColumn(parent);
318
        createListColumn(parent);
319
320
        return parent;
321
    }
322
323
    /*
324
     * (non-Javadoc)
325
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
326
     */
327
    @Override
328
    protected void createButtonsForButtonBar(Composite parent) {
329
        GridData gridData = new GridData();
330
        gridData.verticalAlignment = GridData.FILL;
331
        gridData.horizontalSpan = 1;
332
        gridData.grabExcessHorizontalSpace = true;
333
        gridData.grabExcessVerticalSpace = true;
334
        gridData.horizontalAlignment = SWT.RIGHT;
335
336
        parent.setLayoutData(gridData);
337
338
        // Create the "Add" button
339
        Button addButton = createButton(parent, ADD, Messages.LatencyView_Dialogs_AddEvents_Buttons_Add, false);
340
        addButton.addListener(SWT.Selection, new Listener() {
341
            @Override
342
            public void handleEvent(Event event) {
343
                if (isValidInput()) {
344
                    // Add the event pair to the EventMatcher and save the pairs
345
                    EventMatcher.getInstance().addMatch(fStartType, fEndType);
346
                    fEventStartTypes.add(fStartType);
347
                    fEventEndTypes.add(fEndType);
348
                    saveMatchPairs(fEventStartTypes, fEventEndTypes);
349
350
                    EventsPair pairs = EventMatcher.getInstance().getEvents();
351
                    fEventStartTypes = pairs.getFirst();
352
                    fEventEndTypes = pairs.getSecond();
353
354
                    fListTable.removeAll();
355
356
                    for (int i = 0; i < fEventStartTypes.size(); i++) {
357
                        TableItem item = new TableItem(fListTable, SWT.RIGHT);
358
359
                        String max = String.valueOf(fEventStartTypes.size());
360
                        String number = formatListNumber(i + 1, max.length());
361
362
                        String[] columns = { number, fEventStartTypes.get(i), fEventEndTypes.get(i) };
363
364
                        item.setText(columns);
365
                    }
366
367
                    saveMatchPairs(fEventStartTypes, fEventEndTypes);
368
                }
369
370
                fRedrawGraphs = true;
371
            }
372
        });
373
374
        // Create the "Close" button
375
        Button closeButton = createButton(parent, CANCEL, Messages.LatencyView_Dialogs_AddEvents_Buttons_Close, false);
376
        closeButton.addListener(SWT.Selection, new Listener() {
377
            @Override
378
            public void handleEvent(Event event) {
379
                setReturnCode(CANCEL);
380
381
                if (fRedrawGraphs == true)
382
                    redrawGraphs();
383
384
                close();
385
            }
386
        });
387
    }
388
389
    /**
390
     * Validate the list before adding event pairs.
391
     * @return "true" if the input is valid, "false" otherwise.
392
     */
393
    protected boolean isValidInput() {
394
        // Remove the previous error message
395
        setErrorMessage(null);
396
397
        boolean valid = true;
398
399
        // Check if an item from the start list is selected
400
        TableItem[] items = fStartTable.getItems();
401
        fStartType = null;
402
        boolean startHasSelectedItem = false;
403
        for (int i = 0; i < items.length && !startHasSelectedItem; i++) {
404
            if (items[i].getChecked() == true) {
405
                fStartType = items[i].getText();
406
                startHasSelectedItem = true;
407
            }
408
        }
409
410
        // Check if an item from the end list is selected
411
        items = fEndTable.getItems();
412
        fEndType = null;
413
        boolean endHasSelectedItem = false;
414
        for (int i = 0; i < items.length && !endHasSelectedItem; i++) {
415
            if (items[i].getChecked() == true) {
416
                fEndType = items[i].getText();
417
                endHasSelectedItem = true;
418
            }
419
        }
420
421
        // Print error message if needed.
422
        if (!startHasSelectedItem && !endHasSelectedItem) {
423
            setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_NoSelection);
424
            valid = false;
425
        } else if (!startHasSelectedItem) {
426
            setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_StartNotSelected);
427
            valid = false;
428
        } else if (!endHasSelectedItem) {
429
            setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_EndNotSelected);
430
            valid = false;
431
        }
432
433
        // Check if the same item is selected in both lists
434
        if (startHasSelectedItem && endHasSelectedItem) {
435
            if (fStartType.equalsIgnoreCase(fEndType)) {
436
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_SameSelected);
437
                valid = false;
438
            }
439
        }
440
441
        // Check if the selected item is already in the list
442
        if (startHasSelectedItem && endHasSelectedItem) {
443
            EventsPair pairs = getMatchPairs();
444
            Vector<String> startEvents = pairs.getFirst();
445
            Vector<String> endEvents = pairs.getSecond();
446
447
            boolean startAlreadyUsed = false;
448
            boolean endAlreadyUsed = false;
449
            boolean startAsEndAlreadyUsed = false;
450
            boolean endAsStartAlreadyUsed = false;
451
452
            if (startEvents.contains(fStartType)) {
453
                startAlreadyUsed = true;
454
            }
455
            if (endEvents.contains(fEndType)) {
456
                endAlreadyUsed = true;
457
            }
458
            if (startEvents.contains(fEndType)) {
459
                endAsStartAlreadyUsed = true;
460
            }
461
            if (endEvents.contains(fStartType)) {
462
                startAsEndAlreadyUsed = true;
463
            }
464
465
            if (startAlreadyUsed && endAlreadyUsed) {
466
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_AlreadyMatched);
467
                valid = false;
468
            } else if (startAlreadyUsed) {
469
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_StartAlreadyMatched);
470
                valid = false;
471
            } else if (endAlreadyUsed) {
472
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_EndAlreadyMatched);
473
                valid = false;
474
            }
475
476
            if (startAsEndAlreadyUsed) {
477
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_StartAsEnd);
478
                valid = false;
479
            }
480
            if (endAsStartAlreadyUsed) {
481
                setErrorMessage(Messages.LatencyView_Dialogs_AddEvents_Errors_EndAsStart);
482
                valid = false;
483
            }
484
        }
485
486
        return valid;
487
    }
488
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/dialogs/DeleteDialog.java (+155 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new messages file, fixed warnings
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.dialogs;
15
16
import org.eclipse.jface.dialogs.MessageDialog;
17
import org.eclipse.linuxtools.lttng.core.latency.analyzer.EventMatcher;
18
import org.eclipse.linuxtools.lttng.ui.views.latency.Messages;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.layout.GridData;
21
import org.eclipse.swt.widgets.Button;
22
import org.eclipse.swt.widgets.Composite;
23
import org.eclipse.swt.widgets.Event;
24
import org.eclipse.swt.widgets.Listener;
25
import org.eclipse.swt.widgets.Shell;
26
import org.eclipse.swt.widgets.TableItem;
27
28
/**
29
 * <b><u>DeleteDialog</u></b>
30
 * <p>
31
 * Remove dialog, lets the user remove start/end event pairs.
32
 * 
33
 * @author Philippe Sawicki
34
 */
35
public class DeleteDialog extends ListDialog {
36
37
    // ------------------------------------------------------------------------
38
    // Constructors
39
    // ------------------------------------------------------------------------
40
41
    /**
42
     * Constructor.
43
     * @param parentShell
44
     *            The parent shell.
45
     * @param title
46
     *            The dialog's window title.
47
     * @param message
48
     *            The dialog's window message.
49
     */
50
    public DeleteDialog(Shell parentShell, String title, String message) {
51
        super(parentShell, title, message);
52
53
        // Set the table style
54
        fStyle = SWT.MULTI | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL;
55
    }
56
57
    // ------------------------------------------------------------------------
58
    // Operations
59
    // ------------------------------------------------------------------------
60
61
    /*
62
     * (non-Javadoc)
63
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.ListDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
64
     */
65
    @Override
66
    protected void createButtonsForButtonBar(Composite parent) {
67
        GridData gridData = new GridData();
68
        gridData.verticalAlignment = GridData.FILL;
69
        gridData.horizontalSpan = 1;
70
        gridData.grabExcessHorizontalSpace = true;
71
        gridData.grabExcessVerticalSpace = true;
72
        gridData.horizontalAlignment = SWT.RIGHT;
73
74
        parent.setLayoutData(gridData);
75
76
        // Create the "Delete" button
77
        Button deleteButton = createButton(parent, DELETE, Messages.LatencyView_Dialogs_DeleteEvents_Buttons_Delete, false);
78
        deleteButton.addListener(SWT.Selection, new Listener() {
79
            @Override
80
            public void handleEvent(Event event) {
81
                TableItem selectedItem = fTable.getSelection()[0];
82
                if (selectedItem == null)
83
                    return;
84
85
                int[] selectedIndices = fTable.getSelectionIndices();
86
87
                String deletePairs = ""; //$NON-NLS-1$
88
                for (int i = 0; i < selectedIndices.length; i++) {
89
                    int index = selectedIndices[i];
90
                    deletePairs += "\t* " + fEventStartTypes.get(index) + " / " + fEventEndTypes.get(index); //$NON-NLS-1$ //$NON-NLS-2$
91
92
                    if (i < selectedIndices.length - 1) {
93
                        deletePairs += "\n"; //$NON-NLS-1$
94
                    }
95
                }
96
97
                boolean confirmDeletion = MessageDialog.openQuestion(getShell(), Messages.LatencyView_Dialogs_DeleteEvents_Confirm_Title,
98
                        Messages.LatencyView_Dialogs_DeleteEvents_Confirm_Message + "\n\n" + deletePairs); //$NON-NLS-1$
99
100
                if (confirmDeletion) {
101
                    // Remove the events starting from the end of the list, otherwise the TableItem elements will lose
102
                    // their index from the table and may trigger an exception when removing an index that is no longer
103
                    // valid.
104
                    for (int i = selectedIndices.length - 1; i >= 0; i--) {
105
                        int selectedIndex = selectedIndices[i];
106
                        EventMatcher.getInstance().removeMatch(fEventStartTypes.get(selectedIndex), fEventEndTypes.get(selectedIndex));
107
108
                        fTable.remove(selectedIndex);
109
110
                        // Update the list of events
111
                        fEventStartTypes.remove(selectedIndex);
112
                        fEventEndTypes.remove(selectedIndex);
113
                    }
114
115
                    // Save the events pairs in the settings file so it can be retrieved in the next session
116
                    saveMatchPairs(fEventStartTypes, fEventEndTypes);
117
118
                    fTable.setItemCount(fEventStartTypes.size());
119
120
                    TableItem[] newItems = fTable.getItems();
121
                    fTable.removeAll();
122
                    for (int i = 0; i < newItems.length; i++) {
123
                        TableItem item = new TableItem(fTable, SWT.RIGHT);
124
125
                        String max = String.valueOf(fEventStartTypes.size());
126
                        String number = formatListNumber(i + 1, max.length());
127
128
                        String[] columns = { number, fEventStartTypes.get(i), fEventEndTypes.get(i) };
129
130
                        item.setText(columns);
131
                    }
132
133
                    fRedrawGraphs = true;
134
                }
135
            }
136
        });
137
138
        // Create the "Close" button
139
        Button closeButton = createButton(parent, CANCEL, Messages.LatencyView_Dialogs_AddEvents_Buttons_Close, false);
140
        closeButton.addListener(SWT.Selection, new Listener() {
141
            @Override
142
            public void handleEvent(Event event) {
143
                // Remember the user's list
144
                saveMatchPairs(fEventStartTypes, fEventEndTypes);
145
146
                setReturnCode(CANCEL);
147
148
                if (fRedrawGraphs == true)
149
                    redrawGraphs();
150
151
                close();
152
            }
153
        });
154
    }
155
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/dialogs/ListDialog.java (+252 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new messages file, fixed warnings
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.dialogs;
15
16
import java.util.Vector;
17
18
import org.eclipse.jface.dialogs.MessageDialog;
19
import org.eclipse.linuxtools.lttng.core.latency.analyzer.EventMatcher;
20
import org.eclipse.linuxtools.lttng.core.util.EventsPair;
21
import org.eclipse.linuxtools.lttng.ui.views.latency.Messages;
22
import org.eclipse.swt.SWT;
23
import org.eclipse.swt.layout.GridData;
24
import org.eclipse.swt.layout.GridLayout;
25
import org.eclipse.swt.widgets.Button;
26
import org.eclipse.swt.widgets.Composite;
27
import org.eclipse.swt.widgets.Control;
28
import org.eclipse.swt.widgets.Event;
29
import org.eclipse.swt.widgets.Listener;
30
import org.eclipse.swt.widgets.Shell;
31
import org.eclipse.swt.widgets.Table;
32
import org.eclipse.swt.widgets.TableColumn;
33
import org.eclipse.swt.widgets.TableItem;
34
35
/**
36
 * <b><u>ListDialog</u></b>
37
 * <p>
38
 * List dialog, shows the list of start/end event pairs.
39
 * 
40
 * @author Philippe Sawicki
41
 */
42
public class ListDialog extends AbstractDialog {
43
44
    // ------------------------------------------------------------------------
45
    // Attributes
46
    // ------------------------------------------------------------------------
47
48
    /**
49
     * The dialog's table.
50
     */
51
    protected Table fTable;
52
53
    /**
54
     * Start event types.
55
     */
56
    protected Vector<String> fEventStartTypes;
57
58
    /**
59
     * End event types.
60
     */
61
    protected Vector<String> fEventEndTypes;
62
63
    /**
64
     * Table columns
65
     */
66
    protected TableColumn[] fColumns;
67
68
    /**
69
     * Column names (header titles).
70
     */
71
    protected static final String[] COLUMN_NAMES = { "#", Messages.LatencyView_Dialogs_ListEvents_Columns_Trigger, Messages.LatencyView_Dialogs_ListEvents_Columns_End }; //$NON-NLS-1$
72
73
    /**
74
     * Column widths.
75
     */
76
    protected static final int[] COLUMN_WIDTHS = { 25, 250, 250 };
77
78
    /**
79
     * The table style.
80
     */
81
    protected int fStyle;
82
83
    // ------------------------------------------------------------------------
84
    // Constructor
85
    // ------------------------------------------------------------------------
86
87
    /**
88
     * Constructor.
89
     * @param parentShell
90
     *            The parent shell.
91
     * @param title
92
     *            The dialog's window title.
93
     * @param message
94
     *            The dialog's window message.
95
     */
96
    public ListDialog(Shell parentShell, String title, String message) {
97
        super(parentShell, title, message);
98
99
        // Set the table style
100
        fStyle = SWT.SINGLE | SWT.FULL_SELECTION | SWT.BORDER | SWT.V_SCROLL;
101
102
        // Get the list of start and end types from the EventMatcher
103
        EventsPair pair = getMatchPairs();
104
        fEventStartTypes = pair.getFirst();
105
        fEventEndTypes = pair.getSecond();
106
    }
107
108
    // ------------------------------------------------------------------------
109
    // Operations
110
    // ------------------------------------------------------------------------
111
    
112
    /**
113
     * Creates the table's column (i.e. the table header).
114
     */
115
    protected void createColumns() {
116
        fColumns = new TableColumn[COLUMN_NAMES.length];
117
        for (int i = 0; i < COLUMN_NAMES.length; i++) {
118
            fColumns[i] = new TableColumn(fTable, SWT.LEFT);
119
            fColumns[i].setText(COLUMN_NAMES[i]);
120
            fColumns[i].setWidth(COLUMN_WIDTHS[i]);
121
        }
122
    }
123
    
124
    /*
125
     * (non-Javadoc)
126
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
127
     */
128
    @Override
129
    protected Control createDialogArea(Composite parent) {
130
        GridLayout layout = new GridLayout(1, true);
131
        parent.setLayout(layout);
132
133
        GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true);
134
        fTable = new Table(parent, fStyle);
135
        fTable.setLayoutData(layoutData);
136
137
        // Some cosmetic enhancements
138
        fTable.setHeaderVisible(true);
139
        fTable.setLinesVisible(true);
140
141
        createColumns();
142
143
        for (int i = 0; i < fEventStartTypes.size(); i++) {
144
            TableItem item = new TableItem(fTable, SWT.RIGHT);
145
146
            String max = String.valueOf(fEventStartTypes.size());
147
            String number = formatListNumber(i + 1, max.length());
148
149
            String[] columns = { number, fEventStartTypes.get(i), fEventEndTypes.get(i) };
150
151
            item.setText(columns);
152
        }
153
154
        return parent;
155
    }
156
157
    /*
158
     * (non-Javadoc)
159
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
160
     */
161
    @Override
162
    protected void createButtonsForButtonBar(Composite parent) {
163
        GridData gridData = new GridData();
164
        gridData.verticalAlignment = GridData.FILL;
165
        gridData.horizontalSpan = 1;
166
        gridData.grabExcessHorizontalSpace = true;
167
        gridData.grabExcessVerticalSpace = true;
168
        gridData.horizontalAlignment = SWT.RIGHT;
169
170
        parent.setLayoutData(gridData);
171
172
        // Create the "Reset" button
173
        Button resetButton = createButton(parent, RESET, Messages.LatencyView_Dialogs_ListEvents_Buttons_Reset, false);
174
        resetButton.addListener(SWT.Selection, new Listener() {
175
            @Override
176
            public void handleEvent(Event event) {
177
                boolean confirmDeletion = MessageDialog.openQuestion(getShell(), Messages.LatencyView_Dialogs_ListEvents_Confirm_Title,
178
                        Messages.LatencyView_Dialogs_ListEvents_Confirm_Message);
179
180
                if (confirmDeletion) {
181
                    EventMatcher.getInstance().resetMatches();
182
183
                    fTable.removeAll();
184
185
                    Vector<String> defaultStarts = new Vector<String>();
186
                    Vector<String> defaultEnds = new Vector<String>();
187
188
                    defaultStarts.add(EventMatcher.PAGE_FAULT_GET_USER_ENTRY);
189
                    defaultEnds.add(EventMatcher.PAGE_FAULT_GET_USER_EXIT);
190
                    defaultStarts.add(EventMatcher.TASKLET_LOW_ENTRY);
191
                    defaultEnds.add(EventMatcher.TASKLET_LOW_EXIT);
192
                    defaultStarts.add(EventMatcher.PAGE_FAULT_ENTRY);
193
                    defaultEnds.add(EventMatcher.PAGE_FAULT_EXIT);
194
                    defaultStarts.add(EventMatcher.SYSCALL_ENTRY);
195
                    defaultEnds.add(EventMatcher.SYSCALL_EXIT);
196
                    defaultStarts.add(EventMatcher.IRQ_ENTRY);
197
                    defaultEnds.add(EventMatcher.IRQ_EXIT);
198
                    defaultStarts.add(EventMatcher.READ);
199
                    defaultEnds.add(EventMatcher.WRITE);
200
                    defaultStarts.add(EventMatcher.OPEN);
201
                    defaultEnds.add(EventMatcher.CLOSE);
202
                    defaultStarts.add(EventMatcher.BUFFER_WAIT_START);
203
                    defaultEnds.add(EventMatcher.BUFFER_WAIT_END);
204
                    defaultStarts.add(EventMatcher.START_COMMIT);
205
                    defaultEnds.add(EventMatcher.END_COMMIT);
206
                    defaultStarts.add(EventMatcher.WAIT_ON_PAGE_START);
207
                    defaultEnds.add(EventMatcher.WAIT_ON_PAGE_END);
208
209
                    saveMatchPairs(defaultStarts, defaultEnds);
210
211
                    for (int i = 0; i < defaultStarts.size(); i++) {
212
                        EventMatcher.getInstance().addMatch(defaultStarts.get(i), defaultEnds.get(i));
213
                    }
214
215
                    // Get the list of start and end types from the EventMatcher
216
                    EventsPair pair = getMatchPairs();
217
                    fEventStartTypes = pair.getFirst();
218
                    fEventEndTypes = pair.getSecond();
219
220
                    for (int i = 0; i < fEventStartTypes.size(); i++) {
221
                        TableItem item = new TableItem(fTable, SWT.RIGHT);
222
223
                        String max = String.valueOf(fEventStartTypes.size());
224
                        String number = formatListNumber(i + 1, max.length());
225
226
                        String[] columns = { number, fEventStartTypes.get(i), fEventEndTypes.get(i) };
227
228
                        item.setText(columns);
229
                    }
230
231
                    fTable.setItemCount(fEventStartTypes.size());
232
233
                    fRedrawGraphs = true;
234
                }
235
            }
236
        });
237
238
        // Create the "Close" button
239
        Button closeButton = createButton(parent, CANCEL, Messages.LatencyView_Dialogs_ListEvents_Buttons_Close, false);
240
        closeButton.addListener(SWT.Selection, new Listener() {
241
            @Override
242
            public void handleEvent(Event event) {
243
                setReturnCode(CANCEL);
244
245
                if (fRedrawGraphs == true)
246
                    redrawGraphs();
247
248
                close();
249
            }
250
        });
251
    }
252
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/AbstractMouseListener.java (+80 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
13
14
import org.eclipse.swt.events.MouseEvent;
15
import org.eclipse.swt.events.MouseListener;
16
17
/**
18
 * <b><u>AbstractMouseListener</u></b>
19
 * <p>
20
 */
21
public abstract class AbstractMouseListener implements MouseListener {
22
23
    // ------------------------------------------------------------------------
24
    // Attributes
25
    // ------------------------------------------------------------------------
26
27
    /**
28
     * Mouse x-coordinate.
29
     */
30
    protected int fMouseX;
31
    
32
    /**
33
     * Mouse y-coordinate.
34
     */
35
    protected int fMouseY;
36
37
    // ------------------------------------------------------------------------
38
    // Constructors
39
    // ------------------------------------------------------------------------
40
41
    // ------------------------------------------------------------------------
42
    // Accessors
43
    // ------------------------------------------------------------------------
44
45
    // ------------------------------------------------------------------------
46
    // Operations
47
    // ------------------------------------------------------------------------
48
    
49
    /*
50
     * (non-Javadoc)
51
     * @see org.eclipse.swt.events.MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
52
     */
53
    @Override
54
    public void mouseDoubleClick(MouseEvent e) {
55
    }
56
57
    /*
58
     * (non-Javadoc)
59
     * @see org.eclipse.swt.events.MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
60
     */
61
    @Override
62
    public void mouseDown(MouseEvent e) {
63
        fMouseX = e.x;
64
        fMouseY = e.y;
65
        display();
66
    }
67
68
    /*
69
     * (non-Javadoc)
70
     * @see org.eclipse.swt.events.MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
71
     */
72
    @Override
73
    public void mouseUp(MouseEvent e) {
74
    }
75
    
76
    /**
77
     * Callback to display information at the current x-y position
78
     */
79
    protected abstract void display();
80
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/AbstractMouseTrackListener.java (+77 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors: 
10
 * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation 
11
 * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code
12
 * Bernd Hufmann - Changed implemented interface to MouseTraceListener
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
15
16
import org.eclipse.swt.events.MouseEvent;
17
import org.eclipse.swt.events.MouseTrackListener;
18
19
/**
20
 *  <b><u>AbstractMouseListener</u></b>
21
 * <p>
22
 * AbstractMouseListener, base class for the canvas mouse listener.
23
 * 
24
 * @author Philippe Sawicki
25
 */
26
public abstract class AbstractMouseTrackListener implements MouseTrackListener {
27
28
    // ------------------------------------------------------------------------
29
    // Attributes
30
    // ------------------------------------------------------------------------
31
32
    /**
33
     * Mouse x-coordinate.
34
     */
35
    protected int fMouseX;
36
    /**
37
     * Mouse y-coordinate.
38
     */
39
    protected int fMouseY;
40
41
    // ------------------------------------------------------------------------
42
    // Operations
43
    // ------------------------------------------------------------------------
44
45
    /*
46
     * (non-Javadoc)
47
     * @see org.eclipse.swt.events.MouseTrackListener#mouseEnter(org.eclipse.swt.events.MouseEvent)
48
     */
49
    @Override
50
    public void mouseEnter(MouseEvent event) {
51
    }
52
53
    /*
54
     * (non-Javadoc)
55
     * @see org.eclipse.swt.events.MouseTrackListener#mouseExit(org.eclipse.swt.events.MouseEvent)
56
     */
57
    @Override
58
    public void mouseExit(MouseEvent event) {
59
    }
60
61
    /*
62
     * (non-Javadoc)
63
     * @see org.eclipse.swt.events.MouseTrackListener#mouseHover(org.eclipse.swt.events.MouseEvent)
64
     */
65
    @Override
66
    public void mouseHover(MouseEvent event) {
67
        fMouseX = event.x;
68
        fMouseY = event.y;
69
        display();
70
    }
71
72
    /**
73
     * Tooltip display callback.
74
     */
75
    protected abstract void display();
76
77
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/AbstractPaintListener.java (+735 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design, display improvements
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
15
16
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
17
import org.eclipse.linuxtools.lttng.ui.views.latency.model.Config;
18
import org.eclipse.swt.SWT;
19
import org.eclipse.swt.events.PaintEvent;
20
import org.eclipse.swt.events.PaintListener;
21
import org.eclipse.swt.graphics.Color;
22
import org.eclipse.swt.graphics.Font;
23
import org.eclipse.swt.graphics.GC;
24
import org.eclipse.swt.graphics.Image;
25
import org.eclipse.swt.graphics.Point;
26
import org.eclipse.swt.graphics.Rectangle;
27
import org.eclipse.swt.widgets.Display;
28
29
/**
30
 * <b><u>AbstractPaintListener</u></b>
31
 * <p> 
32
 * Abstract paint listener. Draws the graphs on the view canvas.
33
 * 
34
 * @author Philippe Sawicki
35
 */
36
public abstract class AbstractPaintListener implements PaintListener {
37
38
    // ------------------------------------------------------------------------
39
    // Attributes
40
    // ------------------------------------------------------------------------
41
    
42
    /**
43
     *  Default colors and fonts
44
     */
45
    protected final Color DEFAULT_DATA_COLOR = new Color(Display.getDefault(), 74, 112, 139);
46
    protected final static Color DEFAULT_LABEL_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
47
    protected final static Color DEFAULT_TEXT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_DARK_GRAY);
48
    protected final static Color DEFAULT_DATA_BACKGROUND_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
49
    protected final static Color DEFAULT_CURRENT_EVENT_COLOR = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
50
51
    protected final Font DEFAULT_TITLE_FONT = new Font(Display.getDefault(), "Arial", 10, SWT.BOLD); //$NON-NLS-1$
52
    protected final Font DEFAULT_VALUES_FONT = new Font(Display.getDefault(), "Arial", 7, SWT.NORMAL); //$NON-NLS-1$
53
    protected final Font DEFAULT_LABEL_FONT = new Font(Display.getDefault(), "Arial", 8, SWT.NORMAL); //$NON-NLS-1$
54
    
55
    /**
56
     * A reference to the listener's view.
57
     */
58
    protected AbstractViewer fViewer;
59
60
    /**
61
     * Graph title
62
     */
63
    protected String fGraphTitle;
64
65
    /**
66
     * X-axis label.
67
     */
68
    protected String fXAxisLabel;
69
    
70
    /**
71
     * Y-axis label.
72
     */
73
    protected String fYAxisLabel;
74
75
    /**
76
     * Horizontal offset for the x-axis label.
77
     */
78
    protected int fXAxisLabelOffset;
79
80
    /**
81
     * Vertical offset for the horizontal axis offset.
82
     */
83
    protected int fHorizontalAxisYOffset = 20;
84
85
    /**
86
     * Graph padding.
87
     */
88
    protected int fPadding = Config.GRAPH_PADDING;
89
90
    /**
91
     * Graph client area.
92
     */
93
    protected Rectangle fClientArea = new Rectangle(0, 0, 1, 1);
94
95
    /**
96
     * Foreground color.
97
     */
98
    protected Color fForegroundColor;
99
    
100
    /**
101
     * Background color.
102
     */
103
    protected Color fBackgroundColor;
104
    
105
    /**
106
     * Data plotting color.
107
     */
108
    protected Color fDataColor;
109
    
110
    /**
111
     * Axis label color.
112
     */
113
    protected Color fLabelColor;
114
    
115
    /**
116
     * Text color.
117
     */
118
    protected Color fTextColor;
119
    
120
    /**
121
     * Data background color.
122
     */
123
    protected Color fDataBackgroundColor;
124
125
    /**
126
     * Color for current event time line.
127
     */
128
    protected Color fCurrentEventColor;
129
130
    /**
131
     * Original canvas font.
132
     */
133
    protected Font fOriginalFont;
134
135
    /**
136
     * Font for the title of the graph.
137
     */
138
    protected Font fTitleFont;
139
140
    /**
141
     * Font for the values on the horizontal and vertical axis.
142
     */
143
    protected Font fValuesFont;
144
145
    /**
146
     * Font for the horizontal and vertical labels.
147
     */
148
    protected Font fLabelFont;
149
150
    /**
151
     * Horizontal offset for the axis arrow.
152
     */
153
    protected final int ARROW_DELTA_X = 10;
154
155
    /**
156
     * Vertical offset for the axis arrow.
157
     */
158
    protected final int ARROW_DELTA_Y = 4;
159
160
    /**
161
     * Max horizontal distance between ticks.
162
     */
163
    protected final int MAX_WIDTH_BETWEEN_TICKS = 40;
164
165
    /**
166
     * Max vertical distance between ticks.
167
     */
168
    protected final int MAX_HEIGHT_BETWEEN_TICKS = 30;
169
170
    /**
171
     * Max characters that can be displayed on the vertical axis.
172
     */
173
    protected final int MAX_CHAR_VERTICAL_DISPLAY = 5;
174
175
    /**
176
     * Draw label each "drawLabelEachNTicks_" ticks.
177
     */
178
    protected int fDrawLabelEachNTicks = 1;
179
180
    /**
181
     * Image drawn on the canvas.
182
     */
183
    protected Image fImage;
184
185
    /**
186
     * Paint canvas, where the values are plotted.
187
     */
188
    protected GC fAxisImage;
189
190
    /**
191
     * Is the paint listener initialized ?
192
     */
193
    protected boolean fInitialized = false;
194
195
    /**
196
     * Draw area.
197
     */
198
    protected Rectangle fDrawArea;
199
200
    /**
201
     * Right padding (in pixels).
202
     */
203
    protected int fPaddingRight = Config.GRAPH_PADDING;
204
205
    /**
206
     * Top padding (in pixels).
207
     */
208
    protected int fPaddingTop = Config.GRAPH_PADDING;
209
210
    /**
211
     * Vertical axis offset (in pixels).
212
     */
213
    protected int fVerticalAxisOffset = 2 * Config.GRAPH_PADDING;
214
215
    /**
216
     * Vertical axis factor for values (10^delta). When values larger than MAX_CHAR_VERTICAL_DISPLAY.
217
     */
218
    protected int fDelta = 0;
219
220
    /**
221
     * The barWidth of a bar
222
     */
223
    protected int fBarWith = Config.DEFAULT_HISTOGRAM_BAR_WIDTH;
224
225
    /**
226
     * Minimum value on horizontal axis
227
     */
228
    protected long fXMin = -1;
229
230
    /**
231
     * Maximum value on horizontal axis
232
     */
233
    protected long fXMax = -1;
234
235
    /**
236
     * Minimum value on vertical axis
237
     */
238
    protected long fYMin = -1;
239
240
    /**
241
     * Maximum value on vertical axis
242
     */
243
    protected long fYMax = -1;
244
245
    // ------------------------------------------------------------------------
246
    // Constructors
247
    // ------------------------------------------------------------------------
248
    
249
    /**
250
     * Constructor.
251
     * @param view
252
     *            A reference to the listener's view.
253
     */
254
    public AbstractPaintListener(AbstractViewer view) {
255
        fViewer = view;
256
        fDataColor = DEFAULT_DATA_COLOR;
257
        fLabelColor = DEFAULT_LABEL_COLOR;
258
        fTextColor = DEFAULT_TEXT_COLOR;
259
        fDataBackgroundColor = DEFAULT_DATA_BACKGROUND_COLOR;
260
        fCurrentEventColor = DEFAULT_CURRENT_EVENT_COLOR;
261
        
262
        fTitleFont = DEFAULT_TITLE_FONT;
263
        fValuesFont = DEFAULT_VALUES_FONT;
264
        fLabelFont = DEFAULT_LABEL_FONT;
265
    }
266
267
    // ------------------------------------------------------------------------
268
    // Accessors
269
    // ------------------------------------------------------------------------
270
    
271
    /**
272
     * Returns the draw area height.
273
     * @return The draw area height.
274
     */
275
    public double getHeight() {
276
        return (fClientArea.height - 2.0 * fPadding - fHorizontalAxisYOffset - fPaddingTop);
277
    }
278
279
    /**
280
     * Returns the histogram's draw area width.
281
     * @return The histogram's draw area width.
282
     */
283
    public double getWidth() {
284
        return (fClientArea.width - 2.0 * fPadding - fVerticalAxisOffset - fPaddingRight);  // width of the plot area;
285
    }
286
287
    /**
288
     * Returns the histogram's draw area padding.
289
     * @return The histogram's draw area padding.
290
     */
291
    public int getPadding() {
292
        return fPadding;
293
    }
294
295
    /**
296
     * Returns the histogram's draw area top padding.
297
     * @return The histogram's draw area top padding.
298
     */
299
    public int getPaddingTop() {
300
        return fPaddingTop;
301
    }
302
303
    /**
304
     * Returns the histogram's vertical axis offset.
305
     * @return The histogram's vertical axis offset.
306
     */
307
    public int getVerticalAxisOffset() {
308
        return fVerticalAxisOffset;
309
    }
310
311
    /**
312
     * Returns the histogram's horizontal axis offset.
313
     * @return The histogram's horizontal axis offset.
314
     */
315
    public int getHorizontalAxisYOffset() {
316
        return fHorizontalAxisYOffset;
317
    }
318
319
    /**
320
     *  Returns the horizontal minimum value
321
     *  @return The horizontal minimum value.
322
     */
323
    public long getXMin() {
324
        return fXMin;
325
    }
326
327
    /**
328
     *  Returns the horizontal maximum value
329
     *  @return The horizontal maximum value.
330
     */
331
    public long getXMax() {
332
        return fXMax;
333
    }
334
335
    /**
336
     *  Returns the horizontal minimum value
337
     *  @return The horizontal minimum value.
338
     */
339
    public long getYMin() {
340
        return fYMin;
341
    }
342
343
    /**
344
     *  Returns the vertical maximum value
345
     *  @return The vertical maximum value.
346
     */
347
    public long getYMax() {
348
        return fYMax;
349
    }
350
    
351
    // ------------------------------------------------------------------------
352
    // Operations
353
    // ------------------------------------------------------------------------
354
    
355
    /**
356
     * Disposes local resources (e.g. colors or fonts)
357
     */
358
    public void dispose() {
359
        DEFAULT_DATA_COLOR.dispose();
360
        DEFAULT_TITLE_FONT.dispose();
361
        DEFAULT_VALUES_FONT.dispose();
362
        DEFAULT_LABEL_FONT.dispose();
363
    }
364
365
    /*
366
     * (non-Javadoc)
367
     * @see org.eclipse.swt.events.PaintListener#paintControl(org.eclipse.swt.events.PaintEvent)
368
     */
369
    @Override
370
    public void paintControl(PaintEvent e) {
371
        fClientArea = fViewer.getClientArea();
372
373
        fForegroundColor = e.gc.getForeground();
374
        fBackgroundColor = e.gc.getBackground();
375
        fOriginalFont = e.gc.getFont();
376
377
        scale();
378
        
379
        if (!fInitialized) {
380
            fImage = new Image(Display.getDefault(), fViewer.getBounds());
381
382
            fAxisImage = new GC(fImage);
383
384
            fAxisImage.setForeground(fForegroundColor);
385
            fAxisImage.setBackground(fBackgroundColor);
386
            fAxisImage.fillRectangle(fImage.getBounds());
387
388
            fInitialized = true;
389
        }
390
        
391
        paintGraphTitle();
392
        paintBackground();     
393
        paintHorizontalAxis();
394
        paintVerticalAxis();
395
        paintContent();
396
397
        e.gc.drawImage(fImage, 0, 0);
398
    }
399
400
    /**
401
     * Paints the title of the graph.
402
     */
403
    public void paintGraphTitle() {
404
        if (fGraphTitle != null) {
405
            fAxisImage.setFont(fTitleFont);
406
            fAxisImage.setForeground(fLabelColor);
407
            fAxisImage.setBackground(fBackgroundColor);
408
409
            int zoomFactor = fViewer.getZoomFactor() / fViewer.getZoomIncrement() + 1;
410
            int labelWidth = fAxisImage.stringExtent(fGraphTitle).x;
411
            // Draws the zoom factor in the title only if there is one
412
            if (fViewer.getZoomFactor() > 1)
413
                fAxisImage.drawText(fGraphTitle + " (" + zoomFactor + "x)", (fViewer.getBounds().width - fPadding - labelWidth) / 2, 0); //$NON-NLS-1$ //$NON-NLS-2$
414
            else
415
                fAxisImage.drawText(fGraphTitle, (fViewer.getBounds().width - fPadding - labelWidth) / 2, 0);
416
        }
417
    }
418
419
    /**
420
     * Paints the background of the draw area.
421
     */
422
    public void paintBackground() {
423
        fAxisImage.setBackground(fDataBackgroundColor);
424
425
        fAxisImage.fillRectangle(fPadding + fVerticalAxisOffset, fPadding + fPaddingTop, (int)getWidth() + 1, (int)getHeight());
426
    }
427
428
    /**
429
     * Paints the horizontal axis.
430
     */
431
    public void paintHorizontalAxis() {
432
        fAxisImage.setForeground(fForegroundColor);
433
434
        int y = fClientArea.height - fPadding - fHorizontalAxisYOffset;
435
436
        fAxisImage.drawLine(fClientArea.x + fPadding + fVerticalAxisOffset, y, fClientArea.width - fPadding, y);
437
438
        paintHorizontalArrow(fClientArea.width - fPadding, y);
439
        // Draw the axis graphic details only if there are some data points (i.e. do not draw the axis graphic details
440
        // if the window timerange is so small that no latency can be computed, or if there are no matching events in
441
        // the timerange (for example, when an experiment has many traces with a large time gap between the logged
442
        // events sets).
443
        if (fXMin != Long.MAX_VALUE && fXMax != Long.MIN_VALUE && fXMin != fXMax) {
444
            paintHorizontalTicks(y);
445
            paintHorizontalAxisValues(y + 30);
446
        }
447
        paintHorizontalAxisLabel(y + fHorizontalAxisYOffset - 5);
448
    }
449
450
    /**
451
     * Paints the vertical axis.
452
     */
453
    public void paintVerticalAxis() {
454
        fAxisImage.setForeground(fForegroundColor);
455
456
        int x = fClientArea.x + fPadding + fVerticalAxisOffset;
457
458
        fAxisImage.drawLine(x, fPadding, x, fClientArea.height - fPadding - fHorizontalAxisYOffset);
459
460
        paintVerticalArrow(x, fClientArea.y + fPadding);
461
        // Draw the axis graphic details only if there are some data points (i.e. do not draw the axis graphic details
462
        // if the window timerange is so small that no latency can be computed, or if there are no matching events in
463
        // the timerange (for example, when an experiment has many traces with a large time gap between the logged
464
        // events sets).
465
        if (fXMin != Long.MAX_VALUE && fXMax != Long.MIN_VALUE && fXMin != fXMax) {
466
            paintVerticalTicks(x);
467
            paintVerticalAxisValues(x);
468
        }
469
        paintVerticalAxisLabel(x);
470
    }
471
472
    /**
473
     * Paints the arrow on the horizontal axis.
474
     * @param x
475
     *            The x-coordinate of the point where the arrow points.
476
     * @param y
477
     *            The y-coordinate of the point where the arrow points.
478
     */
479
    public void paintHorizontalArrow(int x, int y) {
480
        // Arrow top line
481
        fAxisImage.drawLine(x - ARROW_DELTA_X, y - ARROW_DELTA_Y, x, y);
482
        // Arrow bottom line
483
        fAxisImage.drawLine(x - ARROW_DELTA_X, y + ARROW_DELTA_Y, x, y);
484
    }
485
486
    /**
487
     * Paints the arrow on the vertical axis.
488
     * @param x
489
     *            The x-coordinate of the point where the arrow points.
490
     * @param y
491
     *            The y-coordinate of the point where the arrow points.
492
     */
493
    public void paintVerticalArrow(int x, int y) {
494
        // Arrow left line
495
        fAxisImage.drawLine(x - ARROW_DELTA_Y, y + ARROW_DELTA_X, x, y);
496
        // Arrow right line
497
        fAxisImage.drawLine(x + ARROW_DELTA_Y, y + ARROW_DELTA_X, x, y);
498
    }
499
500
    /**
501
     * Paints the horizontal ticks.
502
     * @param y
503
     *            The y coordinate where to draw the axis.
504
     */
505
    public void paintHorizontalTicks(int y) {
506
        if (fXMin >= 0L && fXMin >= 0L) {
507
            int nbTicks = (int)(getWidth()) / MAX_WIDTH_BETWEEN_TICKS + 1;
508
509
            for (int i = 0; i < nbTicks; i++) {
510
                if (i % fDrawLabelEachNTicks == 0) {
511
                    int x = i * MAX_WIDTH_BETWEEN_TICKS + fPadding + fVerticalAxisOffset;
512
                    fAxisImage.drawLine(x, y, x, y + 3);
513
                }
514
            }
515
        }
516
    }
517
518
    /**
519
     * Paints the horizontal axis values.
520
     * @param y
521
     *            The y coordinate where to draw the axis.
522
     */
523
    public void paintHorizontalAxisValues(int y) {
524
        if (fXMin >= 0L && fXMax >= 0L) {
525
            fAxisImage.setForeground(fTextColor);
526
            fAxisImage.setBackground(fBackgroundColor);
527
528
            double width = getWidth();
529
            int nbTicks = ((int)getWidth()) / MAX_WIDTH_BETWEEN_TICKS + 1;
530
531
            for (int i = 0; i < nbTicks; i++) {
532
                if (i % fDrawLabelEachNTicks == 0) {
533
                    int x = i * MAX_WIDTH_BETWEEN_TICKS + fPadding + fVerticalAxisOffset;
534
                    
535
                    long currentValue = (i * MAX_WIDTH_BETWEEN_TICKS)* (long)((fXMax - fXMin) / width) + fXMin;
536
                    String currentLabel = formatStringForHorizontalAxis(currentValue);
537
538
                    fAxisImage.setFont(fValuesFont);
539
                    fAxisImage.drawText(currentLabel, x, y - 24);
540
                }
541
            }
542
        }
543
    }
544
545
    /**
546
     * Paints the horizontal axis label.
547
     * @param y
548
     *            The y-coordinate where to draw the label.
549
     */
550
    public void paintHorizontalAxisLabel(int y) {
551
        if (fXAxisLabel != null) {
552
            fAxisImage.setFont(fLabelFont);
553
            fAxisImage.setForeground(fLabelColor);
554
555
            int labelWidth = fAxisImage.stringExtent(fXAxisLabel).x;
556
557
            fAxisImage.drawText(fXAxisLabel, fClientArea.width - fPadding - labelWidth, y);
558
        }
559
    }
560
561
    /**
562
     * Paints the vertical axis ticks.
563
     * @param x
564
     *            The x-coordinate where to draw the ticks.
565
     */
566
    public void paintVerticalTicks(int x) {
567
        if (fYMin != 0L && fYMin != 0L) {
568
            int nbTicks = (int)(getHeight() / MAX_HEIGHT_BETWEEN_TICKS + 1);
569
570
            for (int i = 0; i < nbTicks; i++) {
571
                int y = fClientArea.height - fPadding - fHorizontalAxisYOffset - i * MAX_HEIGHT_BETWEEN_TICKS;
572
                fAxisImage.drawLine(x - 3, y, x, y);
573
            }
574
        }
575
    }
576
577
    /**
578
     * Paints the vertical axis values.
579
     * @param x
580
     *            The x-coordinate where to draw the values.
581
     */
582
    public void paintVerticalAxisValues(int x) {
583
        if (fYMin >= 0L && fYMax >= 0L) {
584
            fAxisImage.setForeground(fTextColor);
585
            fAxisImage.setBackground(fBackgroundColor);
586
587
            double height = getHeight();
588
            int nbTicks = (int)(height / MAX_HEIGHT_BETWEEN_TICKS + 1);
589
590
            // System.out.println("nbTicks = " + nbTicks);
591
592
            for (int i = 0; i < nbTicks; i++) {
593
                int y = fClientArea.height - fPadding - fHorizontalAxisYOffset - i * MAX_HEIGHT_BETWEEN_TICKS;
594
595
                long currentValue = (i * MAX_HEIGHT_BETWEEN_TICKS)* (long)((fYMax - fYMin) / height) + fYMin;
596
                String currentLabel = formatStringForVerticalAxis(currentValue);
597
598
                fAxisImage.setFont(fValuesFont);
599
600
                Point textDimensions = fAxisImage.stringExtent(currentLabel);
601
                fAxisImage.drawText(currentLabel, x - textDimensions.x - 5, y - textDimensions.y / 2);
602
            }
603
        }
604
    }
605
606
    /**
607
     * Increases the bar width. 
608
     */
609
    public void increaseBarWitdh() {
610
        fBarWith = fBarWith << 1;
611
        if (fBarWith > Config.MAX_HISTOGRAM_BAR_WIDTH) {
612
            fBarWith = Config.MAX_HISTOGRAM_BAR_WIDTH;
613
        }
614
    }
615
616
    /**
617
     * Decreases the bar width. 
618
     */
619
    public void decreaseBarWitdh() {
620
        fBarWith = fBarWith >> 1;
621
        if (fBarWith < Config.MIN_HISTOGRAM_BAR_WIDTH) {
622
            fBarWith = Config.MIN_HISTOGRAM_BAR_WIDTH; 
623
        }
624
    }
625
626
    
627
    /**
628
     * Paints the vertical axis label.
629
     * @param x
630
     *            The x-coordinate where to draw the label.
631
     */
632
    public void paintVerticalAxisLabel(int x) {
633
        if (fYAxisLabel != null) {
634
            fAxisImage.setFont(fLabelFont);
635
            fAxisImage.setForeground(fLabelColor);
636
            fAxisImage.setBackground(fBackgroundColor);
637
638
            if (fDelta >= 1)
639
                fAxisImage.drawText(fYAxisLabel + " (x10^" + fDelta + ")", x + 10, fHorizontalAxisYOffset - 5);  //$NON-NLS-1$//$NON-NLS-2$
640
            else
641
                fAxisImage.drawText(fYAxisLabel, x + 10, fPadding);
642
        }
643
    }
644
645
    /**
646
     * Adds points to the graph and draws them to the canvas.
647
     * @param points
648
     *            The buffer of points to draw.
649
     * @param nbPoints
650
     *            The number of points in the buffer.
651
     */
652
    abstract public String formatToolTipLabel(int x, int y);
653
654
    /**
655
     * Method to be implemented to scale the model data to the actual screen size.
656
     */
657
    abstract public void scale();
658
    
659
    /**
660
     * Called for drawing elements after points are added to the graph.
661
     */
662
    abstract public void paintContent();
663
664
    /**
665
     * Clears the image and prepares it for redrawing.
666
     */
667
    public void clear() {
668
        fInitialized = false;
669
        fXMin = -1;
670
        fXMax = -1;
671
        fYMin = -1;
672
        fYMax = -1;
673
    }
674
    
675
    /**
676
     * Draw horizontal label each "nbTicks" ticks.
677
     * @param nbTicks
678
     *            The draw interval.
679
     */
680
    public void setDrawLabelEachNTicks(int nbTicks) {
681
        fDrawLabelEachNTicks = nbTicks;
682
    }
683
684
    /**
685
     * Sets the title of the graph.
686
     * @param graphTitle
687
     *            The title of the graph.
688
     */
689
    public void setGraphTitle(String graphTitle) {
690
        fGraphTitle = graphTitle;
691
    }
692
693
    /**
694
     * Sets the horizontal axis label.
695
     * @param xAxisLabel
696
     *            The horizontal axis label.
697
     * @param offset
698
     *            The horizontal axis draw offset (in pixels).
699
     */
700
    public void setXAxisLabel(String xAxisLabel, int offset) {
701
        fXAxisLabel = xAxisLabel;
702
        fXAxisLabelOffset = offset;
703
    }
704
705
    /**
706
     * Sets the vertical axis label.
707
     * @param yAxisLabel
708
     *            The vertical axis label.
709
     */
710
    public void setYAxisLabel(String yAxisLabel) {
711
        fYAxisLabel = yAxisLabel;
712
    }
713
714
    /**
715
     * Returns a string representing the given value. 
716
     * 
717
     * @param value
718
     *            The numeric value to convert to String.
719
     * @return The String-formatted value.
720
     */
721
    public String formatStringForHorizontalAxis(long value) {
722
        return String.valueOf(value);
723
    }
724
725
    /**
726
     * Returns a string representing the given value. 
727
     * 
728
     * @param value
729
     *            The numeric value to convert to String.
730
     * @return The String-formatted value.
731
     */
732
    public String formatStringForVerticalAxis(long value) {
733
        return String.valueOf(value);
734
    }
735
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/GraphMouseListener.java (+70 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
13
14
import org.eclipse.linuxtools.lttng.ui.views.latency.GraphViewer;
15
import org.eclipse.linuxtools.lttng.ui.views.latency.model.LatencyGraphModel;
16
17
/**
18
 * <b><u>GraphMouseListener</u></b>
19
 * <p>
20
 */
21
public class GraphMouseListener extends AbstractMouseListener {
22
    
23
    // ------------------------------------------------------------------------
24
    // Attributes
25
    // ------------------------------------------------------------------------
26
27
    /**
28
     * A reference to the observed view.
29
     */
30
    protected GraphViewer fView;
31
32
    /**
33
     * A reference to the HistogramPaintListener.
34
     */
35
    protected GraphPaintListener fGraph;
36
37
    // ------------------------------------------------------------------------
38
    // Constructor
39
    // ------------------------------------------------------------------------
40
    
41
    /**
42
     * Constructor.
43
     * @param view
44
     *            A reference to the observed view.
45
     * @param histogramPaintListener
46
     *            A reference to the histogram's paintListener.
47
     */
48
    public GraphMouseListener(GraphViewer view, GraphPaintListener graphPaintListener) {
49
        fView = view;
50
        fGraph = graphPaintListener;
51
    }
52
53
    // ------------------------------------------------------------------------
54
    // Accessors
55
    // ------------------------------------------------------------------------
56
57
    // ------------------------------------------------------------------------
58
    // Operations
59
    // ------------------------------------------------------------------------
60
61
    /*
62
     * (non-Javadoc)
63
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractMouseListener#display()
64
     */
65
    @Override
66
    protected void display() {
67
        long currentTime = fGraph.getCurrentTimeFromHorizontalValue(fMouseX);
68
        ((LatencyGraphModel)fView.getModel()).setCurrentEventNotifyListeners(currentTime);
69
    }
70
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/GraphPaintListener.java (+227 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design, display improvements
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
15
16
import java.text.DecimalFormat;
17
18
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.BaseDistributionData;
19
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramUtils;
20
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
21
import org.eclipse.linuxtools.lttng.ui.views.latency.GraphViewer;
22
import org.eclipse.linuxtools.lttng.ui.views.latency.model.Config;
23
import org.eclipse.linuxtools.lttng.ui.views.latency.model.GraphScaledData;
24
import org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphDataModel;
25
26
/**
27
 * <b><u>GraphPaintListener</u></b>
28
 * <p>
29
 * Graph paint listener.
30
 * 
31
 * @author Philippe Sawicki
32
 */
33
public class GraphPaintListener extends AbstractPaintListener {
34
35
    // ------------------------------------------------------------------------
36
    // Attributes
37
    // ------------------------------------------------------------------------
38
39
    /**
40
     * Scaled data from data model
41
     */
42
    protected GraphScaledData fScaledData;
43
44
    // ------------------------------------------------------------------------
45
    // Constructors
46
    // ------------------------------------------------------------------------
47
48
    /**
49
     * Constructor.
50
     * @param viewer
51
     *            A reference to the listener's viewer.
52
     */
53
    public GraphPaintListener(AbstractViewer view) {
54
        super(view);
55
    }
56
57
    // ------------------------------------------------------------------------
58
    // Operations
59
    // ------------------------------------------------------------------------
60
61
    /*
62
     * (non-Javadoc)
63
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#scale()
64
     */
65
    @Override
66
    public void scale() {
67
         
68
         // width of the plot area
69
         double width = getWidth();
70
         // height of the plot area
71
         double height = getHeight();
72
73
         IGraphDataModel model = ((GraphViewer)fViewer).getModel();
74
         fScaledData = model.scaleTo((int)width, (int)height, fBarWith);
75
76
         fXMin = fScaledData.getHorFirstBucketTime() > 0 ? fScaledData.getHorFirstBucketTime() : 0;
77
         fXMax = 0;
78
         if (fScaledData.getHorLastBucket() > 0) {
79
             fXMax = fScaledData.getHorBucketEndTime(fScaledData.getHorNbBuckets() - 1);
80
         }
81
         
82
         fYMin = fScaledData.getVerFirstBucketTime() > 0 ? fScaledData.getVerFirstBucketTime() : 0;
83
         fYMax = 0;
84
         if (fScaledData.getVerLastBucket() > 0) {
85
             fYMax = fScaledData.getVerBucketEndTime(fScaledData.getVerNbBuckets() - 1);
86
         }
87
     }
88
    
89
    /*
90
     * (non-Javadoc)
91
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintContent()
92
     */
93
    @Override
94
    public void paintContent() {
95
        if (fXMin >= 0 && fXMax >= 0 && fYMin >= 0 && fYMax >= 0 && fScaledData != null) {
96
            
97
            fAxisImage.setForeground(fDataColor);
98
            fAxisImage.setBackground(fDataColor);
99
100
            double height = getHeight();
101
102
            int xLen = fScaledData.getHorNbBuckets();
103
            int yLen = fScaledData.getVerNbBuckets();
104
105
            int barWidth = fScaledData.getBarWidth();
106
            
107
            for (int i = 0; i < xLen; i++) {
108
                for (int j = 0; j < yLen; j++) {
109
                    if (fScaledData.getEventCount(i, j) > 0) {
110
111
                        double x = fPadding + i * barWidth + fVerticalAxisOffset + 1;
112
                        double y = fPadding + fPaddingTop + height - j * barWidth;
113
114
                        // Avoid over-drawing background area
115
                        int yBarWidth = fBarWith;
116
                        if (y - yBarWidth < fPadding + fPaddingTop) {
117
                            yBarWidth = (int) (y - fPadding - fPaddingTop);
118
                        }
119
                        int xBarWidth = fBarWith;
120
                        if(x + xBarWidth > fClientArea.width - fPadding - fPaddingRight) {
121
                            xBarWidth =  (int)(fClientArea.width - fPadding - fPaddingRight - x);    
122
                        }
123
                        fAxisImage.fillRectangle((int) x, (int) y - (int) yBarWidth, (int) xBarWidth, (int) yBarWidth);
124
                    }
125
                }
126
            }
127
            
128
            if (fScaledData.isCurrentEventTimeValid()) {
129
                // Draw vertical line
130
                int index = fScaledData.getHorBucketIndex(fScaledData.getCurrentEventTime());
131
132
                int x = fPadding + index * barWidth + fVerticalAxisOffset + 1;
133
                fAxisImage.setForeground(fCurrentEventColor);
134
                fAxisImage.setBackground(fCurrentEventColor);
135
                fAxisImage.drawLine(x, fPadding + fPaddingTop, x, fClientArea.height - fPadding - fHorizontalAxisYOffset);
136
            }
137
        }
138
    }
139
140
    /*
141
     * (non-Javadoc)
142
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#formatStringForVerticalAxis(long)
143
     */
144
    @Override
145
    public String formatStringForVerticalAxis(long value) {
146
        DecimalFormat formatter = new DecimalFormat("0.0E0"); //$NON-NLS-1$
147
        return formatter.format(value);
148
    }
149
    
150
    /*
151
     * (non-Javadoc)
152
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#formatStringForHorizontalAxis(long)
153
     */
154
    @Override
155
    public String formatStringForHorizontalAxis(long value) {
156
        return HistogramUtils.nanosecondsToString(value);
157
    }
158
    
159
    /*
160
     * (non-Javadoc)
161
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#formatToolTipLabel(int, int)
162
     */
163
    @Override
164
    public String formatToolTipLabel(int x, int y) {
165
166
        int index = getIndexFromHorizontalValue(x);
167
        int yIndex = getIndexFromVerticalValue(y);
168
169
        if (index != BaseDistributionData.OUT_OF_RANGE_BUCKET && yIndex != BaseDistributionData.OUT_OF_RANGE_BUCKET) {
170
            if (fScaledData.getEventCount(index, yIndex) > 0) {
171
                StringBuffer buffer = new StringBuffer();
172
                buffer.append("Time Range in s = ["); //$NON-NLS-1$
173
                // TODO change Utility
174
                long startTime = fScaledData.getHorBucketStartTime(index) > 0 ? fScaledData.getHorBucketStartTime(index) : 0;
175
                buffer.append(HistogramUtils.nanosecondsToString(startTime));
176
                buffer.append(","); //$NON-NLS-1$
177
                buffer.append(HistogramUtils.nanosecondsToString(fScaledData.getHorBucketEndTime(index)));
178
                buffer.append("]\n"); //$NON-NLS-1$
179
                buffer.append("Latency Range in s = ["); //$NON-NLS-1$
180
                long yStartTime = fScaledData.getVerBucketStartTime(yIndex) > 0 ? fScaledData.getVerBucketStartTime(yIndex) : 0;
181
                buffer.append(HistogramUtils.nanosecondsToString(yStartTime));
182
                buffer.append(","); //$NON-NLS-1$
183
                buffer.append(HistogramUtils.nanosecondsToString(fScaledData.getVerBucketEndTime(yIndex)));
184
                buffer.append("]\n"); //$NON-NLS-1$
185
                buffer.append("Latency count = "); //$NON-NLS-1$
186
                buffer.append(fScaledData.getEventCount(index, yIndex));
187
                return buffer.toString();
188
            }
189
        }
190
        return ""; //$NON-NLS-1$
191
    }
192
    
193
    public int getIndexFromHorizontalValue(int x) {
194
        if (fScaledData != null) {
195
            double barWidth = fScaledData.getBarWidth();
196
            
197
            int index = (int) ((x - fPadding - fVerticalAxisOffset - 1) / barWidth);
198
            if ((index >= 0) && (fScaledData.getHorNbBuckets() > index)) {
199
                return index;
200
            }
201
        }
202
        return BaseDistributionData.OUT_OF_RANGE_BUCKET;
203
    }
204
    
205
    public int getIndexFromVerticalValue(int y) {
206
        if (fScaledData != null) {
207
            double barWidth = fScaledData.getBarWidth();
208
            double height = getHeight();     // height of the plot area
209
            
210
            int index = (int) ((height - (y - fPadding - fPaddingTop)) / barWidth);
211
            if (index >= 0 && fScaledData.getVerNbBuckets() > index) {
212
                return index;
213
            }
214
        }
215
        return BaseDistributionData.OUT_OF_RANGE_BUCKET;
216
    }
217
218
    public long getCurrentTimeFromHorizontalValue(int x) {
219
        if (fXMin >= 0 && fXMax >= 0) {
220
            int index = getIndexFromHorizontalValue(x);
221
            if (index != BaseDistributionData.OUT_OF_RANGE_BUCKET) {
222
                return fScaledData.getHorBucketStartTime(index);
223
            }
224
        }
225
        return Config.INVALID_EVENT_TIME;
226
    }
227
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/HistogramPaintListener.java (+355 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Adapted to new model-view-controller design, display improvements
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
15
16
import java.text.DecimalFormat;
17
import java.util.Collections;
18
import java.util.Vector;
19
20
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramScaledData;
21
import org.eclipse.linuxtools.lttng.ui.views.histogram.HistogramUtils;
22
import org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramDataModel;
23
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
24
import org.eclipse.linuxtools.lttng.ui.views.latency.HistogramViewer;
25
import org.eclipse.linuxtools.lttng.ui.views.latency.Messages;
26
import org.eclipse.swt.graphics.Image;
27
import org.eclipse.swt.graphics.Point;
28
import org.eclipse.swt.widgets.Display;
29
import org.eclipse.ui.plugin.AbstractUIPlugin;
30
31
/**
32
 * <b><u>HistogramPaintListener</u></b>
33
 * <p>
34
 * Histogram paint listener.
35
 * 
36
 * @author Philippe Sawicki
37
 */
38
public class HistogramPaintListener extends AbstractPaintListener {
39
40
    // ------------------------------------------------------------------------
41
    // Attributes
42
    // ------------------------------------------------------------------------
43
    
44
    /**
45
     * Is a histogram bar so high that it is clipped from the draw area ?
46
     */
47
    private boolean fBarIsClipped = false;
48
49
    /**
50
     * Scaled data from data model
51
     */
52
    protected HistogramScaledData fScaledData;
53
54
    /**
55
     * Warning Image
56
     */
57
    protected Image fWarningImage;
58
59
    // ------------------------------------------------------------------------
60
    // Constructors
61
    // ------------------------------------------------------------------------
62
    
63
    /**
64
     * Constructor.
65
     * @param view
66
     *            A reference to the listener's viewer.
67
     */
68
    public HistogramPaintListener(AbstractViewer viewer) {
69
        super(viewer);
70
        fWarningImage = AbstractUIPlugin.imageDescriptorFromPlugin(Messages.LatencyView_tmf_UI, "icons/elcl16/warning.gif").createImage(Display.getCurrent()); //$NON-NLS-1$
71
    }
72
73
    // ------------------------------------------------------------------------
74
    // Accessors
75
    // ------------------------------------------------------------------------
76
    
77
    /**
78
     * Returns the histogram's bar Width.
79
     * @return The histogram's bar Width.
80
     */
81
    public int getBarWidth() {
82
        return fBarWith;
83
    }
84
    
85
    // ------------------------------------------------------------------------
86
    // Operations
87
    // ------------------------------------------------------------------------
88
    
89
    /*
90
     * (non-Javadoc)
91
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#dispose()
92
     */
93
    @Override
94
    public void dispose() {
95
        fWarningImage.dispose();
96
        super.dispose();
97
    }
98
99
    /*
100
     * (non-Javadoc)
101
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#scale()
102
     */
103
    @Override
104
    public void scale() {
105
        // width of the plot area
106
        double width = getWidth();
107
        // height of the plot area
108
        double height = getHeight();
109
110
        int barWidth = getBarWidth();
111
112
        IHistogramDataModel model = ((HistogramViewer)fViewer).getModel();
113
        fScaledData = model.scaleTo((int)width, (int)height, barWidth);
114
115
        fYMin = 0;
116
        fYMax = fScaledData.fMaxValue;
117
118
        fXMin = fScaledData.getFirstBucketTime();
119
        fXMin = fXMin > 0 ? fXMin : 0; 
120
        fXMax = fScaledData.getBucketEndTime(fScaledData.fLastBucket - 1);
121
122
        // No data to display - set end time to 0 
123
        if (fYMax == 0) {
124
            fXMax = 0;
125
        }
126
    }
127
128
    /*
129
     * (non-Javadoc)
130
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintVerticalTicks(int)
131
     */
132
    @Override
133
    public void paintVerticalTicks(int x) {
134
        // done in method paintVerticalAxisValues()
135
    }
136
    
137
    /*
138
     * (non-Javadoc)
139
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintVerticalAxisValues(int)
140
     */
141
    @Override
142
    public void paintVerticalAxisValues(int x) {
143
        int zoomFactor = 1;
144
145
        zoomFactor = fViewer.getZoomFactor();
146
147
        if (fYMin >= 0L && fYMax != 0L) {
148
            fAxisImage.setForeground(fTextColor);
149
            fAxisImage.setBackground(fBackgroundColor);
150
151
            // Apply the zoom to the max value of the graph for the next calculations
152
            long yMax = fYMax / zoomFactor;
153
154
            int nbTicks = ((int)getHeight()) / MAX_HEIGHT_BETWEEN_TICKS + 1;
155
156
            Vector<Integer> values = new Vector<Integer>();
157
            boolean multipleSameValues = true;
158
            while (multipleSameValues) {
159
                double valueStep = (double) (yMax - fYMin) / (double) (nbTicks);
160
161
                for (int i = 0; i < nbTicks; i++) {
162
                    double currentValue = (double) (fYMin + i * valueStep) / (Math.pow(10, fDelta));
163
164
                    values.add((int) currentValue);
165
                }
166
167
                Collections.sort(values);
168
                boolean hasRepetition = false;
169
                for (int i = 1; i < values.size(); i++) {
170
                    if (values.get(i) == values.get(i - 1)) {
171
                        hasRepetition = true;
172
                        break;
173
                    }
174
                }
175
176
                if (hasRepetition) {
177
                    nbTicks--;
178
                    values.clear();
179
                } else {
180
                    multipleSameValues = false;
181
182
                    // Draw rectangle over the old values
183
                    int height = fViewer.getBounds().height - 2 * fPadding - fPaddingTop - fHorizontalAxisYOffset;
184
                    fAxisImage.fillRectangle(0, fPadding + fPaddingTop, fPadding + fVerticalAxisOffset, height);
185
186
                    double pixelStep = (getHeight()) / values.size() + 1;
187
188
                    for (int i = 0; i < values.size(); i++) {
189
                        double currentValue = values.get(i);
190
191
                        int y = (int)  (fClientArea.height - fPadding - fHorizontalAxisYOffset -  i * pixelStep);
192
                        String currentLabel = formatStringForVerticalAxis((long) currentValue);
193
194
                        fAxisImage.setFont(fValuesFont);
195
196
                        Point textDimensions = fAxisImage.stringExtent(currentLabel);
197
                        fAxisImage.drawText(currentLabel, x - textDimensions.x - 5, y - textDimensions.y / 2);
198
                        fAxisImage.drawLine(x - 3, y, x, y);
199
                    }
200
                }
201
            }
202
        }
203
    }
204
205
    /*
206
     * (non-Javadoc)
207
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#paintContent()
208
     */
209
    @Override
210
    public void paintContent() {
211
        double zoomFactor = fViewer.getZoomFactor();
212
213
        // Calculate the vertical axis factor and see if it has changed
214
        double tmpDelta = fDelta;
215
        fDelta = 0;
216
        if (Long.toString(fYMax / (long) zoomFactor).length() > MAX_CHAR_VERTICAL_DISPLAY) {
217
            fDelta = Long.toString(fYMax / (long) zoomFactor).length() - MAX_CHAR_VERTICAL_DISPLAY;
218
        }
219
        if (tmpDelta != fDelta) {
220
            fViewer.clearBackground();
221
        }
222
223
        paintBackground();
224
        paintVerticalAxis();
225
        paintHorizontalAxis();
226
227
        fAxisImage.setForeground(fDataColor);
228
        fAxisImage.setBackground(fDataColor);
229
230
        // height of the plot area
231
        double height = getHeight();
232
233
        int barWidth = getBarWidth();
234
        
235
        // axisImage_.setBackground(backgroundColor_);
236
        // 1.a Iterate over the points, from 0 to nbPoints
237
        // 1.b Find the max counter value
238
        // 2. Assign the max value to the "yMax_" class attribute
239
        // 3. Draw the histogram bars using "axisImage_.fillRectangle(...)"
240
        boolean oneBarIsClipped = false;
241
242
        for (int i = 0; i < fScaledData.fData.length; i++) {
243
            double pointY = fScaledData.fData[i];
244
245
            // in pixels
246
            double x = fPadding + i * barWidth + fVerticalAxisOffset + 1;
247
248
            if (i == fScaledData.fData.length - 1)
249
                x -= 1.0;
250
            double barHeight = zoomFactor * ((double)(pointY - fYMin) / (double)(fYMax - fYMin)) * height;
251
252
            if (barHeight > height + 1) {
253
                barHeight = height;
254
                oneBarIsClipped = true;
255
256
                fAxisImage.drawImage(fWarningImage, 5, 3);
257
            }
258
259
            // Only draw the bars that have a barHeight of more than 1 pixel
260
            if (barHeight > 0) {
261
                double y = fPadding + fPaddingTop + height - barHeight;
262
                fAxisImage.setBackground(fDataColor);
263
264
                if (barHeight > height - 1) {
265
                    fAxisImage.fillRectangle((int) x, (int) y, (int) barWidth, (int) (barHeight + 1));
266
                } else {
267
                    fAxisImage.fillRectangle((int) x, (int) y, (int) barWidth, (int) (barHeight + 2));
268
                }
269
            }
270
        }
271
272
        if (oneBarIsClipped)
273
            fBarIsClipped = true;
274
        else
275
            fBarIsClipped = false;
276
    }
277
    
278
    /**
279
     * Paints the histogram horizontal axis values in engineering notation in which the exponent is a multiple of three.
280
     * @param value
281
     *            The numeric value to convert to engineering notation.
282
     * @return The given value formatted according to the engineering notation.
283
     */
284
    @Override
285
    public String formatStringForHorizontalAxis(long value) {
286
        DecimalFormat formatter = new DecimalFormat("##0.#E0"); //$NON-NLS-1$
287
        return formatter.format(value);
288
    }
289
290
    /**
291
     * Sets the bar width.
292
     * @param barWidth 
293
     *            bar width to set
294
     */
295
    public void setBarWidth(int barWidth) {
296
        fBarWith = barWidth;
297
    }
298
    
299
    /**
300
     * Returns "true" if a histogram bar is so high that it cannot be drawn in the draw area, "false" otherwise.
301
     * @return "true" if a histogram bar is so high that it cannot be drawn in the draw area, "false" otherwise.
302
     */
303
    public boolean barIsClipped() {
304
        return fBarIsClipped;
305
    }
306
    
307
    /*
308
     * (non-Javadoc)
309
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractPaintListener#formatToolTipLabel(int, int)
310
     */
311
    @Override
312
    public String formatToolTipLabel(int x, int y) {
313
        if (fScaledData != null) {
314
315
            double barWidth = getBarWidth();
316
            double height = getHeight();     // height of the plot area
317
            
318
            double zoomFactor = fViewer.getZoomFactor();
319
320
            int index = (int) ((x - fPadding - fVerticalAxisOffset - 1) / barWidth);
321
322
            double barHeight = 0.0;
323
            if (index >= 0 && index <= fScaledData.fLastBucket) {
324
                barHeight = (zoomFactor * height * (fScaledData.fData[index] - fYMin) / (fYMax - fYMin));
325
            }
326
327
            long fMouseY = (long) (height - (y - fPadding - fPaddingTop));
328
329
            // Verifying mouse pointer is over histogram bar
330
            if (index >= 0 && fScaledData.fLastBucket >= index && fMouseY >= 0 && fMouseY < barHeight && fMouseY < height && x >= (fVerticalAxisOffset + fPadding)) {
331
332
                fScaledData.fCurrentBucket = index;
333
334
                long startTime = fScaledData.getBucketStartTime(index);
335
                // negative values are possible if time values came into the model in decreasing order
336
                if (startTime < 0) {
337
                    startTime = 0;
338
                }
339
                long endTime = fScaledData.getBucketEndTime(index);
340
                int nbEvents = fScaledData.fData[index];
341
342
                StringBuffer buffer = new StringBuffer();
343
                buffer.append("Latency Range in s = ["); //$NON-NLS-1$
344
                buffer.append(HistogramUtils.nanosecondsToString(startTime));
345
                buffer.append(","); //$NON-NLS-1$
346
                buffer.append(HistogramUtils.nanosecondsToString(endTime));
347
                buffer.append("]\n"); //$NON-NLS-1$
348
                buffer.append("Latency count = "); //$NON-NLS-1$
349
                buffer.append(nbEvents);
350
                return buffer.toString();
351
            }
352
        }
353
        return ""; //$NON-NLS-1$
354
    }
355
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/TimePointerListener.java (+69 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *   Bernd Hufmann - Changed display interface implementation 
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
15
16
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
17
18
/**
19
 * <b><u>TimePointerListener</u></b>
20
 * <p>
21
 * Displays a tooltip showing the approximate values of the point under the mouse cursor.
22
 * 
23
 * @author Philippe Sawicki
24
 */
25
public class TimePointerListener extends AbstractMouseTrackListener {
26
27
    // ------------------------------------------------------------------------
28
    // Attributes
29
    // ------------------------------------------------------------------------
30
31
    /**
32
     * A reference to the observed view.
33
     */
34
    protected AbstractViewer fView;
35
36
    /**
37
     * A reference to the HistogramPaintListener.
38
     */
39
    protected GraphPaintListener fGraph;
40
41
    // ------------------------------------------------------------------------
42
    // Constructors
43
    // ------------------------------------------------------------------------
44
    
45
    /**
46
     * Constructor.
47
     * @param view
48
     *            A reference to the observed view.
49
     * @param histogramPaintListener
50
     *            A reference to the histogram's paintListener.
51
     */
52
    public TimePointerListener(AbstractViewer view, GraphPaintListener graphPaintListener) {
53
        fView = view;
54
        fGraph = graphPaintListener;
55
    }
56
57
    // ------------------------------------------------------------------------
58
    // Operations
59
    // ------------------------------------------------------------------------
60
61
    /*
62
     * (non-Javadoc)
63
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractMouseTrackListener#display()
64
     */
65
    @Override
66
    protected void display() {
67
        fView.setToolTipText(fGraph.formatToolTipLabel(fMouseX, fMouseY));
68
    }
69
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/TooltipListener.java (+100 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation
11
 *   Bernd Hufmann - Changed display interface implementation
12
 *******************************************************************************/
13
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
14
15
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
16
import org.eclipse.linuxtools.lttng.ui.views.latency.Messages;
17
18
/**
19
 * <b><u>TooltipListener</u></b>
20
 * <p>
21
 * Tooltip listener, displays the event count for each latency selected by the mouse click area on histogram.
22
 * 
23
 * @author Ali Jawhar
24
 */
25
public class TooltipListener extends AbstractMouseTrackListener {
26
27
    // ------------------------------------------------------------------------
28
    // Attributes
29
    // ------------------------------------------------------------------------
30
31
    /**
32
     * A reference to the observed view.
33
     */
34
    protected AbstractViewer fView;
35
36
    /**
37
     * A reference to the HistogramPaintListener.
38
     */
39
    protected HistogramPaintListener fHistogram;
40
41
    /**
42
     * Is the mouse over the warning icon, indicating that a bar is higher than the draw area due to zooming ?
43
     */
44
    protected boolean fDisplayWarning = false;
45
46
    // ------------------------------------------------------------------------
47
    // Constructors
48
    // ------------------------------------------------------------------------
49
    
50
    /**
51
     * Constructor.
52
     * @param view
53
     *            A reference to the observed view.
54
     * @param histogramPaintListener
55
     *            A reference to the histogram's paintListener.
56
     */
57
    public TooltipListener(AbstractViewer view, HistogramPaintListener histogramPaintListener) {
58
        fView = view;
59
        fHistogram = histogramPaintListener;
60
    }
61
62
    // ------------------------------------------------------------------------
63
    // Operations
64
    // ------------------------------------------------------------------------
65
66
    /*
67
     * (non-Javadoc)
68
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.listeners.AbstractMouseTrackListener#display()
69
     */
70
    @Override
71
    protected void display() {
72
        displayWarningTooltip();
73
        displayTooltip();
74
    }
75
76
    // ------------------------------------------------------------------------
77
    // Helper Functions
78
    // ------------------------------------------------------------------------
79
    
80
    /**
81
     * Displays a tooltip if the mouse is over the warning icon indication that a bar cannot be draw entirely due to the
82
     * zoom factor.
83
     */
84
    protected void displayWarningTooltip() {
85
        if (fHistogram.barIsClipped() && fMouseX > 5 && fMouseX < 21 && fMouseY > 3 && fMouseY < 18) {
86
            fView.setToolTipText(Messages.LatencyView_ClippingWarning);
87
            fDisplayWarning = true;
88
        } else {
89
            fDisplayWarning = false;
90
        }
91
    }
92
93
    /**
94
     * Displays the tooltip showing the details of the histogram bar pointed by the mouse.
95
     */
96
    protected void displayTooltip() {
97
        if (!fDisplayWarning)
98
            fView.setToolTipText(fHistogram.formatToolTipLabel(fMouseX, fMouseY));
99
    }
100
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/listeners/ZoomListener.java (+134 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactored code
12
 *******************************************************************************/
13
package org.eclipse.linuxtools.lttng.ui.views.latency.listeners;
14
15
import org.eclipse.linuxtools.lttng.ui.views.latency.AbstractViewer;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.widgets.Canvas;
18
import org.eclipse.swt.widgets.Event;
19
import org.eclipse.swt.widgets.Listener;
20
21
/**
22
 * <b><u>ZoomListener</u></b>
23
 * <p>
24
 * 
25
 * Canvas zoom listener.
26
 * 
27
 * @author Philippe Sawicki
28
 */
29
public class ZoomListener implements Listener {
30
31
    // ------------------------------------------------------------------------
32
    // Attributes
33
    // ------------------------------------------------------------------------
34
35
    /**
36
     * A reference to the observed view.
37
     */
38
    protected AbstractViewer fView;
39
    /**
40
     * Default zoom factor.
41
     */
42
    protected int fZoomFactor;
43
    /**
44
     * Zoom increment.
45
     */
46
    protected int fZoomIncrement = 30;
47
48
    // ------------------------------------------------------------------------
49
    // Constructors
50
    // ------------------------------------------------------------------------
51
52
    /**
53
     * Constructor.
54
     * @param view
55
     *            A reference to the observed view.
56
     * @param defaultZoomFactor
57
     *            Default zoom factor.
58
     */
59
    public ZoomListener(AbstractViewer view, int defaultZoomFactor) {
60
        fView = view;
61
        fZoomFactor = defaultZoomFactor;
62
    }
63
64
    /**
65
     * Constructor.
66
     * @param view
67
     *            A reference to the observed view.
68
     */
69
    public ZoomListener(AbstractViewer view) {
70
        this(view, 1);
71
    }
72
73
    // ------------------------------------------------------------------------
74
    // Accessors
75
    // ------------------------------------------------------------------------
76
77
    /**
78
     * Returns the zoom factor.
79
     * @return The zoom factor.
80
     */
81
    public int getZoomFactor() {
82
        if (fZoomFactor < 1)
83
            return 1;
84
        else
85
            return fZoomFactor;
86
    }
87
88
    /**
89
     * Returns the zoom increment.
90
     * @return The zoom increment.
91
     */
92
    public int getZoomIncrement() {
93
        return fZoomIncrement;
94
    }
95
    
96
    // ------------------------------------------------------------------------
97
    // Operations
98
    // ------------------------------------------------------------------------
99
    
100
    /*
101
     * (non-Javadoc)
102
     * @see org.eclipse.swt.widgets.Listener#handleEvent(org.eclipse.swt.widgets.Event)
103
     */
104
    @Override
105
    public void handleEvent(Event event) {
106
        switch (event.type) {
107
            case SWT.MouseWheel:
108
                boolean scrollDown = (event.count == 0 ? false : (event.count > 0 ? false : true));
109
                int zoomStep = fZoomIncrement;
110
                if (scrollDown)
111
                    zoomStep = -fZoomIncrement;
112
                fZoomFactor = Math.max(0, fZoomFactor + zoomStep);
113
114
                Canvas canvas = (Canvas) event.widget;
115
                if (fView != null) {
116
                    // clear the background to allow redraw of values of the vertical axis.
117
                    fView.clearBackground();
118
                    fView.redrawTitle();
119
                    fView.askForRedraw();
120
                }
121
                canvas.redraw();
122
                break;
123
        }
124
    }
125
126
    /**
127
     * Sets the zoom increment.
128
     * @param zoomIncrement
129
     *            The new zoom increment.
130
     */
131
    public void setZoomIncrement(int zoomIncrement) {
132
        fZoomIncrement = zoomIncrement;
133
    }
134
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/messages.properties (+59 lines)
Added Link Here
1
#*******************************************************************************
2
# Copyright (c) 2011 Ericsson
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
# Contributors:
10
#   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
#   Bernd Hufmann - Updated and added properties    
12
# *******************************************************************************/
13
14
LatencyView_ViewName=LatencyView
15
LatencyView_Action_IncreaseBarWidth_Tooltip=Increase bar width/height
16
LatencyView_Action_DecreaseBarWidth_Tooltip=Decrease bar width/height
17
LatencyView_Action_AddEvents_Tooltip=Add matching events
18
LatencyView_Action_DeleteEvents_Tooltip=Delete matching events
19
LatencyView_Action_ListEvents_Tooltip=List matching events
20
LatencyView_Dialogs_AddEvents_Title=Add event pairs
21
LatencyView_Dialogs_AddEvents_Message=Select a pair of events to add it to the match list :
22
LatencyView_Dialogs_AddEvents_Buttons_Add=Add
23
LatencyView_Dialogs_AddEvents_Buttons_Close=Close
24
LatencyView_Dialogs_AddEvents_Columns_Start=Start event types
25
LatencyView_Dialogs_AddEvents_Columns_End=End event types
26
LatencyView_Dialogs_AddEvents_Columns_List_Trigger=Trigger event type
27
LatencyView_Dialogs_AddEvents_Columns_List_End=End event type
28
LatencyView_Dialogs_AddEvents_Errors_NoSelection=You must select one item from both lists_
29
LatencyView_Dialogs_AddEvents_Errors_StartNotSelected=You must select one item from the start event list_
30
LatencyView_Dialogs_AddEvents_Errors_EndNotSelected=You must select one item from the end event list_
31
LatencyView_Dialogs_AddEvents_Errors_SameSelected=The same event cannot be selected in both list at the same time_
32
LatencyView_Dialogs_AddEvents_Errors_AlreadyMatched=The start and end events are already matched_
33
LatencyView_Dialogs_AddEvents_Errors_StartAlreadyMatched=The start event is already matched_
34
LatencyView_Dialogs_AddEvents_Errors_EndAlreadyMatched=The end event is already matched_
35
LatencyView_Dialogs_AddEvents_Errors_StartAsEnd=The start event is already matched as an end event_
36
LatencyView_Dialogs_AddEvents_Errors_EndAsStart=The end event is already matched as a start event_
37
LatencyView_Dialogs_DeleteEvents_Title=Delete event pairs
38
LatencyView_Dialogs_DeleteEvents_Message=Select a pair of matched events to remove it from the list :
39
LatencyView_Dialogs_DeleteEvents_Buttons_Close=Close
40
LatencyView_Dialogs_DeleteEvents_Buttons_Delete=Delete
41
LatencyView_Dialogs_DeleteEvents_Confirm_Title=Confirm event deletion
42
LatencyView_Dialogs_DeleteEvents_Confirm_Message=Are you sure you want to delete these event pairs?
43
LatencyView_Dialogs_ListEvents_Title=Matched events list
44
LatencyView_Dialogs_ListEvents_Message=List of matched events for latency computation :
45
LatencyView_Dialogs_ListEvents_Buttons_Close=Close
46
LatencyView_Dialogs_ListEvents_Buttons_Reset=Reset to default pairs
47
LatencyView_Dialogs_ListEvents_Columns_Trigger=Trigger event type
48
LatencyView_Dialogs_ListEvents_Columns_End=End event type
49
LatencyView_Dialogs_ListEvents_Confirm_Title=Confirm pairs reset
50
LatencyView_Dialogs_ListEvents_Confirm_Message=Are you sure you want to reset the event pairs to their default values?
51
LatencyView_Graphs_Graph_Title=Latency vs Time
52
LatencyView_Graphs_Graph_XAxisLabel=time (s)
53
LatencyView_Graphs_Graph_YAxisLabel=latency (ms)
54
LatencyView_Graphs_Histogram_Title=Latency Distribution
55
LatencyView_Graphs_Histogram_XAxisLabel=latency (ms)
56
LatencyView_Graphs_Histogram_YAxisLabel=# events
57
LatencyView_msgSlogan=Latency View
58
LatencyView_tmf_UI=org.eclipse.linuxtools.lttng.ui
59
LatencyView_ClippingWarning=One or more bars are higher than the drawing area due to zooming
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/Config.java (+76 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2010, 2011 Ericsson
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
 * Contributors:
10
 *   Philippe Sawicki (INF4990.A2010@gmail.com)   - Initial API and implementation
11
 *   Mathieu Denis    (mathieu.denis55@gmail.com) - Refactor code
12
 *   Bernd Hufmann - Added and updated constants
13
 *******************************************************************************/
14
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
15
16
/**
17
 * <b><u>Config</u></b>
18
 * <p>
19
 * Configuration class, holds some application constants.
20
 * 
21
 * @author Philippe Sawicki
22
 */
23
public class Config {
24
25
    /**
26
     * Private constructor to defeat instantiation.
27
     */
28
    private Config() {
29
    }
30
31
    /**
32
     * Time scale for TMF events;
33
     */
34
    public static byte TIME_SCALE = -9;
35
    
36
    /**
37
     * Size of the point buffer holding point values before sending them to the view.
38
     */
39
    public static final int POINT_BUFFER_SIZE = 10000;
40
41
    /**
42
     * Histogram bar width.
43
     */
44
    public static final int DEFAULT_HISTOGRAM_BAR_WIDTH = 2;
45
    
46
    /**
47
     * Histogram bar width increase step.
48
     */
49
    public static final int MIN_HISTOGRAM_BAR_WIDTH = 1;
50
51
    /**
52
     * Histogram bar width increase step.
53
     */
54
    public static final int MAX_HISTOGRAM_BAR_WIDTH = 16;
55
56
    
57
    /**
58
     * Diameter of a point drawn on the chart (in pixels).
59
     */
60
    public static final int GRAPH_POINT_DIAMETER = 1;
61
62
    /**
63
     * Graph padding.
64
     */
65
    public static final int GRAPH_PADDING = 10;
66
67
    /**
68
     * Default number of buckets used in data models
69
     */
70
    public static final int DEFAULT_NUMBER_OF_BUCKETS = 2 * 1000;
71
    
72
    /**
73
     * Invalid event time
74
     */
75
    public static final long INVALID_EVENT_TIME = -1;
76
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/GraphScaledData.java (+246 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
13
14
/**
15
 * <b><u>GraphScaledData</u></b>
16
 * Convenience class for scaled distribution data.  
17
 * <p>
18
 */
19
import java.util.Arrays;
20
21
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.BaseDistributionData;
22
23
public class GraphScaledData {
24
25
    // ------------------------------------------------------------------------
26
    // Attributes
27
    // ------------------------------------------------------------------------
28
29
    private int fWidth;
30
    private int fHeight;
31
    private int fBarWidth;
32
    private int[][] fData;
33
    private BaseDistributionData fHorDistributionData;
34
    private BaseDistributionData fVerDistributionData;
35
    private long fCurrentEventTime;
36
37
    // ------------------------------------------------------------------------
38
    // Constructor
39
    // ------------------------------------------------------------------------
40
41
    public GraphScaledData(int width, int height, int barWidth) {
42
        fWidth = width;
43
        fHeight = height;
44
        fBarWidth = barWidth;
45
        int horNbBuckets = (int)width/barWidth;
46
        int verNbBuckets = (int)height/barWidth; 
47
        fData = new int[horNbBuckets][verNbBuckets];
48
        for (int[] row : fData) {
49
            Arrays.fill(row, 0);    
50
        }
51
        fHorDistributionData = new BaseDistributionData(horNbBuckets);
52
        fHorDistributionData.clear();
53
        
54
        fVerDistributionData = new BaseDistributionData(verNbBuckets);
55
        fVerDistributionData.clear();
56
        
57
        fCurrentEventTime = Config.INVALID_EVENT_TIME;
58
    }
59
60
    // ------------------------------------------------------------------------
61
    // Accessors
62
    // ------------------------------------------------------------------------
63
64
    public int getWidth() {
65
        return fWidth;
66
    }
67
68
    public int getHeight() {
69
        return fHeight;
70
    }
71
72
    public int getBarWidth() {
73
        return fBarWidth;
74
    }
75
76
    public int[][] getData() {
77
        return fData;
78
    }
79
80
    public int getHorNbBuckets() {
81
        return fHorDistributionData.getNbBuckets();
82
    }
83
    
84
    public int getVerNbBuckets() {
85
        return fVerDistributionData.getNbBuckets();
86
    }
87
88
    public long getHorFirstBucketTime() {
89
        return fHorDistributionData.getFirstBucketTime();
90
    }
91
92
    public long getVerFirstBucketTime() {
93
        return fVerDistributionData.getFirstBucketTime();
94
    }
95
96
    public long getHorLastBucketTime() {
97
        return fHorDistributionData.getLastBucketTime();
98
    }
99
100
    public long getVerLastBucketTime() {
101
        return fVerDistributionData.getLastBucketTime();
102
    }
103
    
104
    public long getHorFirstEventTime() {
105
        return fHorDistributionData.getFirstEventTime();
106
    }
107
108
    public long getVerFirstEventTime() {
109
        return fVerDistributionData.getFirstEventTime();
110
    }
111
112
    public long getHorLastEventTime() {
113
        return fHorDistributionData.getLastEventTime();
114
    }
115
116
    public long getVerLastEventTime() {
117
        return fVerDistributionData.getLastEventTime();
118
    }
119
    
120
    public long getHorBucketDuration() {
121
        return fHorDistributionData.getBucketDuration();
122
    }
123
124
    public long getVerBucketDuration() {
125
        return fVerDistributionData.getBucketDuration();
126
    }
127
128
    public int getHorLastBucket() {
129
        return fHorDistributionData.getLastBucket();
130
    }
131
132
    public int getVerLastBucket() {
133
        return fVerDistributionData.getLastBucket();
134
    }
135
136
    public long getHorBucketStartTime(int index) {
137
        return  fHorDistributionData.getBucketStartTime(index);
138
    }
139
    
140
    public long getHorBucketEndTime(int index) {
141
        return fHorDistributionData.getBucketEndTime(index);
142
    }
143
    
144
    public long getVerBucketStartTime(int index) {
145
        return  fVerDistributionData.getBucketStartTime(index);
146
    }
147
    
148
    public long getVerBucketEndTime(int index) {
149
        return fVerDistributionData.getBucketEndTime(index);
150
    }
151
    
152
    public int getEventCount(int horIndex, int verIndex) {
153
        return fData[horIndex][verIndex];
154
    }
155
    
156
    public long getCurrentEventTime() {
157
        return fCurrentEventTime;
158
    }
159
160
    public boolean isCurrentEventTimeValid() {
161
        if (fCurrentEventTime == Config.INVALID_EVENT_TIME || fCurrentEventTime < getHorFirstEventTime() || fCurrentEventTime > getHorLastEventTime()) {
162
            return false;
163
        }
164
        return true;
165
    }
166
    
167
    public int getHorBucketIndex(long time) {
168
         return fHorDistributionData.getIndex(time);
169
    }
170
    
171
    public int getVerBucketIndex(long time) {
172
        return fVerDistributionData.getIndex(time);
173
    }
174
    
175
    public boolean isHorIndexValid(int index) {
176
        return fHorDistributionData.isIndexValid(index);
177
    }
178
    
179
    public boolean isVerIndexValid(int index) {
180
        return fVerDistributionData.isIndexValid(index);
181
    }
182
183
    // ------------------------------------------------------------------------
184
    // Operations
185
    // ------------------------------------------------------------------------
186
187
    public void setWidth(int width) {
188
        fWidth = width;
189
    }
190
191
    public void setHeight(int height) {
192
        fHeight = height;
193
    }
194
    
195
    public void setBarWidth(int barWidth) {
196
        fBarWidth = barWidth;
197
    }
198
199
    public void setData(int[][] data) {
200
        fData = data;
201
    }
202
203
    public void setHorFirstBucketTime(long firstBucketTime) {
204
        fHorDistributionData.setFirstBucketTime(firstBucketTime);
205
    }
206
207
    public void setVerFirstBucketTime(long firstBucketTime) {
208
        fVerDistributionData.setFirstBucketTime(firstBucketTime);
209
    }
210
211
    public void setHorFirstEventTime(long firstEventTime) {
212
        fHorDistributionData.setFirstEventTime(firstEventTime);
213
    }
214
215
    public void setVerFirstEventTime(long firstEventTime) {
216
        fVerDistributionData.setFirstEventTime(firstEventTime);
217
    }
218
219
    public void setHorLastEventTime(long lastEventTime) {
220
        fHorDistributionData.setLastEventTime(lastEventTime);
221
    }
222
223
    public void setVerLastEventTime(long lastEventTime) {
224
        fVerDistributionData.setLastEventTime(lastEventTime);
225
    }
226
227
    public void setHorBucketDuration(long bucketDuration) {
228
        fHorDistributionData.setBucketDuration(bucketDuration);
229
    }
230
231
    public void setVerBucketDuration(long bucketDuration) {
232
        fVerDistributionData.setBucketDuration(bucketDuration);
233
    }
234
235
    public void setHorLastBucket(int lastBucket) {
236
        fHorDistributionData.setLastBucket(lastBucket);
237
    }
238
239
    public void setVerLastBucket(int lastBucket) {
240
        fVerDistributionData.setLastBucket(lastBucket);
241
    }
242
243
    public void setCurrentEventTime(long currentEventTime) {
244
        fCurrentEventTime = currentEventTime;
245
    }
246
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/IGraphDataModel.java (+41 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
13
14
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDistributionModel;
15
16
/**
17
 * <b><u>IGraphDataModel</u></b>
18
 * <p>
19
 */
20
public interface IGraphDataModel extends IBaseDistributionModel {
21
22
    /**
23
     * Add event to the correct bucket, compacting the if needed.
24
     * 
25
     * @param eventCount - the event count
26
     * @param timestamp - the timestamp (x-coordinate) of the event to count
27
     * @param time - the time (y-coordinate) of the event to count
28
     */
29
    public void countEvent(int eventCount, long timestamp, long time);
30
    
31
    /**
32
     * Scale the model data to the width and height requested.
33
     * 
34
     * @param width - width of graph
35
     * @param height - height of graph
36
     * @param barWidth - width of bar
37
     * @return the result array of size [width] and where the highest value
38
     *         doesn't exceed [height]
39
     */
40
    public GraphScaledData scaleTo(int width, int height, int barWidth);
41
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/IGraphModelListener.java (+31 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
13
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
14
15
/**
16
 * <b><u>IGraphModelListener</u></b>
17
 * <p>
18
 */
19
public interface IGraphModelListener {
20
    
21
    /**
22
     * Method to notify listeners about model updates 
23
     */
24
    public void graphModelUpdated();
25
26
    /**
27
     * Method to inform listeners about current time updates 
28
     */
29
    public void currentEventUpdated(long currentEventTime);
30
31
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/LatencyController.java (+189 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
13
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
14
15
import org.eclipse.core.runtime.ListenerList;
16
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDistributionModel;
17
import org.eclipse.linuxtools.lttng.ui.views.histogram.IHistogramDataModel;
18
import org.eclipse.linuxtools.tmf.core.component.TmfEventProvider;
19
import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
20
import org.eclipse.linuxtools.tmf.core.request.TmfDataRequest;
21
import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest.ExecutionType;
22
23
/**
24
 * <b><u>LatencyController</u></b>
25
 * <p>
26
 */
27
public class LatencyController {
28
   
29
    // ------------------------------------------------------------------------
30
    // Attributes
31
    // ------------------------------------------------------------------------
32
33
    private static LatencyController fInstance = null;
34
    
35
    private LatencyEventRequest fEventRequest;
36
    
37
    private TmfEventProvider<?> fProvider;
38
    
39
    private final ListenerList fModels;
40
41
    // ------------------------------------------------------------------------
42
    // Constructor
43
    // ------------------------------------------------------------------------
44
45
    private LatencyController() {
46
        fModels = new ListenerList();
47
    }
48
49
    // ------------------------------------------------------------------------
50
    // Accessors
51
    // ------------------------------------------------------------------------
52
    public static LatencyController getInstance() {
53
        if (fInstance == null) {
54
            fInstance = new LatencyController();
55
        }
56
        return fInstance;
57
    }
58
    
59
    // ------------------------------------------------------------------------
60
    // Operations
61
    // ------------------------------------------------------------------------
62
63
    /**
64
     * Refresh all registered models
65
     * 
66
     * @param provider - TmfEventProvider to request data from
67
     * @param timeRange - time range of request
68
     */
69
    @SuppressWarnings({ "unchecked", "rawtypes" })
70
    public void refreshModels(TmfEventProvider<?> provider, TmfTimeRange timeRange) {
71
        // save provider
72
        fProvider = provider;
73
        if (fProvider != null) {
74
            if (fEventRequest != null && !fEventRequest.isCompleted()) {
75
                fEventRequest.cancel();
76
            }
77
            clear();
78
            fEventRequest = new LatencyEventRequest(this, timeRange, ExecutionType.FOREGROUND);
79
            fProvider.sendRequest((TmfDataRequest)fEventRequest);
80
        }
81
    }
82
83
    /**
84
     * Refreshes registered models by re-sending previous request to saved provider
85
     */
86
    public void refreshModels() {
87
        if (fProvider != null && fEventRequest != null) {
88
            refreshModels(fProvider, fEventRequest.getRange());
89
        }
90
    }
91
92
    /**
93
     * Clear all models
94
     */
95
    public void clear() {
96
        Object models[] = fModels.getListeners();
97
        
98
        for (int i = 0; i < models.length; i++) {
99
            ((IBaseDistributionModel)models[i]).clear();
100
        }
101
    }
102
    
103
    /**
104
     * Dispose of controller
105
     */
106
    public void dispose() {
107
        if (fEventRequest != null && !fEventRequest.isCompleted()) {
108
            fEventRequest.cancel();
109
        }
110
        fProvider = null;
111
    }
112
    
113
    /**
114
     * Register given model.
115
     * @param model - model to register
116
     */
117
    public void registerModel(IBaseDistributionModel model) {
118
        fModels.add(model);
119
    }
120
    
121
    /**
122
     * Deregister given model.
123
     * 
124
     * @param model - model to deregister
125
     */
126
    public void deregisterModel(IBaseDistributionModel model) {
127
        fModels.remove(model);
128
    }
129
    
130
    /**
131
     * Handle data of event request and pass it information to the registered models
132
     * 
133
     * @param eventCount - event count
134
     * @param timestamp - start timestamp of latency calculation
135
     * @param latency - latency value (startTimestamp - endTimestamp)
136
     */
137
    public void handleData(int eventCount, long timestamp, long latency) {
138
        Object[] models = fModels.getListeners();
139
        for (int i = 0; i < models.length; i++) {
140
            IBaseDistributionModel model = (IBaseDistributionModel)models[i];
141
            if (model instanceof IHistogramDataModel) {
142
                ((IHistogramDataModel)model).countEvent(eventCount, latency);
143
            } else if (model instanceof IGraphDataModel) {
144
                ((IGraphDataModel)model).countEvent(eventCount, timestamp, latency);
145
            }
146
        }
147
    }
148
149
    /**
150
     * Handle complete indication from request.
151
     */
152
    public void handleCompleted() {
153
        Object[] models = fModels.getListeners();
154
        for (int i = 0; i < models.length; i++) {
155
            ((IBaseDistributionModel)models[i]).complete();
156
        }
157
    }
158
159
    /**
160
     * Handle cancel indication from request.
161
     */
162
    public void handleCancel() {
163
        clear();
164
    }
165
    
166
    /**
167
     * Set event provider for refresh.
168
     * 
169
     * @param provider
170
     */
171
    public void setEventProvider(TmfEventProvider<?> provider) {
172
        fProvider = provider;
173
    }
174
    
175
    /**
176
     * Set current event time in model(s).
177
     * 
178
     * @param timestamp
179
     */
180
    public void setCurrentEventTime(long timestamp) {
181
        Object[] models = fModels.getListeners();
182
        for (int i = 0; i < models.length; i++) {
183
            IBaseDistributionModel model = (IBaseDistributionModel)models[i];
184
            if (model instanceof LatencyGraphModel) {
185
                ((LatencyGraphModel)model).setCurrentEventNotifyListeners(timestamp);
186
            }
187
        }
188
    }
189
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/LatencyEventRequest.java (+91 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
13
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
14
15
import org.eclipse.linuxtools.lttng.core.LttngConstants;
16
import org.eclipse.linuxtools.lttng.core.event.LttngEvent;
17
import org.eclipse.linuxtools.lttng.core.latency.analyzer.EventMatcher;
18
import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
19
import org.eclipse.linuxtools.tmf.core.request.ITmfDataRequest;
20
import org.eclipse.linuxtools.tmf.core.request.TmfEventRequest;
21
22
/**
23
 * <b><u>LatencyEventRequest</u></b>
24
 * <p>
25
 */
26
public class LatencyEventRequest extends TmfEventRequest<LttngEvent> {
27
28
    // ------------------------------------------------------------------------
29
    // Attributes
30
    // ------------------------------------------------------------------------
31
    final private LatencyController fController;
32
    
33
    // ------------------------------------------------------------------------
34
    // Constructor
35
    // ------------------------------------------------------------------------
36
37
    public LatencyEventRequest(LatencyController controller, TmfTimeRange range, int rank, int nbEvents, ITmfDataRequest.ExecutionType execType) {
38
        super(LttngEvent.class, range, rank, nbEvents, LttngConstants.DEFAULT_BLOCK_SIZE, execType);
39
        fController = controller;
40
        EventMatcher.getInstance().clearStack();
41
    }
42
43
    public LatencyEventRequest(LatencyController controller, TmfTimeRange range, ITmfDataRequest.ExecutionType execType) {
44
        this(controller, range, 0, ALL_DATA, execType);
45
    }
46
47
    public LatencyEventRequest(LatencyController controller, TmfTimeRange range, int rank, ITmfDataRequest.ExecutionType execType) {
48
        this(controller, range, rank, ALL_DATA, execType);
49
    }
50
51
    // ------------------------------------------------------------------------
52
    // Operations
53
    // ------------------------------------------------------------------------
54
55
    /*
56
     * (non-Javadoc)
57
     * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleData(org.eclipse.linuxtools.tmf.event.TmfData)
58
     */
59
    @Override
60
    public void handleData(LttngEvent event) {
61
        super.handleData(event);
62
        
63
        LttngEvent startEvent = EventMatcher.getInstance().process(event);
64
65
        if (startEvent != null) {
66
            long latency = event.getTimestamp().getValue() - startEvent.getTimestamp().getValue(); 
67
            fController.handleData(getNbRead(), startEvent.getTimestamp().getValue(), latency);
68
        }
69
    }
70
71
    /*
72
     * (non-Javadoc)
73
     * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCompleted()
74
     */
75
    @Override
76
    public void handleCompleted() {
77
        fController.handleCompleted();
78
        super.handleCompleted();
79
    }
80
81
    /*
82
     * (non-Javadoc)
83
     * @see org.eclipse.linuxtools.tmf.request.TmfDataRequest#handleCancel()
84
     */
85
    @Override
86
    public void handleCancel() {
87
        EventMatcher.getInstance().clearStack();
88
        fController.handleCancel();
89
        super.handleCancel();
90
    }
91
}
(-)a/lttng/org.eclipse.linuxtools.lttng.ui/src/org/eclipse/linuxtools/lttng/ui/views/latency/model/LatencyGraphModel.java (-1 / +380 lines)
Added Link Here
0
- 
1
/*******************************************************************************
2
 * Copyright (c) 2011 Ericsson
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
 * Contributors:
10
 *   Bernd Hufmann - Initial API and implementation
11
 *******************************************************************************/
12
13
package org.eclipse.linuxtools.lttng.ui.views.latency.model;
14
15
import java.util.Arrays;
16
import java.util.concurrent.locks.ReentrantLock;
17
18
import org.eclipse.core.runtime.ListenerList;
19
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.DistributionData;
20
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.HorDistributionData;
21
import org.eclipse.linuxtools.lttng.ui.views.distribution.model.VerDistributionData;
22
23
/**
24
 * <b><u>LatencyGraphModel</u></b>
25
 * <p>
26
 */
27
public class LatencyGraphModel implements IGraphDataModel {
28
29
    // ------------------------------------------------------------------------
30
    // Attributes
31
    // ------------------------------------------------------------------------
32
    private final int fNbBuckets;
33
    private final int [][] fBuckets;
34
    private final DistributionData fHorDistributionData;
35
    private final DistributionData fVerDistributionData;
36
    private long fCurrentEventTime;
37
    
38
    // private listener lists
39
    private final ListenerList fModelListeners;
40
41
    private final ReentrantLock fLock;
42
    
43
    // ------------------------------------------------------------------------
44
    // Constructors
45
    // ------------------------------------------------------------------------
46
    public LatencyGraphModel() {
47
        this(Config.DEFAULT_NUMBER_OF_BUCKETS);
48
    }
49
50
    public LatencyGraphModel(int nbBuckets) {
51
        fNbBuckets = nbBuckets;
52
        fBuckets = new int[nbBuckets][nbBuckets];
53
        fHorDistributionData = new HorDistributionData(nbBuckets, fBuckets);
54
        fVerDistributionData = new VerDistributionData(nbBuckets, fBuckets);
55
        fCurrentEventTime = Config.INVALID_EVENT_TIME;
56
       
57
        fModelListeners = new ListenerList();
58
        fLock = new ReentrantLock();
59
        clear();
60
    }
61
62
    // ------------------------------------------------------------------------
63
    // Accessors
64
    // ------------------------------------------------------------------------
65
    
66
    public int getNbBuckets() {
67
        return fNbBuckets;
68
    }
69
    
70
    public long getHorBucketDuration() {
71
        fLock.lock(); 
72
        try {
73
            return fHorDistributionData.getBucketDuration();
74
        } finally {
75
            fLock.unlock();
76
        }
77
    }
78
79
    public long getVerBucketDuration() {
80
        fLock.lock(); 
81
        try {
82
            return fVerDistributionData.getBucketDuration();
83
        } finally {
84
            fLock.unlock();
85
        }
86
    }
87
    
88
    public long getHorFirstBucketTime() {
89
        fLock.lock(); 
90
        try {
91
            return fHorDistributionData.getFirstBucketTime();
92
        } finally {
93
            fLock.unlock();
94
        }
95
    }
96
97
    public long getVerFirstBucketTime() {
98
        fLock.lock(); 
99
        try {
100
            return fVerDistributionData.getFirstBucketTime();
101
        } finally {
102
            fLock.unlock();
103
        }
104
    }
105
106
    public long getHorFirstEventTime() {
107
        fLock.lock(); 
108
        try {
109
            return fHorDistributionData.getFirstEventTime();
110
        } finally {
111
            fLock.unlock();
112
        }
113
    }
114
115
    public long getVerFirstEventTime() {
116
        fLock.lock(); 
117
        try {
118
            return fVerDistributionData.getFirstEventTime();
119
        } finally {
120
            fLock.unlock();
121
        }
122
    }
123
124
    public long getHorLastEventTime() {
125
        fLock.lock(); 
126
        try {
127
            return fHorDistributionData.getLastEventTime();
128
        } finally {
129
            fLock.unlock();
130
        }
131
    }
132
133
    public long getVerLastEventTime() {
134
        fLock.lock(); 
135
        try {
136
            return fVerDistributionData.getLastEventTime();
137
        } finally {
138
            fLock.unlock();
139
        }
140
    }
141
142
    public long getHorTimeLimit() {
143
        fLock.lock(); 
144
        try {
145
            return fHorDistributionData.getTimeLimit();
146
        } finally {
147
            fLock.unlock();
148
        }
149
    }
150
151
    public long getVerTimeLimit() {
152
        fLock.lock(); 
153
        try {
154
            return fVerDistributionData.getTimeLimit();
155
        } finally {
156
            fLock.unlock();
157
        }
158
    }
159
    
160
    public int getHorLastBucket() {
161
        fLock.lock(); 
162
        try {
163
            return fHorDistributionData.getLastBucket();
164
        } finally {
165
            fLock.unlock();
166
        }
167
    }
168
169
    public int getVerLastBucket() {
170
        fLock.lock(); 
171
        try {
172
            return fVerDistributionData.getLastBucket();
173
        } finally {
174
            fLock.unlock();
175
        }
176
    }
177
    
178
    public long getCurrentEventTime() {
179
        fLock.lock();
180
        try {
181
            return fCurrentEventTime;
182
        } finally {
183
            fLock.unlock();
184
        }
185
    }
186
187
    // ------------------------------------------------------------------------
188
    // Listener interface
189
    // ------------------------------------------------------------------------
190
    public void addGraphModelListener(IGraphModelListener listener) {
191
        fModelListeners.add(listener);        
192
    }
193
    
194
    public void removeGraphModelListener(IGraphModelListener listener) {
195
        fModelListeners.remove(listener);
196
    }
197
 
198
    // ------------------------------------------------------------------------
199
    // Operations
200
    // ------------------------------------------------------------------------
201
    /*
202
     * (non-Javadoc)
203
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDataModel#clear()
204
     */
205
    @Override
206
    public void clear() {
207
        fLock.lock();
208
        try {
209
            for (int[] row : fBuckets) {
210
                Arrays.fill(row, 0, fNbBuckets, 0);
211
            }
212
            fHorDistributionData.clear();
213
            fVerDistributionData.clear();
214
        } finally {
215
            fLock.unlock();
216
        }
217
        fireModelUpdateNotification();
218
    }
219
    
220
    /*
221
     * (non-Javadoc)
222
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphDataModel#countEvent(int, long, long)
223
     */
224
    @Override
225
    public void countEvent(int eventCount, long timestamp, long time) {
226
        fLock.lock();
227
        try {
228
            int horIndex = fHorDistributionData.countEvent(timestamp);
229
            int verIndex = fVerDistributionData.countEvent(time);
230
231
            fBuckets[horIndex][verIndex]++;
232
        } finally {
233
            fLock.unlock();
234
        }
235
236
        fireModelUpdateNotification(eventCount);
237
    }
238
    
239
    /*
240
     * (non-Javadoc)
241
     * @see org.eclipse.linuxtools.lttng.ui.views.latency.model.IGraphDataModel#scaleTo(int, int, int)
242
     */
243
    @Override
244
    public GraphScaledData scaleTo(int width, int height, int barWidth) {
245
        GraphScaledData scaledData = new GraphScaledData(width, height, barWidth);
246
        fLock.lock();
247
        try {
248
            if (!fHorDistributionData.isFirst() && !fVerDistributionData.isFirst() ) {
249
250
                // Basic validation
251
                if (width <= 0 ||  height <= 0 || barWidth <= 0)
252
                    throw new AssertionError("Invalid histogram dimensions (" + width + "x" + height + ", barWidth=" + barWidth + ")");   //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$//$NON-NLS-4$
253
254
                // Scale horizontally
255
                int nbBars = width / barWidth;
256
                int bucketsPerBar = fHorDistributionData.getLastBucket() / nbBars + 1;
257
258
                int horData[][] = new int[nbBars][fNbBuckets];  
259
                for (int y = 0; y < fNbBuckets; y++) {
260
                    for (int i = 0; i < nbBars; i++) {
261
                        int count = 0;
262
                        for (int j = i * bucketsPerBar; j < (i + 1) * bucketsPerBar; j++) {
263
                            if (fNbBuckets <= j)
264
                                break;
265
                            count += fBuckets[j][y];
266
                        }
267
                        horData[i][y] = count;
268
                    }
269
                }
270
271
                // Scale vertically
272
                int nbVerBars = height / barWidth;
273
                int bucketsPerVerBar = fVerDistributionData.getLastBucket() / nbVerBars + 1;
274
275
                int verData[][] = new int[nbBars][nbVerBars];  
276
                for (int x = 0; x < nbBars; x++) {
277
                    for (int i = 0; i < nbVerBars; i++) {
278
                        int count = 0;
279
                        for (int j = i * bucketsPerVerBar; j < (i + 1) * bucketsPerVerBar; j++) {
280
                            if (fNbBuckets <= j)
281
                                break;
282
                            count += horData[x][j];
283
                        }
284
                        verData[x][i] = count;
285
                    }
286
                }
287
288
                scaledData.setData(verData);
289
                scaledData.setHorFirstBucketTime(fHorDistributionData.getFirstBucketTime());
290
                scaledData.setVerFirstBucketTime(fVerDistributionData.getFirstBucketTime());
291
                scaledData.setHorFirstEventTime(fHorDistributionData.getFirstEventTime());
292
                scaledData.setVerFirstEventTime(fVerDistributionData.getFirstEventTime());
293
                scaledData.setHorLastEventTime(fHorDistributionData.getLastEventTime());
294
                scaledData.setVerLastEventTime(fVerDistributionData.getLastEventTime());
295
                scaledData.setHorBucketDuration(bucketsPerBar * fHorDistributionData.getBucketDuration());
296
                scaledData.setVerBucketDuration(bucketsPerVerBar * fVerDistributionData.getBucketDuration());
297
                scaledData.setHorLastBucket(fHorDistributionData.getLastBucket() / bucketsPerBar);
298
                scaledData.setVerLastBucket(fVerDistributionData.getLastBucket() / bucketsPerVerBar);
299
                scaledData.setCurrentEventTime(fCurrentEventTime);
300
            }
301
        } finally {
302
            fLock.unlock();
303
        }
304
305
        return scaledData;
306
    }
307
308
    /*
309
     * (non-Javadoc)
310
     * @see org.eclipse.linuxtools.lttng.ui.views.distribution.model.IBaseDataModel#complete()
311
     */
312
    @Override
313
    public void complete() {
314
        fireModelUpdateNotification();
315
    }
316
317
    /**
318
     * Sets the current event time but don't notify listeners.
319
     * 
320
     * @param timestamp
321
     */
322
    public void setCurrentEvent(long timestamp) {
323
        fLock.lock();
324
        try {
325
            fCurrentEventTime = timestamp;
326
        } finally {
327
            fLock.unlock();
328
        }   
329
    }
330
331
    /**
332
     * Sets the current event time and notify listeners.
333
     * 
334
     * @param timestamp
335
     */
336
    public void setCurrentEventNotifyListeners(long timestamp) {
337
        fLock.lock();
338
        try {
339
            fCurrentEventTime = timestamp;
340
        } finally {
341
            fLock.unlock();
342
        }
343
        fireCurrentEventUpdateNotification();
344
    }
345
   
346
    // ------------------------------------------------------------------------
347
    // Helper functions
348
    // ------------------------------------------------------------------------
349
350
    /*
351
     * Notify listeners immediately
352
     */
353
    private void fireModelUpdateNotification() {
354
        fireModelUpdateNotification(0);
355
    }
356
    
357
    /*
358
     * Notify listeners with certain refresh rate.
359
     */
360
    private void fireModelUpdateNotification(int count) {
361
        if (count % Config.POINT_BUFFER_SIZE == 0) {
362
            Object[] listeners = fModelListeners.getListeners();
363
            for (int i = 0; i < listeners.length; i++) {
364
                IGraphModelListener listener = (IGraphModelListener) listeners[i];
365
                listener.graphModelUpdated();
366
            }
367
        }
368
    }
369
370
    /*
371
     * Notify listeners immediately
372
     */
373
    private void fireCurrentEventUpdateNotification() {
374
        Object[] listeners = fModelListeners.getListeners();
375
        for (int i = 0; i < listeners.length; i++) {
376
            IGraphModelListener listener = (IGraphModelListener) listeners[i];
377
            listener.currentEventUpdated(fCurrentEventTime);
378
        }
379
    }
380
}

Return to bug 331467