com.github.bezsias.multimap.CompactMultiMap Maven / Gradle / Ivy
The newest version!
package com.github.bezsias.multimap;
import java.io.*;
import java.util.*;
import java.io.Serializable;
/**
* Compact zipped byte[] based value serialization.
* Works best for append only situation.
*/
public class CompactMultiMap implements MultiMap {
private Map compressedMap;
private Map noncompressedMap;
private int _size = 0;
private BytePackager packager;
CompactMultiMap(BytePackager packager, MapFactory mapFactory) throws IOException {
this.packager = packager;
this.noncompressedMap = mapFactory.createMap();
this.compressedMap = mapFactory.createMap();
}
protected boolean remove(List values, V value) {
return values.remove(value);
}
protected boolean contains(List values, V value) {
return values.contains(value);
}
@Override
public int size() {
return _size;
}
@Override
public int minKeySize() {
return Math.max(compressedMap.size(), noncompressedMap.size());
}
@Override
public int maxKeySize() {
return compressedMap.size() + noncompressedMap.size();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(K key) {
return noncompressedMap.containsKey(key) || compressedMap.containsKey(key);
}
@Override
public boolean contains(K key, V value) {
List values = get(key);
return contains(values, value);
}
@Override
public Set keys() {
Set ks = new HashSet<>();
ks.addAll(noncompressedMap.keySet());
ks.addAll(compressedMap.keySet());
return ks;
}
BytePack fetch(K key) {
return new BytePack(noncompressedMap.get(key), compressedMap.get(key));
}
private void store(K key, BytePack pack) {
if (pack.noncompressed != null) {
noncompressedMap.put(key, pack.noncompressed);
} else {
noncompressedMap.remove(key);
}
if (pack.compressed != null) {
compressedMap.put(key, pack.compressed);
} else {
compressedMap.remove(key);
}
}
@Override
public void put(K key, V value) {
try {
BytePack pack = fetch(key);
pack = packager.pack(pack, value);
store(key, pack);
_size++;
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void putAll(K key, List values) {
if (values.isEmpty()) return;
try {
BytePack pack = fetch(key);
pack = packager.pack(pack, values);
store(key, pack);
_size += values.size();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public List get(K key) {
BytePack pack = fetch(key);
try {
return packager.unpack(pack);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
return Collections.emptyList();
}
}
@Override
public void remove(K key) {
_size -= get(key).size();
noncompressedMap.remove(key);
compressedMap.remove(key);
}
@Override
public void remove(K key, V value) {
List values = get(key);
_size -= values.size();
noncompressedMap.remove(key);
compressedMap.remove(key);
while (remove(values, value));
putAll(key, values);
}
@Override
public void clear() {
noncompressedMap.clear();
compressedMap.clear();
_size = 0;
}
}