2 * Copyright 2000-2011 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org.jetbrains.ether.dependencyView;
18 import com.intellij.util.io.DataExternalizer;
19 import com.intellij.util.io.KeyDescriptor;
20 import com.intellij.util.io.PersistentHashMap;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.LinkedList;
29 * Created by IntelliJ IDEA.
33 * To change this template use File | Settings | File Templates.
35 class PersistentMultiMaplet<K, V> implements MultiMaplet<K, V> {
36 private final PersistentHashMap<K, Collection<V>> myMap;
37 private final DataExternalizer<V> myValueExternalizer;
39 public PersistentMultiMaplet(final File file,
40 final KeyDescriptor<K> keyExternalizer,
41 final DataExternalizer<V> valueExternalizer,
42 final TransientMultiMaplet.CollectionConstructor<V> collectionFactory) throws IOException {
43 myValueExternalizer = valueExternalizer;
44 myMap = new PersistentHashMap<K, Collection<V>>(file, keyExternalizer,
45 new CollectionDataExternalizer<V>(valueExternalizer, collectionFactory));
50 public boolean containsKey(final K key) {
52 return myMap.containsMapping(key);
54 catch (IOException e) {
55 throw new RuntimeException(e);
60 public Collection<V> get(final K key) {
62 return myMap.get(key);
64 catch (IOException e) {
65 throw new RuntimeException(e);
70 public void put(final K key, final Collection<V> value) {
72 myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
73 public void append(DataOutput out) throws IOException {
75 myValueExternalizer.save(out, v);
80 catch (IOException e) {
81 throw new RuntimeException(e);
86 public void put(final K key, final V value) {
87 put(key, Collections.singleton(value));
91 public void removeAll(K key, Collection<V> values) {
93 final Collection<V> collection = myMap.get(key);
95 if (collection != null) {
96 if (collection.removeAll(values)) {
97 if (collection.isEmpty()) {
101 myMap.put(key, collection);
106 catch (IOException e) {
107 throw new RuntimeException(e);
112 public void removeFrom(final K key, final V value) {
114 final Collection<V> collection = myMap.get(key);
116 if (collection != null) {
117 if (collection.remove(value)) {
118 if (collection.isEmpty()) {
122 myMap.put(key, collection);
127 catch (IOException e) {
128 throw new RuntimeException(e);
133 public void remove(final K key) {
137 catch (IOException e) {
138 throw new RuntimeException(e);
143 public void putAll(MultiMaplet<K, V> m) {
144 for (Map.Entry<K, Collection<V>> entry : m.entrySet()) {
145 final K key = entry.getKey();
147 put(key, entry.getValue());
151 public Collection<K> keyCollection() {
153 return myMap.getAllKeysWithExistingMapping();
155 catch (IOException e) {
156 throw new RuntimeException(e);
161 public void close() {
165 catch (IOException e) {
166 throw new RuntimeException(e);
170 public void flush(boolean memoryCachesOnly) {
171 if (memoryCachesOnly) {
172 if (myMap.isDirty()) {
173 myMap.dropMemoryCaches();
182 public Collection<Map.Entry<K, Collection<V>>> entrySet() {
183 final Collection<Map.Entry<K, Collection<V>>> result = new LinkedList<Map.Entry<K, Collection<V>>>();
186 for (final K key : myMap.getAllKeysWithExistingMapping()) {
187 final Collection<V> value = myMap.get(key);
189 final Map.Entry<K, Collection<V>> entry = new Map.Entry<K, Collection<V>>() {
196 public Collection<V> getValue() {
201 public Collection<V> setValue(Collection<V> value) {
211 catch (IOException e) {
212 throw new RuntimeException(e);
216 private static class CollectionDataExternalizer<V> implements DataExternalizer<Collection<V>> {
217 private final DataExternalizer<V> myElementExternalizer;
218 private final TransientMultiMaplet.CollectionConstructor<V> myCollectionFactory;
220 public CollectionDataExternalizer(DataExternalizer<V> elementExternalizer,
221 TransientMultiMaplet.CollectionConstructor<V> collectionFactory) {
222 myElementExternalizer = elementExternalizer;
223 myCollectionFactory = collectionFactory;
227 public void save(final DataOutput out, final Collection<V> value) throws IOException {
229 myElementExternalizer.save(out, x);
234 public Collection<V> read(final DataInput in) throws IOException {
235 final Collection<V> result = myCollectionFactory.create();
236 final DataInputStream stream = (DataInputStream)in;
237 while (stream.available() > 0) {
238 result.add(myElementExternalizer.read(in));