All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.aksw.sparqlify.database.IndirectEquiMap Maven / Gradle / Ivy

There is a newer version: 3.17.0-1
Show newest version
package org.aksw.sparqlify.database;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.aksw.commons.util.Pair;

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

public class IndirectEquiMap {
	private Map keyToToken = new HashMap();
	private Multimap tokenToKeys = HashMultimap.create(); 
	private Map tokenToValue = new HashMap();
	
	private int nextToken = 0;
	
	public Set keySet() {
		return keyToToken.keySet();
	}
	
	public Multimap getEquivalences()
	{
		return tokenToKeys;
	}
	
	public Collection getEquivalences(K key) {
		return tokenToKeys.get(keyToToken.get(key));
	}
	
	
	private void putKeyToken(K key, int token) {
		keyToToken.put(key, token);
		tokenToKeys.put(token, key);		
	}
	
	
	public void stateEqual(K a, K b, V value) {
		stateEqual(a, b, value, true);		
	}
	
	
	public Pair stateEqual(K a, K b) {
		return stateEqual(a, b, null, false);
	}
	

	/*
	public Collection<> stateEqual(Collection keys) {
		
	}*/
	
	public void stateEqual(Collection keys, V value) {
		int newToken = ++nextToken;
		
		for(K key : keys) {
			Integer oldToken = keyToToken.get(key);
			if(oldToken != null) {
				tokenToValue.remove(oldToken);
				tokenToKeys.putAll(newToken, tokenToKeys.get(oldToken));
				tokenToKeys.removeAll(oldToken);
			}
			
			putKeyToken(key, newToken);
		}

		tokenToValue.put(newToken, value);
	}
	
	
	/**
	 * States an equality between keys.
	 * 
	 * if overwrite is true, conflicts can not occur as they are overwritten with value. Return value is always null.
	 * if overwrite is false, in case of conflict the pair of conflicting values is returned
	 * 
	 * Conflicts can be resolved using stateEqual(a, b, value)
	 * 
	 * 
	 * @param a
	 * @param b
	 */
	private Pair stateEqual(K a, K b, V value, boolean overwrite) {
		Integer ta = keyToToken.get(a);
		Integer tb = keyToToken.get(b);
		
		if(ta == null) {
			if(tb == null) {
				int token = ++nextToken;
				
				putKeyToken(a, token);
				putKeyToken(b, token);
				
			} else {
				putKeyToken(a, tb);
			}
		} else {
			if(tb == null) {
				putKeyToken(b, ta);
			} else {
				
				V va = tokenToValue.get(ta);
				V vb = tokenToValue.get(tb);

				if(va != null && vb != null && !va.equals(vb)) {
					// Conflict: Equality stated, but two distinct values
					if(overwrite) {
						va = value;
					} else  {
						return Pair.create(va, vb);
					}
				}
				
				if(va == null) {
					va = vb;
				}
				
				// Copy to avoid ConcurrentModificationException
				Collection ka = new ArrayList(tokenToKeys.get(ta));
				Collection kb = new ArrayList(tokenToKeys.get(tb));
				
				Collection tmp;
				int tt;
				if(kb.size() > ka.size()) {
					tmp = ka;
					ka = kb;
					kb = tmp;
					
					tt = ta;
					ta = tb;
					tb = tt;
				}
				
				for(K k : kb) {
					tokenToKeys.remove(tb, k);
					putKeyToken(k, ta);
				}

				if(va != null) {
					tokenToValue.put(ta, va);
				}
			}
		}

		return null;
	}
	
	
	/**
	 * Puts a new value, overwrites existing ones.
	 * 
	 * 
	 * @param key
	 * @param value
	 */
	public void put(K key, V value) {
		Integer token = keyToToken.get(key);
		if(token == null) {
			token = ++nextToken;
			keyToToken.put(key, token);
		}
		
		tokenToValue.put(token, value);
		tokenToKeys.put(token, key);
	}
	
	public V get(K key) {
		Integer token = keyToToken.get(key);
		if(token == null) {
			return null;
		}
		
		return tokenToValue.get(token);
	}


	public boolean isEqual(K a, K b) {
		Integer ta = keyToToken.get(a);
		return ta != null && ta.equals(keyToToken.get(b));
	}
	
	@Override
	public String toString() {
		String result = "[";
		boolean isFirst = true;
		for(Entry> entry : tokenToKeys.asMap().entrySet()) {
			if(!isFirst) {
				result += ", ";
			}
			
			result += entry.getValue() + ": " + tokenToValue.get(entry.getKey());
		}
		result += "]";
		return result;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy