KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > core > internal > utils > StringPoolJob


1 /*******************************************************************************
2  * Copyright (c) 2004, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM - Initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.core.internal.utils;
12
13 import java.util.*;
14 import org.eclipse.core.runtime.*;
15 import org.eclipse.core.runtime.jobs.*;
16 import org.osgi.framework.Bundle;
17
18 /**
19  * Performs string sharing passes on all string pool participants registered
20  * with the platform.
21  */

22 public class StringPoolJob extends Job {
23     private static final long INITIAL_DELAY = 10000;//ten seconds
24
private static final long RESCHEDULE_DELAY = 300000;//five minutes
25
private long lastDuration;
26     /**
27      * Stores all registered string pool participants, along with the scheduling
28      * rule required when running it.
29      */

30     private Map participants = Collections.synchronizedMap(new HashMap(10));
31
32     private final Bundle systemBundle = Platform.getBundle("org.eclipse.osgi"); //$NON-NLS-1$
33

34     public StringPoolJob() {
35         super(Messages.utils_stringJobName);
36         setSystem(true);
37         setPriority(DECORATE);
38     }
39
40     /**
41      * Adds a string pool participant. The job periodically builds
42      * a string pool and asks all registered participants to share their strings in
43      * the pool. Once all participants have added their strings to the pool, the
44      * pool is discarded to avoid additional memory overhead.
45      *
46      * Adding a participant that is equal to a participant already registered will
47      * replace the scheduling rule associated with the participant, but will otherwise
48      * be ignored.
49      *
50      * @param participant The participant to add
51      * @param rule The scheduling rule that must be owned at the time the
52      * participant is called. This allows a participant to protect their data structures
53      * against access at unsafe times.
54      *
55      * @see #removeStringPoolParticipant(IStringPoolParticipant)
56      * @since 3.1
57      */

58     public void addStringPoolParticipant(IStringPoolParticipant participant, ISchedulingRule rule) {
59         participants.put(participant, rule);
60         if (getState() == Job.SLEEPING)
61             wakeUp(INITIAL_DELAY);
62         else
63             schedule(INITIAL_DELAY);
64     }
65
66     /**
67      * Removes the indicated log listener from the set of registered string
68      * pool participants. If no such participant is registered, no action is taken.
69      *
70      * @param participant the participant to deregister
71      * @see #addStringPoolParticipant(IStringPoolParticipant, ISchedulingRule)
72      * @since 3.1
73      */

74     public void removeStringPoolParticipant(IStringPoolParticipant participant) {
75         participants.remove(participant);
76     }
77
78     /* (non-Javadoc)
79      * Method declared on Job
80      */

81     protected IStatus run(IProgressMonitor monitor) {
82         //if the system is shutting down, don't build
83
if (systemBundle.getState() == Bundle.STOPPING)
84             return Status.OK_STATUS;
85
86         //copy current participants to handle concurrent additions and removals to map
87
Map.Entry[] entries = (Map.Entry[]) participants.entrySet().toArray(new Map.Entry[0]);
88         ISchedulingRule[] rules = new ISchedulingRule[entries.length];
89         IStringPoolParticipant[] toRun = new IStringPoolParticipant[entries.length];
90         for (int i = 0; i < toRun.length; i++) {
91             toRun[i] = (IStringPoolParticipant) entries[i].getKey();
92             rules[i] = (ISchedulingRule) entries[i].getValue();
93         }
94         final ISchedulingRule rule = MultiRule.combine(rules);
95         long start = -1;
96         int savings = 0;
97         final IJobManager jobManager = Job.getJobManager();
98         try {
99             jobManager.beginRule(rule, monitor);
100             start = System.currentTimeMillis();
101             savings = shareStrings(toRun, monitor);
102         } finally {
103             jobManager.endRule(rule);
104         }
105         if (start > 0) {
106             lastDuration = System.currentTimeMillis() - start;
107             if (Policy.DEBUG_STRINGS)
108                 Policy.debug("String sharing saved " + savings + " bytes in: " + lastDuration); //$NON-NLS-1$ //$NON-NLS-2$
109
}
110         //throttle frequency if it takes too long
111
long scheduleDelay = Math.max(RESCHEDULE_DELAY, lastDuration*100);
112         if (Policy.DEBUG_STRINGS)
113             Policy.debug("Rescheduling string sharing job in: " + scheduleDelay); //$NON-NLS-1$
114
schedule(scheduleDelay);
115         return Status.OK_STATUS;
116     }
117
118     private int shareStrings(IStringPoolParticipant[] toRun, IProgressMonitor monitor) {
119         final StringPool pool = new StringPool();
120         for (int i = 0; i < toRun.length; i++) {
121             if (monitor.isCanceled())
122                 break;
123             final IStringPoolParticipant current = toRun[i];
124             SafeRunner.run(new ISafeRunnable() {
125                 public void handleException(Throwable JavaDoc exception) {
126                     //exceptions are already logged, so nothing to do
127
}
128
129                 public void run() {
130                     current.shareStrings(pool);
131                 }
132             });
133         }
134         return pool.getSavedStringCount();
135     }
136 }
137
Popular Tags