Page Speed Optimization Libraries
1.2.24.1
|
00001 /* 00002 * Copyright 2012 Google Inc. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http:///www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00091 00092 #ifndef NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_ 00093 #define NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_ 00094 00095 #include <map> 00096 #include <set> 00097 00098 #include "net/instaweb/util/public/basictypes.h" 00099 #include "net/instaweb/util/public/scoped_ptr.h" 00100 #include "net/instaweb/util/public/string.h" 00101 #include "net/instaweb/util/public/string_util.h" 00102 00103 namespace net_instaweb { 00104 00105 class AbstractMutex; 00106 class CacheInterface; 00107 class PropertyValueProtobuf; 00108 class PropertyPage; 00109 class ThreadSystem; 00110 class Timer; 00111 00113 class PropertyValue { 00114 public: 00115 StringPiece value() const; 00116 bool has_value() const { return valid_; } 00117 00120 int64 write_timestamp_ms() const; 00121 00124 bool was_read() { return was_read_; } 00125 00129 bool IsStable(int stable_hit_per_thousand_threshold) const; 00130 00133 bool IsRecentlyConstant(int num_writes_unchanged) const; 00134 00137 static bool IsIndexOfLeastSetBitSmaller(uint64 value, int index); 00138 00139 private: 00140 friend class PropertyCache; 00141 friend class PropertyPage; 00142 00144 PropertyValue(); 00145 ~PropertyValue(); 00146 00147 void set_was_read(bool was_read) { was_read_ = was_read; } 00148 00150 void InitFromProtobuf(const PropertyValueProtobuf& value); 00151 00158 void SetValue(const StringPiece& value, int64 now_ms); 00159 00160 PropertyValueProtobuf* protobuf() { return proto_.get(); } 00161 00162 scoped_ptr<PropertyValueProtobuf> proto_; 00163 bool changed_; 00164 bool valid_; 00165 bool was_read_; 00166 00167 DISALLOW_COPY_AND_ASSIGN(PropertyValue); 00168 }; 00169 00171 class PropertyCache { 00172 public: 00174 static const char kPagePropertyCacheKeyPrefix[]; 00175 static const char kClientPropertyCacheKeyPrefix[]; 00176 00177 class CacheInterfaceCallback; 00178 00190 class Cohort : public GoogleString {}; 00191 00192 PropertyCache(const GoogleString& cache_key_prefix, 00193 CacheInterface* cache, Timer* timer, ThreadSystem* threads); 00194 ~PropertyCache(); 00195 00199 void Read(PropertyPage* property_page) const; 00200 00207 void WriteCohort(const Cohort* cohort, 00208 PropertyPage* property_page) const; 00209 00211 bool IsStable(const PropertyValue* property) const { 00212 return property->IsStable(mutations_per_1000_writes_threshold_); 00213 } 00214 00223 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00224 00226 bool IsImminentlyExpiring(const PropertyValue* property_value, 00227 int64 ttl_ms) const; 00228 00231 void UpdateValue(const StringPiece& value, PropertyValue* property) const; 00232 00233 void set_mutations_per_1000_writes_threshold(int x) { 00234 mutations_per_1000_writes_threshold_ = x; 00235 } 00236 00238 const Cohort* AddCohort(const StringPiece& cohort_name); 00239 00243 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00244 00248 void set_enabled(bool x) { enabled_ = x; } 00249 00251 bool enabled() const { return enabled_; } 00252 00257 GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const; 00258 00259 const CacheInterface* cache_backend() const { return cache_; } 00260 00262 00263 private: 00264 GoogleString cache_key_prefix_; 00265 CacheInterface* cache_; 00266 Timer* timer_; 00267 ThreadSystem* thread_system_; 00268 00269 int mutations_per_1000_writes_threshold_; 00270 typedef std::set<Cohort> CohortSet; 00271 CohortSet cohorts_; 00272 00273 bool enabled_; 00274 00275 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00276 }; 00277 00280 class PropertyPage { 00281 public: 00282 virtual ~PropertyPage(); 00283 00300 PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00301 const StringPiece& property_name); 00302 00312 void DeleteProperty(const PropertyCache::Cohort* cohort, 00313 const StringPiece& property_name); 00314 00315 const GoogleString& key() const { return key_; } 00316 00317 protected: 00319 explicit PropertyPage(AbstractMutex* mutex, const StringPiece& key) 00320 : mutex_(mutex), 00321 key_(key.as_string()), 00322 was_read_(false) {} 00323 00326 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00327 00329 virtual void Done(bool success) = 0; 00330 00331 private: 00332 class CallbackCollector; 00333 friend class CallbackCollector; 00334 friend class PropertyCache::CacheInterfaceCallback; 00335 friend class PropertyCache; 00336 00339 bool EncodeCacheEntry(const PropertyCache::Cohort* cohort, 00340 GoogleString* value); 00341 00343 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00344 00345 void CallDone(bool success) { 00346 was_read_ = true; 00347 Done(success); 00348 } 00349 00350 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00351 const PropertyValueProtobuf& proto); 00352 00353 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00354 00355 struct PropertyMapStruct { 00356 PropertyMapStruct() { 00357 has_deleted_property = false; 00358 } 00359 PropertyMap pmap; 00360 bool has_deleted_property; 00361 }; 00362 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00363 CohortDataMap; 00364 CohortDataMap cohort_data_map_; 00365 scoped_ptr<AbstractMutex> mutex_; 00366 GoogleString key_; 00367 bool was_read_; 00368 00369 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00370 }; 00371 00372 } 00373 00374 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_