Sirikata
libcore/include/sirikata/core/transfer/TransferPool.hpp
Go to the documentation of this file.
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