/******************************************************************************* * Copyright (c) 2004-2008 Gabor Bergmann and Daniel Varro * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Gabor Bergmann - initial API and implementation *******************************************************************************/ package org.eclipse.incquery.runtime.rete.tuple; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import org.eclipse.incquery.runtime.rete.collections.CollectionsFactory; /** * @author Gabor Bergmann * * Indexes a collection of Tuples according to their masks. */ public class MaskedTupleMemory implements Clearable, Iterable<Tuple> { /** * Counts the number of occurences of each pattern. Element is deleted if # of occurences drops to 0. */ protected Map<Tuple, Collection<Tuple>> matchings; /** * The mask used to index the matchings */ protected TupleMask mask; /** * @param mask * The mask used to index the matchings */ public MaskedTupleMemory(TupleMask mask) { super(); this.mask = mask; matchings = CollectionsFactory.getMap();//new HashMap<Tuple, Collection<Tuple>>(); } /** * Adds a pattern occurence to the memory * * @param ps * * @return true if new signature encountered */ public boolean add(Tuple ps) { Tuple signature = mask.transform(ps); return add(ps, signature); } /** * Adds a pattern occurence to the memory, with given signature * * @param ps * @param signature * * @return true if new signature encountered */ public boolean add(Tuple ps, Tuple signature) { Collection<Tuple> coll = matchings.get(signature); boolean change = (coll == null); if (change) { coll = new TupleMemory(); matchings.put(signature, coll); } if (!coll.add(ps)) { throw new IllegalStateException(); } return change; } /** * Removes a pattern occurence from the memory * * @return true if this was the the last occurence of the signature */ public boolean remove(Tuple ps) { Tuple signature = mask.transform(ps); return remove(ps, signature); } /** * Removes a pattern occurence from the memory, with given signature * * @return true if this was the the last occurence of the signature */ public boolean remove(Tuple ps, Tuple signature) { Collection<Tuple> coll = matchings.get(signature); if (!coll.remove(ps)) { throw new IllegalStateException(); } boolean change = coll.isEmpty(); if (change) matchings.remove(signature); return change; } /** * Retrieves entries that have the specified signature * * @return collection of matchings found */ public Collection<Tuple> get(Tuple signature) { return matchings.get(signature); } public void clear() { matchings.clear(); } /** * Retrieves a read-only collection of exactly those signatures for which at least one tuple is stored * * @return collection of significant signatures */ public Collection<Tuple> getSignatures() { return matchings.keySet(); } public Iterator<Tuple> iterator() { return new MaskedPatternIterator(this); } class MaskedPatternIterator implements Iterator<Tuple> { // private MaskedTupleMemory memory; Iterator<Collection<Tuple>> signatureGroup; Iterator<Tuple> element; public MaskedPatternIterator(MaskedTupleMemory memory) { // this.memory = memory; signatureGroup = memory.matchings.values().iterator(); Set<Tuple> emptySet = Collections.emptySet(); element = emptySet.iterator(); } public boolean hasNext() { return (element.hasNext() || signatureGroup.hasNext()); } public Tuple next() throws NoSuchElementException { if (element.hasNext()) return element.next(); else if (signatureGroup.hasNext()) { element = signatureGroup.next().iterator(); return element.next(); } else throw new NoSuchElementException(); } /** * Not implemented */ public void remove() { } } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return "MTM<" + mask + "|" + matchings + ">"; } public int getSize() { return matchings.values().size(); } }