Sirikata
libspace/plugins/prox/ManualReplicatedRequestManager.hpp
Go to the documentation of this file.
00001 // Copyright (c) 2012 Sirikata Authors. All rights reserved.
00002 // Use of this source code is governed by a BSD-style license that can
00003 // be found in the LICENSE file.
00004 
00005 #ifndef _SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_
00006 #define _SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_
00007 
00008 #include <sirikata/pintoloc/ProxSimulationTraits.hpp>
00009 #include <sirikata/core/service/Service.hpp>
00010 #include <sirikata/core/service/Context.hpp>
00011 
00012 #include <boost/multi_index_container.hpp>
00013 #include <boost/multi_index/member.hpp>
00014 #include <boost/multi_index/ordered_index.hpp>
00015 #include <boost/multi_index/hashed_index.hpp>
00016 
00017 #include <prox/manual/Query.hpp>
00018 
00019 namespace Sirikata {
00020 
00035 class ManualReplicatedRequestManager :
00036         public Service
00037 {
00038   public:
00039     typedef Prox::ManualQuery<ObjectProxSimulationTraits> ProxQuery;
00040 
00041     ManualReplicatedRequestManager(Context* ctx, Network::IOStrandPtr strand);
00042     ManualReplicatedRequestManager(Context* ctx, Network::IOStrand* strand);
00043     virtual ~ManualReplicatedRequestManager();
00044 
00045     // Service Interface
00046     virtual void start();
00047     virtual void stop();
00048 
00049     // Add a failed refinement request.
00050     void addFailedRefine(ProxQuery* query, const ObjectReference& objid);
00051     // Lookup any queries waiting on the object to be refined. Note that when
00052     // you call this, you should be asking for the queries waiting on the
00053     // *parent* of node/object that you just added since that's the node for
00054     // which data is now available.
00055     void lookupWaitingQueries(const ObjectReference& objid, std::vector<ProxQuery*>* queries_out);
00056     // Clear out any requests by the given querier
00057     void removeQuerier(ProxQuery* query);
00058 
00059   private:
00060 
00061     // Track each request for refinement
00062     struct Request {
00063         Request(ProxQuery* _query, const ObjectReference& _objid, Time _expires)
00064          : query(_query),
00065            objid(_objid),
00066            expires(_expires)
00067         {}
00068         ProxQuery* query;
00069         ObjectReference objid;
00070         Time expires;
00071     };
00072     struct query_tag {};
00073     struct objid_tag {};
00074     struct expires_tag {};
00075     typedef boost::multi_index_container<
00076         Request,
00077         boost::multi_index::indexed_by<
00078             boost::multi_index::hashed_non_unique< boost::multi_index::tag<query_tag>, BOOST_MULTI_INDEX_MEMBER(Request,ProxQuery*,query) >,
00079             boost::multi_index::hashed_non_unique< boost::multi_index::tag<objid_tag>, BOOST_MULTI_INDEX_MEMBER(Request,ObjectReference,objid), ObjectReference::Hasher >,
00080             boost::multi_index::ordered_non_unique< boost::multi_index::tag<expires_tag>, BOOST_MULTI_INDEX_MEMBER(Request,Time,expires) >
00081             >
00082         > RequestIndex;
00083     typedef RequestIndex::index<query_tag>::type RequestsByQuery;
00084     typedef RequestIndex::index<objid_tag>::type RequestsByObject;
00085     typedef RequestIndex::index<expires_tag>::type RequestsByExpiration;
00086 
00087 
00088     Context* mContext;
00089     // This is unfortunate, but we need to be able to accept both raw
00090     // IOStrand*'s and IOStrandPtrs, so we store both, and sometimes the
00091     // IOStrandPtr is just empty (we always use the sanely-named raw ptr).
00092     Network::IOStrandPtr doNotUse___mStrand;
00093     Network::IOStrand* mStrand;
00094 
00095     RequestIndex mRequestIndex;
00096     Network::IOTimerPtr mExpiryTimer;
00097 
00098 
00099 
00100     void processExpiredRequests();
00101 };
00102 
00103 } // namespace Sirikata
00104 
00105 #endif //_SIRIKATA_LIBPROX_MANUAL_REPLICATED_REQUEST_MANAGER_HPP_