package com.vitco.util.misc;
import java.util.ArrayList;
import java.util.HashMap;
/**
* This class is used to keep track of String.
*
* Strings can be assigned to indices. One can then check if a given string
* was already seen and to which index it was assigned.
*
* The class further supports migration of all strings that have a certain
* index to another index (very efficient!).
*/
public final class StringIndexer {
// maps all seen points to internal ids
private final HashMap<String, Integer> seen = new HashMap<String, Integer>();
// internal id counter
private int _idCounter = 1;
// maps local ids to external ids
private final HashMap<Integer, Integer> local2ext = new HashMap<Integer, Integer>();
// maps external ids to local ids (arrays)
private final HashMap<Integer, ArrayList<Integer>> ext2local = new HashMap<Integer, ArrayList<Integer>>();
// get one internal id (allocate if none assigned yet)
private Integer getLocalId(Integer id) {
ArrayList<Integer> _idList = ext2local.get(id);
if (_idList == null) {
_idList = new ArrayList<Integer>();
ext2local.put(id, _idList);
Integer _id = _idCounter++;
_idList.add(_id);
local2ext.put(_id, id);
}
return _idList.get(0);
}
// add a point to this manager
public final void index(String str, Integer id) {
Integer _id = getLocalId(id);
seen.put(str, _id);
}
// check where/if a point was seen before
// (returns null if not seen before)
public final Integer getIndex(String str) {
Integer _id = seen.get(str);
if (_id != null) {
return local2ext.get(_id);
}
return null;
}
// migrate all points from one index to another
public final void changeIndex(Integer newIndex, Integer oldIndex) {
// initialize the local id
getLocalId(newIndex);
// remap old
ArrayList<Integer> list = ext2local.get(oldIndex);
// this is necessary since if all points are seen,
// there might not be points tracked for the old id
if (list != null) {
// remap
for (Integer local : list) {
local2ext.put(local, newIndex);
}
// remove and add
ext2local.get(newIndex).addAll(
ext2local.remove(oldIndex)
);
}
}
}