PageRenderTime 49ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/cseg/src/DistributedCoordinateSegmentation.hpp

http://github.com/sirikata/sirikata
C++ Header | 300 lines | 164 code | 92 blank | 44 comment | 0 complexity | 7ccb0b5cdc885742dfb76a93f559afa5 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. /* Sirikata
  2. * DistributedCoordinateSegmentation.hpp
  3. *
  4. * Copyright (c) 2009, Tahir Azim
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are
  9. * met:
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Sirikata nor the names of its contributors may
  17. * be used to endorse or promote products derived from this software
  18. * without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  23. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  24. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. #ifndef _SIRIKATA_DISTRIBUTED_COORDINATE_SEGMENTATION_HPP_
  33. #define _SIRIKATA_DISTRIBUTED_COORDINATE_SEGMENTATION_HPP_
  34. #include <boost/unordered_map.hpp>
  35. #include <boost/shared_ptr.hpp>
  36. #include <boost/asio.hpp>
  37. #include <boost/tokenizer.hpp>
  38. #include <boost/bind.hpp>
  39. #include <sirikata/core/util/AtomicTypes.hpp>
  40. #include <sirikata/core/network/Message.hpp>
  41. #include <sirikata/core/queue/SizedThreadSafeQueue.hpp>
  42. #include <sirikata/core/service/PollingService.hpp>
  43. #include <sirikata/space/SegmentedRegion.hpp>
  44. #include <sirikata/core/network/Address4.hpp>
  45. #include <sirikata/core/options/CommonOptions.hpp>
  46. #include <sirikata/core/network/Message.hpp>
  47. #include <sirikata/core/util/Hash.hpp>
  48. #include "WorldPopulationBSPTree.hpp"
  49. #include "CSegContext.hpp"
  50. #include "LoadBalancer.hpp"
  51. #include "Protocol_CSeg.pbj.hpp"
  52. typedef boost::asio::ip::tcp tcp;
  53. namespace Sirikata {
  54. class ServerIDMap;
  55. typedef struct SegmentationChangeListener {
  56. char host[255];
  57. uint16 port;
  58. } SegmentationChangeListener;
  59. typedef boost::shared_ptr<tcp::socket> SocketPtr;
  60. typedef struct SocketContainer {
  61. SocketContainer() {
  62. mSocket = SocketPtr();
  63. }
  64. SocketContainer(SocketPtr socket) {
  65. mSocket = socket;
  66. }
  67. size_t size() {
  68. return 1;
  69. }
  70. SocketPtr socket() {
  71. return mSocket;
  72. }
  73. SocketPtr mSocket;
  74. } SocketContainer;
  75. typedef std::tr1::function< void(std::map<ServerID, SocketContainer>) > ResponseCompletionFunction;
  76. typedef boost::shared_ptr<Sirikata::SizedThreadSafeQueue<SocketContainer> > SocketQueuePtr;
  77. /** Distributed kd-tree based implementation of CoordinateSegmentation. */
  78. class DistributedCoordinateSegmentation : public PollingService {
  79. public:
  80. DistributedCoordinateSegmentation(CSegContext* ctx, const BoundingBox3f& region, const Vector3ui32& perdim, int, ServerIDMap * );
  81. virtual ~DistributedCoordinateSegmentation();
  82. virtual BoundingBoxList serverRegionCached(const ServerID& server);
  83. void getServerRegionUncached(const ServerID& server,
  84. boost::shared_ptr<tcp::socket> socket);
  85. virtual BoundingBox3f region() ;
  86. virtual uint32 numServers() ;
  87. virtual void poll();
  88. virtual void stop();
  89. void handleSelfLookup(ServerID my_sid, Address4 my_addr);
  90. private:
  91. void service();
  92. CSegContext* mContext;
  93. SegmentedRegion mTopLevelRegion;
  94. Time mLastUpdateTime;
  95. LoadBalancer mLoadBalancer;
  96. std::vector<SegmentationChangeListener> mSpacePeers;
  97. boost::asio::io_service mIOService; //creates an io service
  98. boost::asio::io_service mLLIOService; //creates an io service
  99. boost::shared_ptr<tcp::acceptor> mAcceptor;
  100. boost::shared_ptr<tcp::socket> mSocket;
  101. boost::shared_ptr<tcp::acceptor> mLLTreeAcceptor;
  102. boost::shared_ptr<tcp::socket> mLLTreeAcceptorSocket;
  103. std::map<String, SegmentedRegion*> mHigherLevelTrees;
  104. std::map<String, SegmentedRegion*> mLowerLevelTrees;
  105. int mAvailableCSEGServers;
  106. int mUpperTreeCSEGServers;
  107. void csegChangeMessage(Sirikata::Protocol::CSeg::ChangeMessage* ccMsg);
  108. void handleLoadReport(boost::shared_ptr<tcp::socket>, Sirikata::Protocol::CSeg::LoadReportMessage* message);
  109. void notifySpaceServersOfChange(const std::vector<SegmentationInfo> segInfoVector);
  110. /* Start listening for and accepting incoming connections. */
  111. void startAccepting();
  112. void startAcceptingLLRequests();
  113. /* Handlers for incoming connections */
  114. void accept_handler();
  115. void acceptLLTreeRequestHandler();
  116. /* Functions to do the initial kd-tree partitioning of the virtual world into regions, and
  117. divide the kd-tree into upper and lower trees.
  118. */
  119. void generateHierarchicalTrees(SegmentedRegion* region, int depth, int& numLLTreesSoFar);
  120. void subdivideTopLevelRegion(SegmentedRegion* region,
  121. Vector3ui32 perdim,
  122. int& numServersAssigned);
  123. /* Functions to contact another CSEG server, create sockets to them and/or forward calls to them.
  124. These should go away later when calls to CSEG no longer remain recursive. */
  125. void callLowerLevelCSEGServer(boost::shared_ptr<tcp::socket> socket, ServerID, const Vector3f& searchVec,
  126. const BoundingBox3f& boundingBox,
  127. BoundingBox3f& returningBBox);
  128. void callLowerLevelCSEGServersForServerRegions(boost::shared_ptr<tcp::socket> socket,
  129. ServerID server_id, BoundingBoxList&);
  130. void sendLoadReportToLowerLevelCSEGServer(boost::shared_ptr<tcp::socket> socket, ServerID,
  131. const BoundingBox3f& boundingBox,
  132. Sirikata::Protocol::CSeg::LoadReportMessage* message);
  133. void callLowerLevelCSEGServersForLookupBoundingBoxes(boost::shared_ptr<tcp::socket> socket,
  134. const BoundingBox3f& bbox,
  135. const std::map<ServerID, std::vector<SegmentedRegion*> >&,
  136. std::vector<ServerID>& );
  137. /* Functions run in separate threads to listen for incoming packets */
  138. void ioServicingLoop();
  139. void llIOServicingLoop();
  140. /* Functions to send buffers to all CSEG or all space servers */
  141. void sendToAllCSEGServers( Sirikata::Protocol::CSeg::CSegMessage& );
  142. void sendOnAllSockets(Sirikata::Protocol::CSeg::CSegMessage csegMessage, std::map< ServerID, SocketContainer > socketList);
  143. void sendToAllSpaceServers( Sirikata::Protocol::CSeg::CSegMessage& );
  144. uint32 getAvailableServerIndex();
  145. void getRandomLeafParentSibling(SegmentedRegion** randomLeaf,
  146. SegmentedRegion** sibling,
  147. SegmentedRegion** parent);
  148. /* Functions to read from a socket. */
  149. void asyncRead(boost::shared_ptr<tcp::socket> socket,
  150. uint8* asyncBufferArray,
  151. const boost::system::error_code& ec,
  152. std::size_t bytes_transferred);
  153. void asyncLLRead(boost::shared_ptr<tcp::socket> socket,
  154. uint8* asyncBufferArray,
  155. const boost::system::error_code& ec,
  156. std::size_t bytes_transferred);
  157. void writeCSEGMessage(boost::shared_ptr<tcp::socket> socket, Sirikata::Protocol::CSeg::CSegMessage& csegMessage);
  158. void readCSEGMessage(boost::shared_ptr<tcp::socket> socket,
  159. Sirikata::Protocol::CSeg::CSegMessage& csegMessage,
  160. uint8* bufferSoFar,
  161. uint32 bufferSoFarSize
  162. );
  163. void readCSEGMessage(boost::shared_ptr<tcp::socket> socket,
  164. Sirikata::Protocol::CSeg::CSegMessage& csegMessage);
  165. /* Functions to serialize the whole CSEG tree. */
  166. void serializeBSPTree(SerializedBSPTree* serializedBSPTree);
  167. void traverseAndStoreTree(SegmentedRegion* region, uint32& idx,
  168. SerializedBSPTree* serializedTree);
  169. ServerIDMap * mSidMap;
  170. /* Key value maps for fast lookup of bounding boxes managed by space servers. */
  171. std::map<ServerID, BoundingBoxList > mWholeTreeServerRegionMap;
  172. std::map<ServerID, BoundingBoxList > mLowerTreeServerRegionMap;
  173. boost::shared_mutex mCSEGReadWriteMutex;
  174. boost::shared_mutex mSocketsToCSEGServersMutex;
  175. std::map<ServerID, SocketQueuePtr > mLeasedSocketsToCSEGServers;
  176. friend class LoadBalancer;
  177. SocketContainer getSocketToCSEGServer(ServerID server_id);
  178. void doSocketCreation(ServerID server_id,
  179. std::vector<ServerID> server_id_List,
  180. std::map<ServerID, SocketContainer>* socketMapPtr,
  181. ResponseCompletionFunction func,
  182. ServerID resolved_id,
  183. Address4 addy
  184. );
  185. void createSocketContainers(std::vector<ServerID> server_id_List,
  186. std::map<ServerID, SocketContainer>* socketMap,
  187. ResponseCompletionFunction func
  188. );
  189. bool handleLookup(Vector3f vector,
  190. boost::shared_ptr<tcp::socket> socket);
  191. void lookupOnSocket(boost::shared_ptr<tcp::socket> clientSocket, const Vector3f searchVec,
  192. const BoundingBox3f boundingBox, std::map<ServerID, SocketContainer> socketList);
  193. void writeLookupResponse(boost::shared_ptr<tcp::socket> socket, BoundingBox3f& bbox, ServerID sid) ;
  194. void requestServerRegionsOnSockets(boost::shared_ptr<tcp::socket> socket, ServerID server_id,
  195. BoundingBoxList bbList,
  196. std::map<ServerID, SocketContainer> socketList);
  197. void writeServerRegionResponse(boost::shared_ptr<tcp::socket> socket,
  198. BoundingBoxList boundingBoxlist);
  199. bool handleLookupBBox(const BoundingBox3f& bbox, boost::shared_ptr<tcp::socket> socket);
  200. void lookupBBoxOnSocket(boost::shared_ptr<tcp::socket> clientSocket,
  201. const BoundingBox3f boundingBox, std::vector<ServerID> server_ids,
  202. std::map<ServerID, std::vector<SegmentedRegion*> > otherCSEGServers,
  203. std::map<ServerID, SocketContainer> socketList);
  204. void writeLookupBBoxResponse(boost::shared_ptr<tcp::socket> clientSocket, std::vector<ServerID>) ;
  205. void sendLoadReportOnSocket(boost::shared_ptr<tcp::socket> clientSocket, BoundingBox3f boundingBox, Sirikata::Protocol::CSeg::LoadReportMessage message, std::map< ServerID, SocketContainer > socketList);
  206. }; // class CoordinateSegmentation
  207. } // namespace Sirikata
  208. #endif