Sirikata
|
00001 /* Sirikata Transfer -- Content Transfer management system 00002 * TransferPool.hpp 00003 * 00004 * Copyright (c) 2010, Jeff Terrace 00005 * All rights reserved. 00006 * 00007 * Redistribution and use in source and binary forms, with or without 00008 * modification, are permitted provided that the following conditions are 00009 * met: 00010 * * Redistributions of source code must retain the above copyright 00011 * notice, this list of conditions and the following disclaimer. 00012 * * Redistributions in binary form must reproduce the above copyright 00013 * notice, this list of conditions and the following disclaimer in 00014 * the documentation and/or other materials provided with the 00015 * distribution. 00016 * * Neither the name of Sirikata nor the names of its contributors may 00017 * be used to endorse or promote products derived from this software 00018 * without specific prior written permission. 00019 * 00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 00021 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 00022 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 00023 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 00024 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00025 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00026 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00027 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00028 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00029 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00030 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00031 */ 00032 /* Created on: Jan 20th, 2010 */ 00033 00034 #ifndef SIRIKATA_TransferPool_HPP__ 00035 #define SIRIKATA_TransferPool_HPP__ 00036 00037 #include <sirikata/core/transfer/Defs.hpp> 00038 #include <sirikata/core/queue/ThreadSafeQueue.hpp> 00039 #include <sirikata/core/transfer/TransferRequest.hpp> 00040 00041 namespace Sirikata { 00042 namespace Transfer { 00043 00044 /* 00045 * Abstract class for providing an algorithm for aggregating priorities from 00046 * one or more clients for a request 00047 */ 00048 class PriorityAggregationAlgorithm { 00049 00050 public: 00051 // Return an aggregated priority given a list of priorities 00052 virtual Priority aggregate( 00053 const std::vector<Priority> &) const = 0; 00054 00055 //Return an aggregated priority given the list of priorities 00056 virtual Priority aggregate( 00057 const std::map<std::string, TransferRequestPtr> &) const = 0; 00058 00059 virtual Priority aggregate( 00060 const std::vector<TransferRequestPtr>&) const = 0; 00061 00062 virtual ~PriorityAggregationAlgorithm() { 00063 } 00064 }; 00065 00077 class TransferPool { 00078 public: 00079 virtual ~TransferPool() {} 00080 00082 inline const std::string& getClientID() const { 00083 return mClientID; 00084 } 00085 00087 virtual void addRequest(TransferRequestPtr req) = 0; 00089 virtual void updatePriority(TransferRequestPtr req, Priority p) = 0; 00091 virtual void deleteRequest(TransferRequestPtr req) = 0; 00092 00093 protected: 00094 // Friend in TransferMediator so it can construct, call getRequest 00095 friend class TransferMediator; 00096 00097 TransferPool(const std::string& clientID) 00098 : mClientID(clientID) 00099 {} 00100 00101 virtual TransferRequestPtr getRequest() = 0; 00102 00103 // Utility methods because they require being friended by 00104 // TransferRequest but that doesn't extend to subclasses 00105 void setRequestClientID(TransferRequestPtr req) { 00106 req->setClientID(mClientID); 00107 } 00108 void setRequestPriority(TransferRequestPtr req, Priority p) { 00109 req->setPriority(p); 00110 } 00111 void setRequestDeletion(TransferRequestPtr req) { 00112 req->setDeletion(); 00113 } 00114 00115 const std::string mClientID; 00116 }; 00117 typedef std::tr1::shared_ptr<TransferPool> TransferPoolPtr; 00118 00122 class SimpleTransferPool : public TransferPool { 00123 public: 00124 virtual ~SimpleTransferPool() {} 00125 00126 //Puts a request into the pool 00127 virtual void addRequest(TransferRequestPtr req) { 00128 if (req) 00129 setRequestClientID(req); 00130 mDeltaQueue.push(req); 00131 } 00132 00133 //Updates priority of a request in the pool 00134 virtual void updatePriority(TransferRequestPtr req, Priority p) { 00135 setRequestPriority(req, p); 00136 mDeltaQueue.push(req); 00137 } 00138 00139 //Updates priority of a request in the pool 00140 inline void deleteRequest(TransferRequestPtr req) { 00141 setRequestDeletion(req); 00142 mDeltaQueue.push(req); 00143 } 00144 00145 private: 00146 // Friend in TransferMediator so it can construct, call getRequest 00147 friend class TransferMediator; 00148 00149 ThreadSafeQueue<TransferRequestPtr> mDeltaQueue; 00150 00151 SimpleTransferPool(const std::string &clientID) 00152 : TransferPool(clientID) 00153 { 00154 } 00155 00156 //Returns an item from the pool. Blocks if pool is empty. 00157 inline std::tr1::shared_ptr<TransferRequest> getRequest() { 00158 std::tr1::shared_ptr<TransferRequest> retval; 00159 mDeltaQueue.blockingPop(retval); 00160 return retval; 00161 } 00162 }; 00163 00164 } 00165 } 00166 00167 #endif