Page Speed Optimization Libraries
1.4.26.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 <vector> 00097 00098 #include "net/instaweb/http/public/request_context.h" 00099 #include "net/instaweb/util/public/basictypes.h" 00100 #include "net/instaweb/util/public/cache_interface.h" 00101 #include "net/instaweb/util/public/ref_counted_ptr.h" 00102 #include "net/instaweb/util/public/scoped_ptr.h" 00103 #include "net/instaweb/util/public/string.h" 00104 #include "net/instaweb/util/public/string_util.h" 00105 00106 namespace net_instaweb { 00107 00108 class AbstractMutex; 00109 class LogRecord; 00110 class PropertyValueProtobuf; 00111 class PropertyPage; 00112 class Statistics; 00113 class ThreadSystem; 00114 class Timer; 00115 00116 typedef std::vector<PropertyPage*> PropertyPageStarVector; 00117 00119 class PropertyValue { 00120 public: 00121 StringPiece value() const; 00122 bool has_value() const { return valid_; } 00123 00126 int64 write_timestamp_ms() const; 00127 00130 bool was_read() { return was_read_; } 00131 00135 bool IsStable(int stable_hit_per_thousand_threshold) const; 00136 00139 bool IsRecentlyConstant(int num_writes_unchanged) const; 00140 00143 static bool IsIndexOfLeastSetBitSmaller(uint64 value, int index); 00144 00145 private: 00146 friend class PropertyCache; 00147 friend class PropertyPage; 00148 00150 PropertyValue(); 00151 ~PropertyValue(); 00152 00153 void set_was_read(bool was_read) { was_read_ = was_read; } 00154 00156 void InitFromProtobuf(const PropertyValueProtobuf& value); 00157 00164 void SetValue(const StringPiece& value, int64 now_ms); 00165 00166 PropertyValueProtobuf* protobuf() { return proto_.get(); } 00167 00168 scoped_ptr<PropertyValueProtobuf> proto_; 00169 bool changed_; 00170 bool valid_; 00171 bool was_read_; 00172 00173 DISALLOW_COPY_AND_ASSIGN(PropertyValue); 00174 }; 00175 00177 class PropertyCache { 00178 public: 00180 static const char kPagePropertyCacheKeyPrefix[]; 00181 static const char kClientPropertyCacheKeyPrefix[]; 00182 static const char kDevicePropertyCacheKeyPrefix[]; 00183 00184 class CacheInterfaceCallback; 00185 00192 class Cohort { 00193 public: 00195 Cohort(StringPiece name, CacheInterface* cache) 00196 : cache_(cache) { 00197 name.CopyToString(&name_); 00198 } 00199 const GoogleString& name() const { return name_; } 00200 CacheInterface* cache() const { return cache_.get(); } 00201 00202 private: 00203 scoped_ptr<CacheInterface> cache_; 00204 GoogleString name_; 00205 00206 DISALLOW_COPY_AND_ASSIGN(Cohort); 00207 }; 00208 00209 typedef std::vector<const Cohort*> CohortVector; 00210 00211 PropertyCache(const GoogleString& cache_key_prefix, 00212 CacheInterface* cache, Timer* timer, 00213 Statistics* stats, ThreadSystem* threads); 00214 ~PropertyCache(); 00215 00219 void Read(PropertyPage* property_page) const; 00220 00223 void ReadWithCohorts(const CohortVector& cohort_list, 00224 PropertyPage* property_page) const; 00225 00227 bool IsStable(const PropertyValue* property) const { 00228 return property->IsStable(mutations_per_1000_writes_threshold_); 00229 } 00230 00239 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00240 00241 void set_mutations_per_1000_writes_threshold(int x) { 00242 mutations_per_1000_writes_threshold_ = x; 00243 } 00244 00248 const Cohort* AddCohort(const StringPiece& cohort_name); 00249 00252 const Cohort* AddCohortWithCache(const StringPiece& cohort_name, 00253 CacheInterface* cache); 00254 00258 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00259 00263 void set_enabled(bool x) { enabled_ = x; } 00264 00266 bool enabled() const { return enabled_; } 00267 00272 GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const; 00273 00274 const CacheInterface* cache_backend() const { return cache_; } 00275 00277 static void InitCohortStats(const GoogleString& cohort, 00278 Statistics* statistics); 00279 00281 Timer* timer() const { return timer_; } 00282 00284 00285 private: 00286 GoogleString cache_key_prefix_; 00287 CacheInterface* cache_; 00288 Timer* timer_; 00289 Statistics* stats_; 00290 ThreadSystem* thread_system_; 00291 00292 int mutations_per_1000_writes_threshold_; 00293 typedef std::map<GoogleString, Cohort*> CohortMap; 00294 CohortMap cohorts_; 00296 CohortVector cohort_list_; 00297 bool enabled_; 00298 00299 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00300 }; 00301 00304 class PropertyPage { 00305 public: 00306 virtual ~PropertyPage(); 00307 00324 virtual PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00325 const StringPiece& property_name) const; 00326 00329 virtual void UpdateValue( 00330 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00331 const StringPiece& value); 00332 00339 virtual void WriteCohort(const PropertyCache::Cohort* cohort); 00340 00345 CacheInterface::KeyState GetCacheState(const PropertyCache::Cohort* cohort); 00346 00353 void set_cache_state_for_tests(const PropertyCache::Cohort* cohort, 00354 CacheInterface::KeyState x); 00355 00365 void DeleteProperty(const PropertyCache::Cohort* cohort, 00366 const StringPiece& property_name); 00367 00368 const GoogleString& key() const { return key_; } 00369 00370 LogRecord* log_record() { 00371 return request_context_->log_record(); 00372 } 00373 00375 virtual void LogPageCohortInfo(LogRecord* log_record, int cohort_index) {} 00376 00377 protected: 00379 PropertyPage(const StringPiece& key, 00380 const RequestContextPtr& request_context, 00381 AbstractMutex* mutex, 00382 PropertyCache* property_cache); 00383 00386 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00387 00389 virtual void Done(bool success) = 0; 00390 00391 private: 00392 class CallbackCollector; 00393 friend class CallbackCollector; 00394 friend class PropertyCache::CacheInterfaceCallback; 00395 friend class PropertyCache; 00396 00397 void SetupCohorts(const PropertyCache::CohortVector& cohort_list); 00398 00401 bool EncodeCacheEntry(const PropertyCache::Cohort* cohort, 00402 GoogleString* value); 00403 00405 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00406 00407 void CallDone(bool success) { 00408 was_read_ = true; 00409 Done(success); 00410 } 00411 00412 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00413 const PropertyValueProtobuf& proto); 00414 00415 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00416 00417 struct PropertyMapStruct { 00418 PropertyMapStruct(LogRecord* log, int index) 00419 : has_deleted_property(false), 00420 log_record(log), 00421 cohort_index(index) {} 00422 PropertyMap pmap; 00423 bool has_deleted_property; 00424 LogRecord* log_record; 00425 int cohort_index; 00426 CacheInterface::KeyState cache_state; 00427 }; 00428 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00429 CohortDataMap; 00430 CohortDataMap cohort_data_map_; 00431 scoped_ptr<AbstractMutex> mutex_; 00432 GoogleString key_; 00433 RequestContextPtr request_context_; 00434 bool was_read_; 00435 PropertyCache* property_cache_; 00436 00437 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00438 }; 00439 00440 } 00441 00442 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_