package edu.uniklu.itec.mosaix.engine;
import java.util.HashMap;
/*
* This file is part of the Caliph and Emir project: http://www.SemanticMetadata.net.
*
* Caliph & Emir is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Caliph & Emir 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Caliph & Emir; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Copyright statement:
* --------------------
* (c) 2002-2007 by Mathias Lux (mathias@juggle.at), Lukas Esterle & Manuel Warum.
* http://www.juggle.at, http://www.SemanticMetadata.net
*/
/**
* <p>Outlines a strategy that takes the usage count
* of an image into account.</p>
* <p>To achieve this, the following to things are
* required for this strategy to be actually useful:</p>
* <ol>
* <li>The implementation of the <code>WeightingData</code>
* instance must implement <code>hashCode()</code> in such
* a way, that the resulting integer is always equal to
* other instances handling the very same image.</li>
* <li>The engine using this strategy also has to add this
* strategy to its list of observers.</li>
* </ol>
* <p>If any of the above preconditions are not given,
* then this strategy will yield false factors, most
* often just <code>1.0f</code>.</p>
*
* @author Manuel Warum
* @version 1.02
* @see java.lang.Object#hashCode()
*/
public final class LeastUsedWeightingStrategy implements WeightingStrategy, EngineObserver {
private HashMap<Integer, Integer> usageCount_;
/**
* Instantiates a new instance with the initial state.
*/
public LeastUsedWeightingStrategy() {
reset();
}
public float getFactor(final WeightingData data) {
int hash = data.hashCode();
int n = (usageCount_.containsKey(hash) ? usageCount_.get(hash) : 0) + 1;
// Logging.log(this, "Image " + hash + " has been used " + n + " times already. " + n + "^-1 penalty.");
return 1f / (float) n; // force floating point arithmetic
}
/**
* Resets the usage counter to its initial state.
* All usage counters will be removed or reset to
* zero.
*/
public void reset() {
usageCount_ = new HashMap<Integer, Integer>();
// Logging.log(this, "(Re-)Set to initial state");
}
public void notifyState(final WeightingData data, int state) {
if (state == EngineObserver.USED && data != null)
shiftCounter(data.hashCode(), 1);
}
private void shiftCounter(int hash, int shaft) {
int cnt = usageCount_.containsKey(hash) ? usageCount_.get(hash) : 0;
cnt += shaft;
usageCount_.put(hash, cnt);
}
}