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