fb65b0eb7d038ee5464c952607364e0e4cd3399d
[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::Connection *fcp);\r
27         virtual ~IIndexInserter()               {}\r
28 \r
29         virtual void FCPConnected();\r
30         virtual void FCPDisconnected();\r
31         virtual const bool HandleMessage(FCPv2::Message &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(FCPv2::Message &message)=0;\r
41         virtual const bool HandlePutFailed(FCPv2::Message &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::Connection *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 : "+m_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(FCPv2::Message &message)\r
90 {\r
91 \r
92         if(message["Identifier"].find(m_fcpuniquename)==0)\r
93         {\r
94                 m_log->trace("IIndexInserter<IDTYPE>::HandleMessage "+m_fcpuniquename+" received "+message.GetName()+"  ID="+message["Identifier"]+"  URI="+message["URI"]);\r
95 \r
96                 if(message.GetName()=="URIGenerated")\r
97                 {\r
98                         return true;\r
99                 }\r
100 \r
101                 if(message.GetName()=="PutSuccessful")\r
102                 {\r
103                         return HandlePutSuccessful(message);\r
104                 }\r
105 \r
106                 if(message.GetName()=="PutFailed")\r
107                 {\r
108                         return HandlePutFailed(message);\r
109                 }\r
110 \r
111                 if(message.GetName()=="IdentifierCollision")\r
112                 {\r
113                         // remove one of the ids from the requesting list\r
114                         IDTYPE id;\r
115                         std::vector<std::string> idparts;\r
116                         StringFunctions::Split(message["Identifier"],"|",idparts);\r
117                         StringFunctions::Convert(idparts[1],id);\r
118                         RemoveFromInsertList(id);\r
119                         m_log->debug("IIndexInserter<IDTYPE>::HandleMessage IdentifierCollision for "+m_fcpuniquename+" "+message["Identifier"]);\r
120                         return true;\r
121                 }\r
122         }\r
123 \r
124         return false;\r
125 }\r
126 \r
127 template <class IDTYPE>\r
128 void IIndexInserter<IDTYPE>::InitializeIIndexInserter()\r
129 {\r
130         m_fcpuniquename="";\r
131         Option::Instance()->Get("MessageBase",m_messagebase);\r
132         m_lastchecked=Poco::Timestamp();\r
133 }\r
134 \r
135 template <class IDTYPE>\r
136 void IIndexInserter<IDTYPE>::Process()\r
137 {\r
138         Poco::DateTime now;\r
139 \r
140         if(m_lastchecked<(now-Poco::Timespan(0,0,1,0,0)))\r
141         {\r
142                 CheckForNeededInsert();\r
143                 m_lastchecked=now;\r
144         }\r
145 }\r
146 \r
147 template <class IDTYPE>\r
148 void IIndexInserter<IDTYPE>::RegisterWithThread(FreenetMasterThread *thread)\r
149 {\r
150         thread->RegisterFCPConnected(this);\r
151         thread->RegisterFCPMessageHandler(this);\r
152         thread->RegisterPeriodicProcessor(this);\r
153 }\r
154 \r
155 template <class IDTYPE>\r
156 void IIndexInserter<IDTYPE>::RemoveFromInsertList(const IDTYPE identityid)\r
157 {\r
158         typename std::vector<IDTYPE>::iterator i=m_inserting.begin();\r
159         while(i!=m_inserting.end() && (*i)!=identityid)\r
160         {\r
161                 i++;\r
162         }\r
163         if(i!=m_inserting.end())\r
164         {\r
165                 m_inserting.erase(i);\r
166         }\r
167 }\r
168 \r
169 #endif  // _iindexrequester_\r