version 0.2.17
[fms.git] / include / freenet / iindexinserter.h
1 #ifndef _iindexinserter_\r
2 #define _iindexinserter_\r
3 \r
4 #include "../idatabase.h"\r
5 #include "../ilogger.h"\r
6 #include "../option.h"\r
7 #include "../datetime.h"\r
8 #include "../stringfunctions.h"\r
9 #include "ifreenetregistrable.h"\r
10 #include "ifcpconnected.h"\r
11 #include "ifcpmessagehandler.h"\r
12 #include "iperiodicprocessor.h"\r
13 \r
14 #ifdef XMEM\r
15         #include <xmem.h>\r
16 #endif\r
17 \r
18 template <class IDTYPE>\r
19 class IIndexInserter:public IFreenetRegistrable,public IFCPConnected,public IFCPMessageHandler,public IPeriodicProcessor,public IDatabase,public ILogger\r
20 {\r
21 public:\r
22         IIndexInserter();\r
23         IIndexInserter(FCPv2 *fcp);\r
24         virtual ~IIndexInserter()               {}\r
25 \r
26         virtual void FCPConnected();\r
27         virtual void FCPDisconnected();\r
28         virtual const bool HandleMessage(FCPMessage &message);\r
29 \r
30         virtual void Process();\r
31 \r
32         virtual void RegisterWithThread(FreenetMasterThread *thread);\r
33 \r
34 protected:\r
35         void InitializeIIndexInserter();\r
36         virtual void Initialize()=0;            // initialize m_fcpuniquename\r
37         virtual const bool HandlePutSuccessful(FCPMessage &message)=0;\r
38         virtual const bool HandlePutFailed(FCPMessage &message)=0;\r
39         virtual const bool StartInsert(const IDTYPE &id)=0;\r
40         virtual void CheckForNeededInsert()=0;\r
41         virtual void RemoveFromInsertList(const IDTYPE id);\r
42 \r
43         std::vector<IDTYPE> m_inserting;                // list of ids we are inserting\r
44         std::string m_messagebase;\r
45         DateTime m_lastchecked;\r
46 \r
47         // these MUST be populated by child class\r
48         std::string m_fcpuniquename;\r
49 };\r
50 \r
51 template <class IDTYPE>\r
52 IIndexInserter<IDTYPE>::IIndexInserter()\r
53 {\r
54         InitializeIIndexInserter();\r
55 }\r
56 \r
57 template <class IDTYPE>\r
58 IIndexInserter<IDTYPE>::IIndexInserter(FCPv2 *fcp):IFCPConnected(fcp)\r
59 {\r
60         InitializeIIndexInserter();\r
61 }\r
62 \r
63 template <class IDTYPE>\r
64 void IIndexInserter<IDTYPE>::FCPConnected()\r
65 {\r
66         // make sure variables have been initialized by the derived class\r
67         if(m_fcpuniquename=="")\r
68         {\r
69                 m_log->WriteLog(LogFile::LOGLEVEL_FATAL,"IIndexInserter<IDTYPE>::FCPConnected fcpuniquename not initialized correctly!");\r
70         }\r
71         if(m_fcpuniquename.find("|")!=std::string::npos)\r
72         {\r
73                 m_log->WriteLog(LogFile::LOGLEVEL_FATAL,"IIndexInserter<IDTYPE>::FCPConnected fcpuniquename contains | character!  This is not a valid character!");\r
74         }\r
75 \r
76         m_inserting.clear();\r
77 }\r
78 \r
79 template <class IDTYPE>\r
80 void IIndexInserter<IDTYPE>::FCPDisconnected()\r
81 {\r
82         \r
83 }\r
84 \r
85 template <class IDTYPE>\r
86 const bool IIndexInserter<IDTYPE>::HandleMessage(FCPMessage &message)\r
87 {\r
88 \r
89         if(message["Identifier"].find(m_fcpuniquename)==0)\r
90         {\r
91                 if(message.GetName()=="URIGenerated")\r
92                 {\r
93                         return true;\r
94                 }\r
95 \r
96                 if(message.GetName()=="PutSuccessful")\r
97                 {\r
98                         return HandlePutSuccessful(message);\r
99                 }\r
100 \r
101                 if(message.GetName()=="PutFailed")\r
102                 {\r
103                         return HandlePutFailed(message);\r
104                 }\r
105 \r
106                 if(message.GetName()=="IdentifierCollision")\r
107                 {\r
108                         // remove one of the ids from the requesting list\r
109                         IDTYPE id;\r
110                         std::vector<std::string> idparts;\r
111                         StringFunctions::Split(message["Identifier"],"|",idparts);\r
112                         StringFunctions::Convert(idparts[1],id);\r
113                         RemoveFromInsertList(id);\r
114                         m_log->WriteLog(LogFile::LOGLEVEL_DEBUG,"IIndexInserter<IDTYPE>::HandleMessage IdentifierCollision for "+m_fcpuniquename+" "+message["Identifier"]);\r
115                         return true;\r
116                 }\r
117         }\r
118 \r
119         return false;\r
120 }\r
121 \r
122 template <class IDTYPE>\r
123 void IIndexInserter<IDTYPE>::InitializeIIndexInserter()\r
124 {\r
125         m_fcpuniquename="";\r
126         Option::Instance()->Get("MessageBase",m_messagebase);\r
127         m_lastchecked.SetToGMTime();\r
128 }\r
129 \r
130 template <class IDTYPE>\r
131 void IIndexInserter<IDTYPE>::Process()\r
132 {\r
133         DateTime now;\r
134         now.SetToGMTime();\r
135 \r
136         if(m_lastchecked<(now-(1.0/1440.0)))\r
137         {\r
138                 CheckForNeededInsert();\r
139                 m_lastchecked=now;\r
140         }\r
141 }\r
142 \r
143 template <class IDTYPE>\r
144 void IIndexInserter<IDTYPE>::RegisterWithThread(FreenetMasterThread *thread)\r
145 {\r
146         thread->RegisterFCPConnected(this);\r
147         thread->RegisterFCPMessageHandler(this);\r
148         thread->RegisterPeriodicProcessor(this);\r
149 }\r
150 \r
151 template <class IDTYPE>\r
152 void IIndexInserter<IDTYPE>::RemoveFromInsertList(const IDTYPE identityid)\r
153 {\r
154         typename std::vector<IDTYPE>::iterator i=m_inserting.begin();\r
155         while(i!=m_inserting.end() && (*i)!=identityid)\r
156         {\r
157                 i++;\r
158         }\r
159         if(i!=m_inserting.end())\r
160         {\r
161                 m_inserting.erase(i);\r
162         }\r
163 }\r
164 \r
165 #endif  // _iindexrequester_\r