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

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

The newest version!
package org.aksw.sparqlify.database;

import java.util.AbstractSet;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

import com.google.common.collect.Sets;

/**
 * IMPORTANT: If you are working with a child set, then do not modify the parent,
 * or things might go out of sync.
 * So the parent must remain unchanged while working with a child set
 * 
 * @author Claus Stadler 
 *
 * @param 
 */
public class NestedSet
	extends AbstractSet
{
	private Set parent = null;

	// if true, effective items is a view based on the parent't effective clauses
	// if false, effective items is a copy on its own behalf (independent of the parent)	
	
	public boolean isView() {
		return addedItems != null;
	}
	
	
	int parentEffectiveItemCount;
	
	int cachedSize;
	private Set effectiveItems;
	private Set addedItems;
	private Set removedItems;

	public NestedSet(Set items, boolean asView) {
		if(asView) {
			this.addedItems = new HashSet();
			this.removedItems = new HashSet();
			this.parentEffectiveItemCount = items.size();
			this.cachedSize = parentEffectiveItemCount;
			this.effectiveItems = Sets.union(addedItems, Sets.difference(items, removedItems));
		} else {
			if(items == null) {
				this.effectiveItems = new HashSet();
			} else {
				this.effectiveItems = items;
				this.cachedSize = effectiveItems.size();
			}
		}
	}
	
	private void checkCopy(Set deltaSet) {
		if(deltaSet.size() > 4 * parentEffectiveItemCount) {
			this.effectiveItems = new HashSet(effectiveItems);
			this.addedItems = null;
			this.removedItems = null;
		}
	}
	
	/*
	@Override
	public boolean addAll(Collection items) {
		boolean result = false;
		for(T item : items) {
			result = result || add(item);
		}
		
		return result;
	}*/
	
	public boolean add(T item) {
		if(effectiveItems.contains(item)) {
			return false;
		}

		if(isView()) {
			checkCopy(addedItems);
			
			if(isView()) {
				addedItems.add(item);
				removedItems.remove(item);				
			}
		}
		
		if(!isView()){
			effectiveItems.add(item);
		}		
		
		++cachedSize;
		onAdd(item);
		return true;
	}

	/**
	 * State a clause as removed - equivalent to stating the clause as unsatisfiable
	 * 
	 * @param clause
	 */
	public boolean remove(Object item) {
		if(!effectiveItems.contains(item)) {
			return false;
		}

		if(isView()) {	
			checkCopy(removedItems);

			if(isView()) {
				removedItems.add((T)item);
				addedItems.remove(item);
			}
		}
		
		if(!isView()) {
			effectiveItems.remove(item);
		}
		
		onRemove((T)item);
		--cachedSize;
		return true;
	}
	
	protected void onAdd(T item) {
	}
	
	protected void onRemove(T item) {
	}
	
	public int getNestingDepth() {
		if(parent != null && parent instanceof NestedSet) {
			return 1 + ((NestedSet)parent).getNestingDepth();
		}
		
		return 0;
	}
	
	@Override
	public boolean contains(Object item) {
		return effectiveItems.contains(item);
	}
	
	/**
	 * Whether the given item is present in *this* instance, rather
	 * than being actually a member of one of the parents 
	 * 
	 * @param item
	 * @return
	 */
	//@Override
	public boolean containsDirect(Object item) {
		return isView()
				? addedItems.contains(item)
				:effectiveItems.contains(item);
	}
	
	@Override
	public Iterator iterator() {
		return effectiveItems.iterator();
	}

	@Override
	public int size() {
		return cachedSize;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result
				+ ((effectiveItems == null) ? 0 : effectiveItems.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		NestedSet other = (NestedSet) obj;
		if (effectiveItems == null) {
			if (other.effectiveItems != null)
				return false;
		} else if (!effectiveItems.equals(other.effectiveItems))
			return false;
		return true;
	}
	
	
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy