Page Speed Optimization Libraries
1.6.29.3
|
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 AbstractLogRecord; 00109 class AbstractMutex; 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 kDevicePropertyCacheKeyPrefix[]; 00182 00183 class CacheInterfaceCallback; 00184 00191 class Cohort { 00192 public: 00194 Cohort(StringPiece name, CacheInterface* cache) 00195 : cache_(cache) { 00196 name.CopyToString(&name_); 00197 } 00198 const GoogleString& name() const { return name_; } 00199 CacheInterface* cache() const { return cache_.get(); } 00200 00201 private: 00202 scoped_ptr<CacheInterface> cache_; 00203 GoogleString name_; 00204 00205 DISALLOW_COPY_AND_ASSIGN(Cohort); 00206 }; 00207 00208 typedef std::vector<const Cohort*> CohortVector; 00209 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 const CohortVector GetAllCohorts() const { return cohort_list_; } 00228 00230 bool IsStable(const PropertyValue* property) const { 00231 return property->IsStable(mutations_per_1000_writes_threshold_); 00232 } 00233 00242 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00243 00244 void set_mutations_per_1000_writes_threshold(int x) { 00245 mutations_per_1000_writes_threshold_ = x; 00246 } 00247 00251 const Cohort* AddCohort(const StringPiece& cohort_name); 00252 00255 const Cohort* AddCohortWithCache(const StringPiece& cohort_name, 00256 CacheInterface* cache); 00257 00261 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00262 00266 void set_enabled(bool x) { enabled_ = x; } 00267 00269 bool enabled() const { return enabled_; } 00270 00275 GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const; 00276 00277 const CacheInterface* cache_backend() const { return cache_; } 00278 00280 static void InitCohortStats(const GoogleString& cohort, 00281 Statistics* statistics); 00282 00284 Timer* timer() const { return timer_; } 00285 00286 ThreadSystem* thread_system() const { return thread_system_; } 00287 00289 00290 private: 00291 GoogleString cache_key_prefix_; 00292 CacheInterface* cache_; 00293 Timer* timer_; 00294 Statistics* stats_; 00295 ThreadSystem* thread_system_; 00296 00297 int mutations_per_1000_writes_threshold_; 00298 typedef std::map<GoogleString, Cohort*> CohortMap; 00299 CohortMap cohorts_; 00301 CohortVector cohort_list_; 00302 bool enabled_; 00303 00304 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00305 }; 00306 00308 class AbstractPropertyPage { 00309 public: 00310 virtual ~AbstractPropertyPage(); 00313 virtual PropertyValue* GetProperty( 00314 const PropertyCache::Cohort* cohort, 00315 const StringPiece& property_name) = 0; 00316 00319 virtual void UpdateValue( 00320 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00321 const StringPiece& value) = 0; 00322 00326 virtual void WriteCohort(const PropertyCache::Cohort* cohort) = 0; 00327 00329 virtual CacheInterface::KeyState GetCacheState( 00330 const PropertyCache::Cohort* cohort) = 0; 00331 00333 virtual void DeleteProperty(const PropertyCache::Cohort* cohort, 00334 const StringPiece& property_name) = 0; 00335 00336 virtual const GoogleString& key() const = 0; 00337 }; 00338 00339 00342 class PropertyPage : public AbstractPropertyPage { 00343 public: 00345 enum PageType { 00346 kPropertyCachePage, 00347 kPropertyCacheFallbackPage, 00348 kDevicePropertyCachePage, 00349 }; 00350 00351 virtual ~PropertyPage(); 00352 00369 virtual PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00370 const StringPiece& property_name); 00371 00374 virtual void UpdateValue( 00375 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00376 const StringPiece& value); 00377 00384 virtual void WriteCohort(const PropertyCache::Cohort* cohort); 00385 00390 CacheInterface::KeyState GetCacheState(const PropertyCache::Cohort* cohort); 00391 00398 void set_cache_state_for_tests(const PropertyCache::Cohort* cohort, 00399 CacheInterface::KeyState x); 00400 00410 void DeleteProperty(const PropertyCache::Cohort* cohort, 00411 const StringPiece& property_name); 00412 00413 const GoogleString& key() const { return key_; } 00414 00415 AbstractLogRecord* log_record() { 00416 return request_context_->log_record(); 00417 } 00418 00420 void Read(const PropertyCache::CohortVector& cohort_list); 00421 00423 void Abort(); 00424 00425 protected: 00427 PropertyPage(PageType page_type, 00428 const StringPiece& key, 00429 const RequestContextPtr& request_context, 00430 AbstractMutex* mutex, 00431 PropertyCache* property_cache); 00432 00435 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00436 00438 virtual void Done(bool success) = 0; 00439 00440 private: 00441 class CallbackCollector; 00442 friend class CallbackCollector; 00443 friend class PropertyCache::CacheInterfaceCallback; 00444 00445 void SetupCohorts(const PropertyCache::CohortVector& cohort_list); 00446 00449 bool EncodeCacheEntry(const PropertyCache::Cohort* cohort, 00450 GoogleString* value); 00451 00453 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00454 00455 void CallDone(bool success) { 00456 was_read_ = true; 00457 Done(success); 00458 } 00459 00460 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00461 const PropertyValueProtobuf& proto); 00462 00463 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00464 00465 struct PropertyMapStruct { 00466 explicit PropertyMapStruct(AbstractLogRecord* log) 00467 : has_deleted_property(false), 00468 log_record(log) {} 00469 PropertyMap pmap; 00470 bool has_deleted_property; 00471 AbstractLogRecord* log_record; 00472 CacheInterface::KeyState cache_state; 00473 }; 00474 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00475 CohortDataMap; 00476 CohortDataMap cohort_data_map_; 00477 scoped_ptr<AbstractMutex> mutex_; 00478 GoogleString key_; 00479 RequestContextPtr request_context_; 00480 bool was_read_; 00481 PropertyCache* property_cache_; 00482 PageType page_type_; 00483 00484 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00485 }; 00486 00487 } 00488 00489 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_