// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #import "ios/chrome/browser/snapshots/lru_cache.h" #include #include "base/containers/hash_tables.h" #include "base/containers/mru_cache.h" #include "base/mac/scoped_nsobject.h" #include "base/macros.h" #include "base/memory/scoped_ptr.h" namespace { struct NSObjectEqualTo { bool operator()(const base::scoped_nsprotocol>& obj1, const base::scoped_nsprotocol>& obj2) const { return [obj1 isEqual:obj2]; } }; struct NSObjectHash { std::size_t operator()( const base::scoped_nsprotocol>& obj) const { return [obj hash]; } }; template struct MRUCacheNSObjectHashMap { typedef base::hash_map Type; }; class NSObjectMRUCache : public base::MRUCacheBase>, base::scoped_nsprotocol>, NSObjectHash, MRUCacheNSObjectHashMap> { private: typedef base::MRUCacheBase>, base::scoped_nsprotocol>, NSObjectHash, MRUCacheNSObjectHashMap> ParentType; public: explicit NSObjectMRUCache(typename ParentType::size_type max_size) : ParentType(max_size) {} private: DISALLOW_COPY_AND_ASSIGN(NSObjectMRUCache); }; } // namespace @implementation LRUCache { scoped_ptr _cache; } @synthesize maxCacheSize = _maxCacheSize; - (instancetype)init { NOTREACHED(); // Use initWithCacheSize: instead. return nil; } - (instancetype)initWithCacheSize:(NSUInteger)maxCacheSize { self = [super init]; if (self) { _maxCacheSize = maxCacheSize; _cache.reset(new NSObjectMRUCache(self.maxCacheSize)); } return self; } - (id)objectForKey:(id)key { base::scoped_nsprotocol> keyObj([key retain]); auto it = _cache->Get(keyObj); if (it == _cache->end()) return nil; return it->second.get(); } - (void)setObject:(id)value forKey:(NSObject*)key { base::scoped_nsprotocol> keyObj([key copy]); base::scoped_nsprotocol> valueObj([value retain]); _cache->Put(keyObj, valueObj); } - (void)removeObjectForKey:(id)key { base::scoped_nsprotocol> keyObj([key retain]); auto it = _cache->Peek(keyObj); if (it != _cache->end()) _cache->Erase(it); } - (void)removeAllObjects { _cache->Clear(); } - (NSUInteger)count { return _cache->size(); } - (BOOL)isEmpty { return _cache->empty(); } @end