

//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//_/_/
//_/_/  This file is part of CMSDK version 2.0.0.170915_Beta4 (15 September 2017)
//_/_/  
//_/_/  developed by
//_/_/  
//_/_/  Communicative Machines Ltd. 
//_/_/    http://cmlabs.com/
//_/_/  Copyright (c) 2017
//_/_/  
//_/_/  in collaboration with 
//_/_/  
//_/_/  Icelandic Institute for Intelligent Machines ses
//_/_/    Menntavegur 1
//_/_/    101 Reykjavik
//_/_/    ICELAND
//_/_/    http://www.iiim.is/
//_/_/
//_/_/  and is released under the following
//_/_/  
//_/_/  EXTENDED BSD License
//_/_/
//_/_/  Redistribution and use in source and binary forms, with or without
//_/_/  modification, is permitted provided that the following conditions 
//_/_/  are met:
//_/_/
//_/_/  - Redistributions of source code must retain the above copyright 
//_/_/    and collaboration notice, this list of conditions and the following 
//_/_/    disclaimer.
//_/_/
//_/_/  - Redistributions in binary form must reproduce the above copyright 
//_/_/    notice, this list of conditions and the following disclaimer in the 
//_/_/    documentation and/or other materials provided with the distribution.
//_/_/
//_/_/  - Neither the name of its copyright holders nor the names of its 
//_/_/    contributors may be used to endorse or promote products derived from 
//_/_/    this software without specific prior written permission.
//_/_/
//_/_/  - CADIA Clause: The license granted in and to the software under this 
//_/_/    agreement is a limited-use license. The software may not be used in 
//_/_/    furtherance of: (i) intentionally causing bodily injury or severe 
//_/_/    emotional harm to any person; (ii) invading the personal privacy or 
//_/_/    violating the human rights of any person; or (iii) committing or 
//_/_/    preparing for any act of war. 
//_/_/
//_/_/  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
//_/_/  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
//_/_/  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 
//_/_/  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 
//_/_/  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
//_/_/  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
//_/_/  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
//_/_/  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
//_/_/  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
//_/_/  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
//_/_/  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//_/_/
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#if !defined(_MESSAGEINDEX_H_)
#define _MESSAGEINDEX_H_

#include "DataMessage.h"
#include "PsyTime.h"
#include "Subscriptions.h"

namespace	cmlabs {


class MessageIndex {
public:
	static bool UnitTest();

	MessageIndex();
	~MessageIndex();

	bool setDefaultTTL(uint64 defaultTTL);

	bool addIndexKey(const char* key, uint8 type);
	bool removeIndexKey(const char* key, uint8 type);

	bool setFileStorage(const char* dir, uint32 buffertime, const char* indexfilename = "index.db");

	bool addMessage(DataMessage* msg);

	char* queryMessages(RetrieveSpec* spec, uint32 &size, uint32 &count);

	uint32 getCount();

	bool doMaintenance();

private:

	bool addMessageToTime(DataMessage* msg);
	bool addMessageToString(DataMessage* msg);
	bool addMessageToInteger(DataMessage* msg);
	bool addMessageToFloat(DataMessage* msg);

	template <typename T>
	bool deleteIndexKey(const char* key, std::map<std::string, std::multimap<T, DataMessage*> > &maps);

	template <typename T>
	bool removeMessage(DataMessage* msg, std::multimap<T, DataMessage*> &map, T &val);

	template <typename T>
	char* queryMessages(uint32 from, uint32 to, PsyType &type, uint32 maxcount, uint64 maxage, uint32 &size, uint32 &count, std::multimap<T, DataMessage*> &map);
	template <typename T>
	char* queryMessages(T start, uint32 from, uint32 to, PsyType &type, uint32 maxcount, uint64 maxage, uint32 &size, uint32 &count, std::multimap<T, DataMessage*> &map);
	template <typename T>
	char* queryMessages(T start, T end, uint32 from, uint32 to, PsyType &type, uint32 maxcount, uint64 maxage, uint32 &size, uint32 &count, std::multimap<T, DataMessage*> &map);

	typedef std::pair <uint64, DataMessage*> Time_Pair;
	typedef std::pair <std::string, DataMessage*> String_Pair;
	typedef std::pair <int64, DataMessage*> Int_Pair;
	typedef std::pair <float64, DataMessage*> Float_Pair;
	typedef std::pair <PsyType, DataMessage*> Type_Pair;

	std::map<std::string, std::multimap<uint64, DataMessage*> > timeMaps;
	std::map<std::string, std::multimap<std::string, DataMessage*> > stringMaps;
	std::map<std::string, std::multimap<int64, DataMessage*> > integerMaps;
	std::map<std::string, std::multimap<float64, DataMessage*> > floatMaps;

	std::multimap<PsyType, DataMessage*>* typeMap;
	std::multimap<uint64, DataMessage*>* timeMap;
	std::multimap<uint64, DataMessage*> eolMap;
	uint64 lastMaintenance;

	std::string dir;
	std::string indexfilename;
	int32 buffertime;
	int32 maintenanceInterval;

	uint64 defaultTTL;
};


} // namespace cmlabs

#endif // _MESSAGEINDEX_H_
