//
// Copyright (C) 2007 Institut fuer Telematik, Universitaet Karlsruhe (TH)
//
// This program 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.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//

/**
 * @file MyMyDHTLookupStorage.h
 * @author Dilum Bandara
 * @version 0.1.1
 * @date 08/01/2010
 */

#ifndef __MY_DHTLOOKUPSTORAGE_H_
#define __MY_DHTLOOKUPSTORAGE_H_

#include <set>
#include <vector>
#include <map>
#include <sstream>
#include <omnetpp.h>
#include <NodeHandle.h>
#include <InitStages.h>
#include <BinaryValue.h>
#include <NodeVector.h>
#include <CommonMessages_m.h>
#include <OverlayKey.h> 

/**
 * DHT data storage module
 * This modul contains the data storage of the DHT implementation.
 *
 * @author Dilum Bandara
 * @see DHT
 */


struct DhtLookupEntry
{
	uint32_t noLookups;		//No of lookups for the key
	uint32_t totalHops;		//No of hops used to reach this node sofar
	double demand;			//Demand for the key
    bool success;			//Whether query was answered
	bool pending;			//Whether a cache request is pending
};

struct CacheEntry
{
    OverlayKey key;			//Key
    bool success;			//Was query succefully answered by cache
	bool pending;			//Is a cache request is pending
};

typedef std::vector<std::pair<OverlayKey, DhtLookupEntry> > DhtLookupVector;
typedef std::map<OverlayKey, DhtLookupEntry> DhtLookupMap;
typedef std::map<double, CacheEntry> ProfitMap;
//typedef std::map<int, CacheEntry> ProfitMap;

class MyDHTLookupStorage : public cSimpleModule
{
  public:

    virtual int numInitStages() const
    {
        return MAX_STAGE_APP + 1;
    }
    virtual void initialize(int stage);
    virtual void handleMessage(cMessage* msg);

    /**
     * Returns number of stored data items in the map
     *
     * @return number of stored data items
     */
    virtual uint32_t getSize();

    /**
     * Clears all stored data items
     */
    virtual void clear();

    /**
     * Returns a pointer to the requested stored data item
     *
     * @param key The key of the data item
     *
     * @return pointer to the data item or NULL if data item is not available
     */
    DhtLookupEntry* getLookupEntry(const OverlayKey& key);

    /**
     * Returns the stored data items with a given key, kind and id
     *
     * @return all the stored entries in table
     */
    virtual DhtLookupVector* getLookupVector();

    /**
     * Store a new data item in the map
     *
     * @param key The key of the data item to be stored
     * @param no of hops that the lookup has travled so far
     * @param success Whether lookup was successful at this node or had to forward
	 * @param alpha Alpha for weight query demand
	 * @param removeLookupThreshold Threshold to remove stat about query demand
	 * @return whether added key is already in lookup list
     */
    virtual bool addLookup(const OverlayKey& key, uint32_t hops, bool success,
							double alpha, double removeLookupThreshold);

    /**
     * Removes a certain lookup item from the map
     *
     * @param key The key of the data item to be removed
     *
     */
    virtual void removeLookup(const OverlayKey& key);

    /**
     * Dump filtered local lookup records into a vector
     *
     * @param key The key of the lookup items to dump
     *
     * @return the vector containing all matching data items
     */
    DhtLookupVector* dumpLookup(const OverlayKey& key = OverlayKey::UNSPECIFIED_KEY);

	/**
	 * set whether a cache request is pending for the lookup entry
	 *
	 * @param key The key of the lookup item
	 * @param pending True if a query is pending
	 */
	virtual void setPending(const OverlayKey& key, bool pending);

  protected:
    DhtLookupMap lookupMap; /**< internal representation of the data storage */
};

#endif
