speedup: call force() only at the end of the build, between chunk builds drop only...
[idea/community.git] / jps / model / src / org / jetbrains / ether / dependencyView / TransientMultiMaplet.java
1 package org.jetbrains.ether.dependencyView;
2
3 import org.jetbrains.ether.RW;
4
5 import java.io.BufferedReader;
6 import java.util.Collection;
7 import java.util.HashMap;
8 import java.util.Map;
9 import java.util.Set;
10
11 /**
12  * Created by IntelliJ IDEA.
13  * User: db
14  * Date: 08.03.11
15  * Time: 15:38
16  * To change this template use File | Settings | File Templates.
17  */
18 class TransientMultiMaplet<K, V> implements MultiMaplet<K, V> {
19   public static <X, Y> TransientMultiMaplet<X, Y> read(final BufferedReader r,
20                                           final RW.Reader<X> xr,
21                                           final RW.Reader<Y> yr,
22                                           final CollectionConstructor<Y> cc) {
23     final TransientMultiMaplet<X, Y> result = new TransientMultiMaplet<X, Y>(cc);
24
25     final int size = RW.readInt(r);
26
27     for (int i = 0; i < size; i++) {
28       final X key = xr.read(r);
29       result.put(key, (Set<Y>)RW.readMany(r, yr, cc.create()));
30     }
31
32     return result;
33   }
34
35   public interface CollectionConstructor<X> {
36     Collection<X> create();
37   }
38
39   private final Map<K, Collection<V>> myMap = new HashMap<K, Collection<V>>();
40
41   private final CollectionConstructor<V> constr;
42
43   public TransientMultiMaplet(final CollectionConstructor<V> c) {
44     constr = c;
45   }
46
47   @Override
48   public boolean containsKey(final K key) {
49     return myMap.containsKey(key);
50   }
51
52   @Override
53   public Collection<V> get(final K key) {
54     return myMap.get(key);
55   }
56
57   @Override
58   public void put(final K key, final Collection<V> value) {
59     final Collection<V> x = myMap.get(key);
60     if (x == null) {
61       myMap.put(key, value);
62     }
63     else {
64       x.addAll(value);
65     }
66   }
67
68   @Override
69   public void put(final K key, final V value) {
70     final Collection<V> x = constr.create();
71     x.add(value);
72     put(key, x);
73   }
74
75   @Override
76   public void removeFrom(final K key, final V value) {
77     final Collection<V> collection = myMap.get(key);
78     if (collection != null) {
79       if (collection.remove(value)) {
80         if (collection.isEmpty()) {
81           myMap.remove(key);
82         }
83       }
84     }
85   }
86
87   @Override
88   public void removeAll(K key, Collection<V> values) {
89     final Collection<V> collection = myMap.get(key);
90     if (collection != null) {
91       if (collection.removeAll(values)) {
92         if (collection.isEmpty()) {
93           myMap.remove(key);
94         }
95       }
96     }
97   }
98
99   @Override
100   public void remove(final K key) {
101     myMap.remove(key);
102   }
103
104   @Override
105   public void putAll(MultiMaplet<K, V> m) {
106     for (Map.Entry<K, Collection<V>> e : m.entrySet()) {
107       remove(e.getKey());
108       put(e.getKey(), e.getValue());
109     }
110   }
111
112   @Override
113   public Collection<K> keyCollection() {
114     return myMap.keySet();
115   }
116
117   @Override
118   public Set<Map.Entry<K, Collection<V>>> entrySet() {
119     return myMap.entrySet();
120   }
121
122   @Override
123   public void close(){
124     myMap.clear(); // free memory
125   }
126
127   public void flush(boolean memoryCachesOnly) {
128   }
129 }