blob: 554a393e99f298d58ee7314c65c37c5fb56d0236 [file] [log] [blame]
/*******************************************************************************
* 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.viatra2.gtasm.patternmatcher.incremental.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;
/**
* @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 = 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+">";
}
}