/* XXL: The eXtensible and fleXible Library for data processing
Copyright (C) 2000-2011 Prof. Dr. Bernhard Seeger
Head of the Database Research Group
Department of Mathematics and Computer Science
University of Marburg
Germany
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; If not, see <http://www.gnu.org/licenses/>.
http://code.google.com/p/xxl/
*/
package xxl.core.collections.containers.recordManager;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import xxl.core.functions.Constant;
import xxl.core.io.converters.Converter;
import xxl.core.io.converters.FixedSizeConverter;
import xxl.core.io.converters.LongConverter;
import xxl.core.io.converters.MapConverter;
import xxl.core.util.LongIdGenerator;
/**
* This class implements a TIdManager which uses a main
* memory HashMap to store the relationship between external
* identifyers (of type Long) and tuple identifyers inside
* the record manager.
* The identifyers are Long values which are produced by
* a LongIdGenerator.
*/
public class MapTIdManager implements TIdManager {
/**
* A main memory map to store the relationship between
* external identifiers (of type Long) and tuple
* identifiers inside the record manager.
*/
protected Map map;
/**
* An id generator which produces identifiers that are
* Long values.
*/
protected LongIdGenerator idGenerator;
/**
* Converter for the map object.
*/
protected Converter mapConverter;
/**
* Converter for the objects inside the TIds.
*/
protected FixedSizeConverter idConverter;
/**
* Constructs a new MapTIdManager.
* @param idConverter Converter for the specific Ids which are used
* inside the TIds.
*/
public MapTIdManager (FixedSizeConverter idConverter) {
this.idConverter = idConverter;
map = new HashMap();
idGenerator = new LongIdGenerator();
mapConverter = new MapConverter(
LongConverter.DEFAULT_INSTANCE,
TId.getConverter(idConverter),
MapConverter.HASH_MAP_FACTORY_METHOD
);
}
/**
* Returns a converter for the identifyer which
* occur inside TIds.
* @return A converter for the identifyer which
* occur inside TIds.
*/
public FixedSizeConverter getIdConverterInsideTIds() {
return idConverter;
}
/**
* Translates an identifyer into a tuple identifyer.
* If the id does not exist then the return value
* is unspecified.
* @param id identifyer
* @return the tuple identifyer for the given identifyer.
*/
public TId query(Object id) {
return (TId) map.get(id);
}
/**
* Returns all currently stored ids in arbitrary order. If null
* is returned, then there is an identity mapping between
* Ids and TIds.
* @return Iterator with the ids or null.
*/
public Iterator ids() {
return map.keySet().iterator();
}
/**
* Inserts a new TId and returns an identifyer.
* The RecordManager registers a tuple identifyer
* and gets back an identifyer for the object (which
* can also be the same tid). The TIdManager must
* be able to translate the returned Object back into
* the same TId.
* @param tid tuple identifyer
* @return the identifyer under which the Record
* is reachable from outside the RecordManager.
*/
public Object insert(TId tid) {
Object id = new Long(idGenerator.getIdentifyer(new Constant(map.keySet())));
map.put(id,tid);
return id;
}
/**
* Signals that an identifyer gets a new tuple identifyer.
* Here, the new TId is inserted into the map.
* @param id The identifyer used inside the application.
* @param newTId The new tuple identifyer inside the RecordManager.
*/
public void update(Object id, TId newTId) {
Object oldObj = map.put(id, newTId);
if (oldObj==null)
throw new RuntimeException("The given id is not valid");
}
/**
* Signals that the identifier is no longer needed. The
* identifyer is taken out of the map.
* @param id the identifyer which has been given out
* is no longer needed by the RecordManager.
*/
public void remove(Object id) {
if (map.remove(id)==null)
throw new RuntimeException("The given id is not valid");
idGenerator.removeIdentifyer(((Long) id).longValue());
}
/**
* Signals that all identifiers are no longer needed.
*/
public void removeAll() {
map.clear();
idGenerator.reset();
}
/**
* Closes this TIDManager. The map must still be accessible
* for the write method. So, nothing can be done here.
*/
public void close() {
removeAll();
}
/**
* Determines if the TIdManager uses TId-Links. This is
* only possible iff the Ids to be translated are TIds.
* @return true iff links are uses inside the RecordManager.
*/
public boolean useLinks() {
return false;
}
/**
* Returns a converter for the ids which are translated by the
* manager into TIds.
* @return a converter for serializing the identifiers.
*/
public FixedSizeConverter objectIdConverter() {
return LongConverter.DEFAULT_INSTANCE;
}
/**
* Returns the size of the ids in bytes.
* @return the size in bytes of each id.
*/
public int getIdSize() {
return LongConverter.DEFAULT_INSTANCE.getSerializedSize();
}
/**
* Read the map from a DataInput.
* @param dataInput DataInput used.
* @throws IOException
*/
public void read(DataInput dataInput) throws IOException {
// map = (Map) SerializableConverter.DEFAULT_INSTANCE.read(dataInput);
map = (Map) mapConverter.read(dataInput);
idGenerator.read(dataInput);
}
/**
* Writes the map to a DataOutput.
* @param dataOutput DataOutput used.
* @throws IOException
*/
public void write(DataOutput dataOutput) throws IOException {
// SerializableConverter.DEFAULT_INSTANCE.write(dataOutput, map);
mapConverter.write(dataOutput, map);
idGenerator.write(dataOutput);
}
}