1*3638366cSAndrew Rist /************************************************************** 2*3638366cSAndrew Rist * 3*3638366cSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*3638366cSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*3638366cSAndrew Rist * distributed with this work for additional information 6*3638366cSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*3638366cSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*3638366cSAndrew Rist * "License"); you may not use this file except in compliance 9*3638366cSAndrew Rist * with the License. You may obtain a copy of the License at 10*3638366cSAndrew Rist * 11*3638366cSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*3638366cSAndrew Rist * 13*3638366cSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*3638366cSAndrew Rist * software distributed under the License is distributed on an 15*3638366cSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*3638366cSAndrew Rist * KIND, either express or implied. See the License for the 17*3638366cSAndrew Rist * specific language governing permissions and limitations 18*3638366cSAndrew Rist * under the License. 19*3638366cSAndrew Rist * 20*3638366cSAndrew Rist *************************************************************/ 21*3638366cSAndrew Rist 22*3638366cSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #ifndef INCLUDED_BINARYURP_SOURCE_CACHE_HXX 25cdf0e10cSrcweir #define INCLUDED_BINARYURP_SOURCE_CACHE_HXX 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include "sal/config.h" 28cdf0e10cSrcweir 29cdf0e10cSrcweir #include <cstddef> 30cdf0e10cSrcweir #include <map> 31cdf0e10cSrcweir 32cdf0e10cSrcweir #include "boost/noncopyable.hpp" 33cdf0e10cSrcweir #include "osl/diagnose.h" 34cdf0e10cSrcweir #include "sal/types.h" 35cdf0e10cSrcweir 36cdf0e10cSrcweir namespace binaryurp { 37cdf0e10cSrcweir 38cdf0e10cSrcweir namespace cache { 39cdf0e10cSrcweir 40cdf0e10cSrcweir enum { size = 256, ignore = 0xFFFF }; 41cdf0e10cSrcweir 42cdf0e10cSrcweir } 43cdf0e10cSrcweir 44cdf0e10cSrcweir template< typename T > class Cache: private boost::noncopyable { 45cdf0e10cSrcweir public: 46cdf0e10cSrcweir explicit Cache(std::size_t size): 47cdf0e10cSrcweir size_(size), first_(map_.end()), last_(map_.end()) 48cdf0e10cSrcweir { 49cdf0e10cSrcweir OSL_ASSERT(size < cache::ignore); 50cdf0e10cSrcweir } 51cdf0e10cSrcweir 52cdf0e10cSrcweir sal_uInt16 add(T const & content, bool * found) { 53cdf0e10cSrcweir OSL_ASSERT(found != 0); 54cdf0e10cSrcweir typename Map::iterator i(map_.find(content)); 55cdf0e10cSrcweir *found = i != map_.end(); 56cdf0e10cSrcweir if (i == map_.end()) { 57cdf0e10cSrcweir typename Map::size_type n = map_.size(); 58cdf0e10cSrcweir if (n < size_) { 59cdf0e10cSrcweir i = 60cdf0e10cSrcweir (map_.insert( 61cdf0e10cSrcweir typename Map::value_type( 62cdf0e10cSrcweir content, 63cdf0e10cSrcweir Entry( 64cdf0e10cSrcweir static_cast< sal_uInt16 >(n), map_.end(), 65cdf0e10cSrcweir first_)))). 66cdf0e10cSrcweir first; 67cdf0e10cSrcweir if (first_ == map_.end()) { 68cdf0e10cSrcweir last_ = i; 69cdf0e10cSrcweir } else { 70cdf0e10cSrcweir first_->second.prev = i; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir first_ = i; 73cdf0e10cSrcweir } else if (last_ != map_.end()) { 74cdf0e10cSrcweir i = 75cdf0e10cSrcweir (map_.insert( 76cdf0e10cSrcweir typename Map::value_type( 77cdf0e10cSrcweir content, 78cdf0e10cSrcweir Entry(last_->second.index, map_.end(), first_)))). 79cdf0e10cSrcweir first; 80cdf0e10cSrcweir first_->second.prev = i; 81cdf0e10cSrcweir first_ = i; 82cdf0e10cSrcweir typename Map::iterator j(last_); 83cdf0e10cSrcweir last_ = last_->second.prev; 84cdf0e10cSrcweir last_->second.next = map_.end(); 85cdf0e10cSrcweir map_.erase(j); 86cdf0e10cSrcweir } else { 87cdf0e10cSrcweir // Reached iff size_ == 0: 88cdf0e10cSrcweir return cache::ignore; 89cdf0e10cSrcweir } 90cdf0e10cSrcweir } else if (i != first_) { 91cdf0e10cSrcweir // Move to front (reached only if size_ > 1): 92cdf0e10cSrcweir i->second.prev->second.next = i->second.next; 93cdf0e10cSrcweir if (i->second.next == map_.end()) { 94cdf0e10cSrcweir last_ = i->second.prev; 95cdf0e10cSrcweir } else { 96cdf0e10cSrcweir i->second.next->second.prev = i->second.prev; 97cdf0e10cSrcweir } 98cdf0e10cSrcweir i->second.prev = map_.end(); 99cdf0e10cSrcweir i->second.next = first_; 100cdf0e10cSrcweir first_->second.prev = i; 101cdf0e10cSrcweir first_ = i; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir return i->second.index; 104cdf0e10cSrcweir } 105cdf0e10cSrcweir 106cdf0e10cSrcweir private: 107cdf0e10cSrcweir struct Entry; 108cdf0e10cSrcweir 109cdf0e10cSrcweir typedef std::map< T, Entry > Map; 110cdf0e10cSrcweir 111cdf0e10cSrcweir struct Entry { 112cdf0e10cSrcweir sal_uInt16 index; 113cdf0e10cSrcweir typename Map::iterator prev; 114cdf0e10cSrcweir typename Map::iterator next; 115cdf0e10cSrcweir 116cdf0e10cSrcweir Entry( 117cdf0e10cSrcweir sal_uInt16 theIndex, typename Map::iterator thePrev, 118cdf0e10cSrcweir typename Map::iterator theNext): 119cdf0e10cSrcweir index(theIndex), prev(thePrev), next(theNext) {} 120cdf0e10cSrcweir }; 121cdf0e10cSrcweir 122cdf0e10cSrcweir std::size_t size_; 123cdf0e10cSrcweir Map map_; 124cdf0e10cSrcweir typename Map::iterator first_; 125cdf0e10cSrcweir typename Map::iterator last_; 126cdf0e10cSrcweir }; 127cdf0e10cSrcweir 128cdf0e10cSrcweir } 129cdf0e10cSrcweir 130cdf0e10cSrcweir #endif 131