Sirikata
libcore/include/sirikata/core/transfer/LRUPolicy.hpp
Go to the documentation of this file.
00001 /*  Sirikata Transfer -- Content Transfer management system
00002  *  LRUPolicy.hpp
00003  *
00004  *  Copyright (c) 2008, Patrick Reiter Horn
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 5, 2009 */
00033 
00034 #ifndef SIRIKATA_LRUPolicy_HPP__
00035 #define SIRIKATA_LRUPolicy_HPP__
00036 
00037 #include "CachePolicy.hpp"
00038 
00039 namespace Sirikata {
00040 namespace Transfer {
00041 
00043 class LRUPolicy : public CachePolicy {
00044 
00045     typedef Fingerprint LRUElement;
00046     typedef std::list<LRUElement> LRUList;
00047 
00048     struct LRUData : public Data {
00049         LRUList::iterator mIter;
00050 
00051         LRUData(const LRUList::iterator &copyIter)
00052             : mIter(copyIter) {
00053         }
00054     };
00055 
00056     LRUList mLeastUsed;
00057     // std::list<Fingerprint>::const_iterator
00058 
00059 public:
00060     LRUPolicy(cache_usize_type allocatedSpace, float maxSizePct=0.5)
00061         : CachePolicy(allocatedSpace, maxSizePct) {
00062     }
00063 
00064     virtual void use(const Fingerprint &id, Data* data, cache_usize_type size) {
00065         LRUData *lrudata = static_cast<LRUData*>(data);
00066 
00067         // "All iterators remain valid"
00068         mLeastUsed.splice(mLeastUsed.end(), mLeastUsed, lrudata->mIter);
00069     }
00070 
00071     virtual void useAndUpdate(const Fingerprint &id, Data* data, cache_usize_type oldsize, cache_usize_type newsize) {
00072         use(id, data, newsize); // No optimizations to be made here.
00073         CachePolicy::updateSpace(oldsize, newsize);
00074     }
00075 
00076     virtual void destroy(const Fingerprint &id, Data* data, cache_usize_type size) {
00077         LRUData *lrudata = static_cast<LRUData*>(data);
00078 
00079         CachePolicy::updateSpace(size, 0);
00080 
00081         SILOG(lrupolicy,detailed,"Freeing " << id << " (" << size << " bytes); " << mFreeSpace << " free");
00082         mLeastUsed.erase(lrudata->mIter);
00083         delete lrudata;
00084     }
00085 
00086     virtual Data* create(const Fingerprint &id, cache_usize_type size) {
00087         CachePolicy::updateSpace(0, size);
00088 
00089         mLeastUsed.push_back(id);
00090         LRUList::iterator newIter = mLeastUsed.end();
00091         --newIter; // I wish push_back returned an iterator
00092 
00093         return new LRUData(newIter);
00094     }
00095 
00096     virtual bool nextItem(
00097             cache_usize_type requiredSpace,
00098             Fingerprint &myprint)
00099     {
00100         if (mFreeSpace < (cache_ssize_type)requiredSpace && !mLeastUsed.empty()) {
00101 
00102             myprint = mLeastUsed.front();
00103             return true;
00104         } else {
00105             return false;
00106         }
00107     }
00108 };
00109 
00110 }
00111 }
00112 
00113 #endif /* SIRIKATA_LRUPolicy_HPP__ */