package net.tomp2p.message;
import java.util.Map;
import java.util.NavigableMap;
import java.util.TreeMap;
import net.tomp2p.peers.Number160;
import net.tomp2p.peers.Number640;
import net.tomp2p.storage.Data;
import net.tomp2p.utils.Utils;
public class DataMap {
private final NavigableMap<Number640, Data> dataMap;
private final NavigableMap<Number160, Data> dataMapConvert;
private final Number160 locationKey;
private final Number160 domainKey;
private final Number160 versionKey;
private final boolean convertMeta;
public DataMap(final NavigableMap<Number640, Data> dataMap) {
this(dataMap, false);
}
public DataMap(final NavigableMap<Number640, Data> dataMap, boolean convertMeta) {
this.dataMap = dataMap;
this.dataMapConvert = null;
this.locationKey = null;
this.domainKey = null;
this.versionKey = null;
this.convertMeta = convertMeta;
}
public DataMap(final Number160 locationKey, final Number160 domainKey, final Number160 versionKey,
final NavigableMap<Number160, Data> dataMapConvert) {
this(locationKey, domainKey, versionKey, dataMapConvert, false);
}
public DataMap(final Number160 locationKey, final Number160 domainKey, final Number160 versionKey,
final NavigableMap<Number160, Data> dataMapConvert, boolean convertMeta) {
this.dataMap = null;
this.dataMapConvert = dataMapConvert;
this.locationKey = locationKey;
this.domainKey = domainKey;
this.versionKey = versionKey;
this.convertMeta = convertMeta;
}
public boolean isConvertMeta() {
return convertMeta;
}
public NavigableMap<Number640, Data> dataMap() {
return convert(this);
}
public Map<Number160, Data> dataMapConvert() {
return dataMapConvert;
}
public Number160 locationKey() {
return locationKey;
}
public Number160 domainKey() {
return domainKey;
}
public Number160 versionKey() {
return versionKey;
}
/**
* @return The size of either the datamap with the number480 as key, or datamap with the number160 as key
*/
public int size() {
if (dataMap != null) {
return dataMap.size();
} else if (dataMapConvert != null) {
return dataMapConvert.size();
}
return 0;
}
/**
* @return True if we have number160 stored and we need to add the location and domain key
*/
public boolean isConvert() {
return dataMapConvert != null;
}
public NavigableMap<Number640, Number160> convertToHash() {
NavigableMap<Number640, Number160> retVal = new TreeMap<Number640, Number160>();
if (dataMap != null) {
for (Map.Entry<Number640, Data> entry : dataMap.entrySet()) {
retVal.put(entry.getKey(), entry.getValue().hash());
}
} else if (dataMapConvert != null) {
for (Map.Entry<Number160, Data> entry : dataMapConvert.entrySet()) {
retVal.put(new Number640(locationKey, domainKey, entry.getKey(), versionKey), entry
.getValue().hash());
}
}
return retVal;
}
private static NavigableMap<Number640, Data> convert(final DataMap d) {
final NavigableMap<Number640, Data> dataMap3;
if (d.dataMapConvert != null) {
dataMap3 = new TreeMap<Number640, Data>();
for (Map.Entry<Number160, Data> entry : d.dataMapConvert.entrySet()) {
dataMap3.put(new Number640(d.locationKey, d.domainKey, entry.getKey(), d.versionKey),
entry.getValue());
}
} else {
dataMap3 = d.dataMap;
}
return dataMap3;
}
@Override
public int hashCode() {
int hashCode = 31;
final Map<Number640, Data> dataMap = convert(this);
for (Map.Entry<Number640, Data> entry : dataMap.entrySet()) {
hashCode ^= entry.getKey().hashCode();
if (entry.getValue() != null) {
hashCode ^= entry.getValue().hashCode();
}
}
return hashCode;
}
@Override
public boolean equals(final Object obj) {
if (!(obj instanceof DataMap)) {
return false;
}
if (obj == this) {
return true;
}
final Map<Number640, Data> dataMapThis = convert(this);
final Map<Number640, Data> dataMapOther = convert((DataMap) obj);
final boolean test1 = Utils.isSameSets(dataMapThis.keySet(), dataMapOther.keySet());
final boolean test2 = Utils.isSameSets(dataMapThis.values(), dataMapOther.values());
return test1 && test2;
}
}