version 0.3.29
[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(SQLite3DB::DB *db);\r
26         IIndexInserter(SQLite3DB::DB *db, 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(SQLite3DB::DB *db):IDatabase(db)\r
56 {\r
57         InitializeIIndexInserter();\r
58 }\r
59 \r
60 template <class IDTYPE>\r
61 IIndexInserter<IDTYPE>::IIndexInserter(SQLite3DB::DB *db, FCPv2::Connection *fcp):IDatabase(db),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         Option option(m_db);\r
131         m_fcpuniquename="";\r
132         option.Get("MessageBase",m_messagebase);\r
133         m_lastchecked=Poco::Timestamp();\r
134 }\r
135 \r
136 template <class IDTYPE>\r
137 void IIndexInserter<IDTYPE>::Process()\r
138 {\r
139         Poco::DateTime now;\r
140 \r
141         if(m_lastchecked<(now-Poco::Timespan(0,0,1,0,0)))\r
142         {\r
143                 CheckForNeededInsert();\r
144                 m_lastchecked=now;\r
145         }\r
146 }\r
147 \r
148 template <class IDTYPE>\r
149 void IIndexInserter<IDTYPE>::RegisterWithThread(FreenetMasterThread *thread)\r
150 {\r
151         thread->RegisterFCPConnected(this);\r
152         thread->RegisterFCPMessageHandler(this);\r
153         thread->RegisterPeriodicProcessor(this);\r
154 }\r
155 \r
156 template <class IDTYPE>\r
157 void IIndexInserter<IDTYPE>::RemoveFromInsertList(const IDTYPE identityid)\r
158 {\r
159         typename std::vector<IDTYPE>::iterator i=m_inserting.begin();\r
160         while(i!=m_inserting.end() && (*i)!=identityid)\r
161         {\r
162                 i++;\r
163         }\r
164         if(i!=m_inserting.end())\r
165         {\r
166                 m_inserting.erase(i);\r
167         }\r
168 }\r
169 \r
170 #endif  // _iindexrequester_\r