Page Speed Optimization Libraries
1.7.30.2
|
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 AbstractPropertyStoreGetCallback; 00111 class PropertyCacheValues; 00112 class PropertyValueProtobuf; 00113 class PropertyPage; 00114 class PropertyStore; 00115 class Statistics; 00116 class ThreadSystem; 00117 class Timer; 00118 00119 typedef std::vector<PropertyPage*> PropertyPageStarVector; 00120 00122 class PropertyValue { 00123 public: 00124 StringPiece value() const; 00125 bool has_value() const { return valid_; } 00126 00129 int64 write_timestamp_ms() const; 00130 00133 bool was_read() { return was_read_; } 00134 00138 bool IsStable(int stable_hit_per_thousand_threshold) const; 00139 00142 bool IsRecentlyConstant(int num_writes_unchanged) const; 00143 00146 static bool IsIndexOfLeastSetBitSmaller(uint64 value, int index); 00147 00148 private: 00149 friend class PropertyCache; 00150 friend class PropertyPage; 00151 00153 PropertyValue(); 00154 ~PropertyValue(); 00155 00156 void set_was_read(bool was_read) { was_read_ = was_read; } 00157 00159 void InitFromProtobuf(const PropertyValueProtobuf& value); 00160 00167 void SetValue(const StringPiece& value, int64 now_ms); 00168 00169 PropertyValueProtobuf* protobuf() { return proto_.get(); } 00170 00171 scoped_ptr<PropertyValueProtobuf> proto_; 00172 bool changed_; 00173 bool valid_; 00174 bool was_read_; 00175 00176 DISALLOW_COPY_AND_ASSIGN(PropertyValue); 00177 }; 00178 00180 class PropertyCache { 00181 public: 00186 class Cohort { 00187 public: 00188 explicit Cohort(StringPiece name) { 00189 name.CopyToString(&name_); 00190 } 00191 const GoogleString& name() const { return name_; } 00192 00193 private: 00194 GoogleString name_; 00195 00196 DISALLOW_COPY_AND_ASSIGN(Cohort); 00197 }; 00198 00199 typedef std::vector<const Cohort*> CohortVector; 00200 00203 PropertyCache(PropertyStore* property_store, 00204 Timer* timer, 00205 Statistics* stats, 00206 ThreadSystem* threads); 00207 ~PropertyCache(); 00208 00212 void Read(PropertyPage* property_page) const; 00213 00216 void ReadWithCohorts(const CohortVector& cohort_list, 00217 PropertyPage* property_page) const; 00218 00220 const CohortVector GetAllCohorts() const { return cohort_list_; } 00221 00223 bool IsStable(const PropertyValue* property) const { 00224 return property->IsStable(mutations_per_1000_writes_threshold_); 00225 } 00226 00235 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00236 00237 void set_mutations_per_1000_writes_threshold(int x) { 00238 mutations_per_1000_writes_threshold_ = x; 00239 } 00240 00243 const Cohort* AddCohort(const StringPiece& cohort_name); 00244 00248 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00249 00253 void set_enabled(bool x) { enabled_ = x; } 00254 00256 bool enabled() const { return enabled_; } 00257 00259 static void InitCohortStats(const GoogleString& cohort, 00260 Statistics* statistics); 00261 00263 static GoogleString GetStatsPrefix(const GoogleString& cohort_name); 00264 00266 Timer* timer() const { return timer_; } 00267 00268 ThreadSystem* thread_system() const { return thread_system_; } 00269 00270 PropertyStore* property_store() { return property_store_; } 00271 00273 00274 private: 00275 PropertyStore* property_store_; 00276 Timer* timer_; 00277 Statistics* stats_; 00278 ThreadSystem* thread_system_; 00279 00280 int mutations_per_1000_writes_threshold_; 00281 typedef std::map<GoogleString, Cohort*> CohortMap; 00282 CohortMap cohorts_; 00284 CohortVector cohort_list_; 00285 bool enabled_; 00286 00287 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00288 }; 00289 00291 class AbstractPropertyPage { 00292 public: 00293 virtual ~AbstractPropertyPage(); 00296 virtual PropertyValue* GetProperty( 00297 const PropertyCache::Cohort* cohort, 00298 const StringPiece& property_name) = 0; 00299 00302 virtual void UpdateValue( 00303 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00304 const StringPiece& value) = 0; 00305 00309 virtual void WriteCohort(const PropertyCache::Cohort* cohort) = 0; 00310 00312 virtual CacheInterface::KeyState GetCacheState( 00313 const PropertyCache::Cohort* cohort) = 0; 00314 00316 virtual void DeleteProperty(const PropertyCache::Cohort* cohort, 00317 const StringPiece& property_name) = 0; 00318 }; 00319 00320 00323 class PropertyPage : public AbstractPropertyPage { 00324 public: 00326 enum PageType { 00327 kPropertyCachePage, 00328 kPropertyCacheFallbackPage, 00329 kDevicePropertyCachePage, 00330 }; 00331 00332 virtual ~PropertyPage(); 00333 00350 virtual PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00351 const StringPiece& property_name); 00352 00355 virtual void UpdateValue( 00356 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00357 const StringPiece& value); 00358 00365 virtual void WriteCohort(const PropertyCache::Cohort* cohort); 00366 00371 CacheInterface::KeyState GetCacheState(const PropertyCache::Cohort* cohort); 00372 00375 void SetCacheState(const PropertyCache::Cohort* cohort, 00376 CacheInterface::KeyState x); 00377 00387 void DeleteProperty(const PropertyCache::Cohort* cohort, 00388 const StringPiece& property_name); 00389 00390 AbstractLogRecord* log_record() { 00391 return request_context_->log_record(); 00392 } 00393 00395 void Read(const PropertyCache::CohortVector& cohort_list); 00396 00398 void Abort(); 00399 00402 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00403 00405 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00406 const PropertyValueProtobuf& proto); 00407 00409 PageType page_type() { return page_type_; } 00410 00412 bool IsCohortPresent(const PropertyCache::Cohort* cohort); 00413 00416 void FastFinishLookup(); 00417 00422 bool EncodePropertyCacheValues(const PropertyCache::Cohort* cohort, 00423 PropertyCacheValues* values); 00424 00425 protected: 00429 PropertyPage(PageType page_type, 00430 StringPiece url, 00431 StringPiece options_signature_hash, 00432 StringPiece cache_key_suffix, 00433 const RequestContextPtr& request_context, 00434 AbstractMutex* mutex, 00435 PropertyCache* property_cache); 00436 00438 virtual void Done(bool success) = 0; 00439 00440 private: 00441 void SetupCohorts(const PropertyCache::CohortVector& cohort_list); 00442 00444 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00445 00446 void CallDone(bool success) { 00447 was_read_ = true; 00448 Done(success); 00449 } 00450 00451 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00452 00453 struct PropertyMapStruct { 00454 explicit PropertyMapStruct(AbstractLogRecord* log) 00455 : has_deleted_property(false), 00456 log_record(log), 00457 has_value(false) {} 00458 PropertyMap pmap; 00459 bool has_deleted_property; 00460 AbstractLogRecord* log_record; 00461 CacheInterface::KeyState cache_state; 00462 bool has_value; 00463 }; 00464 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00465 CohortDataMap; 00466 CohortDataMap cohort_data_map_; 00467 scoped_ptr<AbstractMutex> mutex_; 00468 GoogleString url_; 00469 GoogleString options_signature_hash_; 00470 GoogleString cache_key_suffix_; 00471 RequestContextPtr request_context_; 00472 bool was_read_; 00473 PropertyCache* property_cache_; 00474 00475 00476 00477 00478 AbstractPropertyStoreGetCallback* property_store_callback_; 00479 PageType page_type_; 00480 00481 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00482 }; 00483 00484 } 00485 00486 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_