Sfoglia il codice sorgente

Added WeakList and WeakMapList and made most relevant places use them. Should stop stuff not being GC'd after registering listeners and whatnot.

git-svn-id: http://svn.dmdirc.com/trunk@2543 00569f92-eb28-0410-84fd-f71c24880f
tags/0.5.5
Chris Smith 16 anni fa
parent
commit
c94ba997c4

+ 6
- 7
src/com/dmdirc/commandparser/CommandManager.java Vedi File

@@ -41,6 +41,7 @@ import com.dmdirc.config.IdentityManager;
41 41
 import com.dmdirc.logger.ErrorLevel;
42 42
 import com.dmdirc.logger.Logger;
43 43
 import com.dmdirc.ui.input.TabCompleter;
44
+import com.dmdirc.util.WeakList;
44 45
 
45 46
 import java.util.ArrayList;
46 47
 import java.util.List;
@@ -77,25 +78,25 @@ public final class CommandManager {
77 78
     /**
78 79
      * The parsers that have requested global commands.
79 80
      */
80
-    private static List<CommandParser> globalParsers = new ArrayList<CommandParser>();
81
+    private static List<CommandParser> globalParsers = new WeakList<CommandParser>();
81 82
     /**
82 83
      * The parsers that have requested server commands.
83 84
      */
84
-    private static List<CommandParser> serverParsers = new ArrayList<CommandParser>();
85
+    private static List<CommandParser> serverParsers = new WeakList<CommandParser>();
85 86
     /**
86 87
      * The parsers that have requested channel commands.
87 88
      */
88
-    private static List<CommandParser> channelParsers = new ArrayList<CommandParser>();
89
+    private static List<CommandParser> channelParsers = new WeakList<CommandParser>();
89 90
     /**
90 91
      * The parsers that have requested query commands.
91 92
      */
92
-    private static List<CommandParser> queryParsers = new ArrayList<CommandParser>();
93
+    private static List<CommandParser> queryParsers = new WeakList<CommandParser>();
93 94
     
94 95
     /**
95 96
      * Channel commands that have been registered to appear in the nicklist
96 97
      * popup.
97 98
      */
98
-    private static List<Command> channelPopupCommands = new ArrayList<Command>();
99
+    private static List<Command> channelPopupCommands = new WeakList<Command>();
99 100
     
100 101
     /** The command char we're using. */
101 102
     private static char commandChar = IdentityManager.getGlobalConfig()
@@ -194,8 +195,6 @@ public final class CommandManager {
194 195
      */
195 196
     private static void registerCommand(final Command command,
196 197
             final List<CommandParser> parsers, final boolean register) {
197
-        // FIXME: There's no way to kill old/dead entries in the *Parsers lists.
198
-        //        Ideally, they'd unregister themselves (or so) when unloaded.
199 198
         for (CommandParser parser : parsers) {
200 199
             if (register) {
201 200
                 parser.registerCommand(command);

+ 3
- 3
src/com/dmdirc/config/ConfigManager.java Vedi File

@@ -22,7 +22,7 @@
22 22
 
23 23
 package com.dmdirc.config;
24 24
 
25
-import com.dmdirc.util.MapList;
25
+import com.dmdirc.util.WeakMapList;
26 26
 
27 27
 import java.io.Serializable;
28 28
 import java.util.ArrayList;
@@ -53,8 +53,8 @@ public final class ConfigManager extends ConfigSource implements Serializable,
53 53
     private List<Identity> sources;
54 54
     
55 55
     /** The listeners registered for this manager. */
56
-    private final MapList<String, ConfigChangeListener> listeners
57
-            = new MapList<String, ConfigChangeListener>();
56
+    private final WeakMapList<String, ConfigChangeListener> listeners
57
+            = new WeakMapList<String, ConfigChangeListener>();
58 58
     
59 59
     /** The ircd this manager is for. */
60 60
     private final String ircd;

+ 2
- 1
src/com/dmdirc/config/Identity.java Vedi File

@@ -26,6 +26,7 @@ import com.dmdirc.Main;
26 26
 import com.dmdirc.Precondition;
27 27
 import com.dmdirc.logger.ErrorLevel;
28 28
 import com.dmdirc.logger.Logger;
29
+import com.dmdirc.util.WeakList;
29 30
 
30 31
 import java.io.File;
31 32
 import java.io.FileInputStream;
@@ -72,7 +73,7 @@ public class Identity extends ConfigSource implements Serializable,
72 73
     
73 74
     /** The config change listeners for this source. */
74 75
     protected final List<ConfigChangeListener> listeners
75
-            = new ArrayList<ConfigChangeListener>();
76
+            = new WeakList<ConfigChangeListener>();
76 77
     
77 78
     /** The file that this identity is read from. */
78 79
     protected File file;

+ 1
- 0
src/com/dmdirc/config/IdentityManager.java Vedi File

@@ -45,6 +45,7 @@ public final class IdentityManager {
45 45
     private final static List<Identity> identities = new ArrayList<Identity>();
46 46
     
47 47
     /** The config managers that have registered with this manager. */
48
+    // XXX: Should this be a weak list?
48 49
     private final static List<ConfigManager> managers = new ArrayList<ConfigManager>();
49 50
     
50 51
     /** The identity file used for the global config. */

+ 3
- 5
src/com/dmdirc/updater/Update.java Vedi File

@@ -27,11 +27,9 @@ import com.dmdirc.logger.ErrorLevel;
27 27
 import com.dmdirc.logger.Logger;
28 28
 import com.dmdirc.updater.Update.STATUS;
29 29
 import com.dmdirc.util.Downloader;
30
-import java.io.IOException;
31
-import java.net.MalformedURLException;
32
-import java.util.ArrayList;
30
+import com.dmdirc.util.WeakList;
31
+
33 32
 import java.util.List;
34
-import java.util.logging.Level;
35 33
 
36 34
 /**
37 35
  * Represents a single available update for some component.
@@ -64,7 +62,7 @@ public final class Update {
64 62
 
65 63
     /** A list of registered update listeners. */
66 64
     private final List<UpdateListener> listeners
67
-            = new ArrayList<UpdateListener>();
65
+            = new WeakList<UpdateListener>();
68 66
 
69 67
     /** Our current status. */
70 68
     private STATUS status = Update.STATUS.PENDING;

+ 2
- 2
src/com/dmdirc/util/MapList.java Vedi File

@@ -40,7 +40,7 @@ import java.util.Set;
40 40
 public class MapList<S,T> {
41 41
     
42 42
     /** Our internal map. */
43
-    private final Map<S, List<T>> map = new HashMap<S, List<T>>();
43
+    protected final Map<S, List<T>> map = new HashMap<S, List<T>>();
44 44
 
45 45
     /**
46 46
      * Determines if this MapList is empty. An empty MapList is one that either
@@ -109,7 +109,7 @@ public class MapList<S,T> {
109 109
      * @param key The key to retrieve
110 110
      * @return A list of the specified key's values
111 111
      */
112
-    private List<T> safeGet(final S key) {
112
+    protected List<T> safeGet(final S key) {
113 113
         if (!map.containsKey(key)) {
114 114
             map.put(key, new ArrayList<T>());
115 115
         }

+ 229
- 0
src/com/dmdirc/util/WeakList.java Vedi File

@@ -0,0 +1,229 @@
1
+/*
2
+ * Copyright (c) 2006-2007 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.lang.ref.WeakReference;
26
+import java.util.ArrayList;
27
+import java.util.Collection;
28
+import java.util.Iterator;
29
+import java.util.List;
30
+import java.util.ListIterator;
31
+
32
+/**
33
+ *
34
+ * @param <T>
35
+ * @author chris
36
+ */
37
+public class WeakList<T> implements List<T> {
38
+
39
+    private final List<WeakReference<T>> list = new ArrayList<WeakReference<T>>();
40
+
41
+    public WeakList() {
42
+        super();
43
+    }
44
+
45
+    private void cleanUp() {
46
+        for (int i = 0; i < list.size(); i++) {
47
+            if (list.get(i).get() == null) {
48
+                list.remove(i--);
49
+            }
50
+        }
51
+    }
52
+
53
+    private List<T> dereferenceList(final List<WeakReference<T>> list) {
54
+        final List<T> res = new ArrayList<T>();
55
+
56
+        for (WeakReference<T> item : list) {
57
+            if (item.get() != null) {
58
+                res.add(item.get());
59
+            }
60
+        }
61
+
62
+        return res;
63
+    }
64
+
65
+    @SuppressWarnings(value = "unchecked")
66
+    private Collection<WeakReference<T>> referenceCollection(final Collection<?> c) {
67
+        final Collection<WeakReference<T>> res = new ArrayList<WeakReference<T>>();
68
+
69
+        for (Object item : c) {
70
+            res.add(new WeakReference(item));
71
+        }
72
+
73
+        return res;
74
+    }
75
+
76
+    /** {@inheritDoc} */
77
+    @Override
78
+    public int size() {
79
+        cleanUp();
80
+
81
+        return list.size();
82
+    }
83
+
84
+    /** {@inheritDoc} */
85
+    @Override
86
+    public boolean isEmpty() {
87
+        cleanUp();
88
+
89
+        return list.isEmpty();
90
+    }
91
+
92
+    /** {@inheritDoc} */
93
+    @Override @SuppressWarnings(value = "unchecked")
94
+    public boolean contains(Object o) {
95
+        return list.contains(new WeakReference(o));
96
+    }
97
+
98
+    /** {@inheritDoc} */
99
+    @Override
100
+    public Iterator<T> iterator() {
101
+        return dereferenceList(list).iterator();
102
+    }
103
+
104
+    /** {@inheritDoc} */
105
+    @Override
106
+    public Object[] toArray() {
107
+        return dereferenceList(list).toArray();
108
+    }
109
+
110
+    /** {@inheritDoc} */
111
+    @Override
112
+    public <T> T[] toArray(T[] a) {
113
+        return dereferenceList(list).toArray(a);
114
+    }
115
+
116
+    /** {@inheritDoc} */
117
+    @Override
118
+    public boolean add(T e) {
119
+        return list.add(new WeakReference<T>(e));
120
+    }
121
+
122
+    /** {@inheritDoc} */
123
+    @Override @SuppressWarnings(value = "unchecked")
124
+    public boolean remove(Object o) {
125
+        return list.remove(new WeakReference(o));
126
+    }
127
+
128
+    /** {@inheritDoc} */
129
+    @Override
130
+    public boolean containsAll(Collection<?> c) {
131
+        return dereferenceList(list).containsAll(c);
132
+    }
133
+
134
+    /** {@inheritDoc} */
135
+    @Override
136
+    public boolean addAll(Collection<? extends T> c) {
137
+        return list.addAll(referenceCollection(c));
138
+    }
139
+
140
+    /** {@inheritDoc} */
141
+    @Override
142
+    public boolean addAll(int index, Collection<? extends T> c) {
143
+        return list.addAll(index, referenceCollection(c));
144
+    }
145
+
146
+    /** {@inheritDoc} */
147
+    @Override
148
+    public boolean removeAll(Collection<?> c) {
149
+        return list.removeAll(referenceCollection(c));
150
+    }
151
+
152
+    /** {@inheritDoc} */
153
+    @Override
154
+    public boolean retainAll(Collection<?> c) {
155
+        return list.retainAll(referenceCollection(c));
156
+    }
157
+
158
+    /** {@inheritDoc} */
159
+    @Override
160
+    public void clear() {
161
+        list.clear();
162
+    }
163
+
164
+    /** {@inheritDoc} */
165
+    @Override
166
+    public T get(int index) {
167
+        cleanUp();
168
+
169
+        return list.get(index).get();
170
+    }
171
+
172
+    /** {@inheritDoc} */
173
+    @Override
174
+    public T set(int index, T element) {
175
+        list.set(index, new WeakReference<T>(element));
176
+
177
+        return element;
178
+    }
179
+
180
+    /** {@inheritDoc} */
181
+    @Override
182
+    public void add(int index, T element) {
183
+        list.add(index, new WeakReference<T>(element));
184
+    }
185
+
186
+    /** {@inheritDoc} */
187
+    @Override
188
+    public T remove(int index) {
189
+        return list.remove(index).get();
190
+    }
191
+
192
+    /** {@inheritDoc} */
193
+    @Override @SuppressWarnings(value = "unchecked")
194
+    public int indexOf(Object o) {
195
+        cleanUp();
196
+
197
+        return list.indexOf(new WeakReference(o));
198
+    }
199
+
200
+    /** {@inheritDoc} */
201
+    @Override @SuppressWarnings(value = "unchecked")
202
+    public int lastIndexOf(Object o) {
203
+        cleanUp();
204
+
205
+        return list.lastIndexOf(new WeakReference(o));
206
+    }
207
+
208
+    /** {@inheritDoc} */
209
+    @Override
210
+    public ListIterator<T> listIterator() {
211
+        cleanUp();
212
+
213
+        return dereferenceList(list).listIterator();
214
+    }
215
+
216
+    /** {@inheritDoc} */
217
+    @Override
218
+    public ListIterator<T> listIterator(int index) {
219
+        cleanUp();
220
+
221
+        return dereferenceList(list).listIterator(index);
222
+    }
223
+
224
+    /** {@inheritDoc} */
225
+    @Override
226
+    public List<T> subList(int fromIndex, int toIndex) {
227
+        return dereferenceList(list.subList(fromIndex, toIndex));
228
+    }
229
+}

+ 54
- 0
src/com/dmdirc/util/WeakMapList.java Vedi File

@@ -0,0 +1,54 @@
1
+/*
2
+ * Copyright (c) 2006-2007 Chris Smith, Shane Mc Cormack, Gregory Holmes
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
+ * SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.util;
24
+
25
+import java.util.List;
26
+
27
+/**
28
+ * Wraps a Map&lt;S, List&lt;T&gt;&gt; with various convenience methods for
29
+ * accessing the data. Implements a Map-like interface for easier transition.
30
+ * This implementation uses WeakLists (i.e., lists of weak references) - all
31
+ * references to values are wrapped in WeakReferences.
32
+ * 
33
+ * @param <S> the type of keys maintained by this map
34
+ * @param <T> the type of mapped values
35
+ * @author chris
36
+ */
37
+public class WeakMapList<S,T> extends MapList<S,T> {
38
+    
39
+    /**
40
+     * Retrieves the list of values associated with the specified key, creating
41
+     * the key if neccessary.
42
+     * 
43
+     * @param key The key to retrieve
44
+     * @return A list of the specified key's values
45
+     */
46
+    @Override
47
+    protected List<T> safeGet(final S key) {
48
+        if (!map.containsKey(key)) {
49
+            map.put(key, new WeakList<T>());
50
+        }
51
+        
52
+        return map.get(key);
53
+    }
54
+}

Loading…
Annulla
Salva