Page Speed Optimization Libraries
1.5.27.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 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 00212 PropertyCache(const GoogleString& cache_key_prefix, 00213 CacheInterface* cache, Timer* timer, 00214 Statistics* stats, ThreadSystem* threads); 00215 ~PropertyCache(); 00216 00220 void Read(PropertyPage* property_page) const; 00221 00224 void ReadWithCohorts(const CohortVector& cohort_list, 00225 PropertyPage* property_page) const; 00226 00228 const CohortVector GetAllCohorts() const { return cohort_list_; } 00229 00231 bool IsStable(const PropertyValue* property) const { 00232 return property->IsStable(mutations_per_1000_writes_threshold_); 00233 } 00234 00243 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00244 00245 void set_mutations_per_1000_writes_threshold(int x) { 00246 mutations_per_1000_writes_threshold_ = x; 00247 } 00248 00252 const Cohort* AddCohort(const StringPiece& cohort_name); 00253 00256 const Cohort* AddCohortWithCache(const StringPiece& cohort_name, 00257 CacheInterface* cache); 00258 00262 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00263 00267 void set_enabled(bool x) { enabled_ = x; } 00268 00270 bool enabled() const { return enabled_; } 00271 00276 GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const; 00277 00278 const CacheInterface* cache_backend() const { return cache_; } 00279 00281 static void InitCohortStats(const GoogleString& cohort, 00282 Statistics* statistics); 00283 00285 Timer* timer() const { return timer_; } 00286 00287 ThreadSystem* thread_system() const { return thread_system_; } 00288 00290 00291 private: 00292 GoogleString cache_key_prefix_; 00293 CacheInterface* cache_; 00294 Timer* timer_; 00295 Statistics* stats_; 00296 ThreadSystem* thread_system_; 00297 00298 int mutations_per_1000_writes_threshold_; 00299 typedef std::map<GoogleString, Cohort*> CohortMap; 00300 CohortMap cohorts_; 00302 CohortVector cohort_list_; 00303 bool enabled_; 00304 00305 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00306 }; 00307 00309 class AbstractPropertyPage { 00310 public: 00311 virtual ~AbstractPropertyPage(); 00314 virtual PropertyValue* GetProperty( 00315 const PropertyCache::Cohort* cohort, 00316 const StringPiece& property_name) const = 0; 00317 00320 virtual void UpdateValue( 00321 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00322 const StringPiece& value) = 0; 00323 00327 virtual void WriteCohort(const PropertyCache::Cohort* cohort) = 0; 00328 00330 virtual CacheInterface::KeyState GetCacheState( 00331 const PropertyCache::Cohort* cohort) = 0; 00332 00334 virtual void DeleteProperty(const PropertyCache::Cohort* cohort, 00335 const StringPiece& property_name) = 0; 00336 00337 virtual const GoogleString& key() const = 0; 00338 }; 00339 00340 00343 class PropertyPage : public AbstractPropertyPage { 00344 public: 00345 virtual ~PropertyPage(); 00346 00363 virtual PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00364 const StringPiece& property_name) const; 00365 00368 virtual void UpdateValue( 00369 const PropertyCache::Cohort* cohort, const StringPiece& property_name, 00370 const StringPiece& value); 00371 00378 virtual void WriteCohort(const PropertyCache::Cohort* cohort); 00379 00384 CacheInterface::KeyState GetCacheState(const PropertyCache::Cohort* cohort); 00385 00392 void set_cache_state_for_tests(const PropertyCache::Cohort* cohort, 00393 CacheInterface::KeyState x); 00394 00404 void DeleteProperty(const PropertyCache::Cohort* cohort, 00405 const StringPiece& property_name); 00406 00407 const GoogleString& key() const { return key_; } 00408 00409 AbstractLogRecord* log_record() { 00410 return request_context_->log_record(); 00411 } 00412 00414 virtual void LogPageCohortInfo(AbstractLogRecord* log_record, 00415 int cohort_index) {} 00416 00418 void Read(const PropertyCache::CohortVector& cohort_list); 00419 00421 void Abort(); 00422 00423 protected: 00425 PropertyPage(const StringPiece& key, 00426 const RequestContextPtr& request_context, 00427 AbstractMutex* mutex, 00428 PropertyCache* property_cache); 00429 00432 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00433 00435 virtual void Done(bool success) = 0; 00436 00437 private: 00438 class CallbackCollector; 00439 friend class CallbackCollector; 00440 friend class PropertyCache::CacheInterfaceCallback; 00441 00442 void SetupCohorts(const PropertyCache::CohortVector& cohort_list); 00443 00446 bool EncodeCacheEntry(const PropertyCache::Cohort* cohort, 00447 GoogleString* value); 00448 00450 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00451 00452 void CallDone(bool success) { 00453 was_read_ = true; 00454 Done(success); 00455 } 00456 00457 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00458 const PropertyValueProtobuf& proto); 00459 00460 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00461 00462 struct PropertyMapStruct { 00463 PropertyMapStruct(AbstractLogRecord* log, int index) 00464 : has_deleted_property(false), 00465 log_record(log), 00466 cohort_index(index) {} 00467 PropertyMap pmap; 00468 bool has_deleted_property; 00469 AbstractLogRecord* log_record; 00470 int cohort_index; 00471 CacheInterface::KeyState cache_state; 00472 }; 00473 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00474 CohortDataMap; 00475 CohortDataMap cohort_data_map_; 00476 scoped_ptr<AbstractMutex> mutex_; 00477 GoogleString key_; 00478 RequestContextPtr request_context_; 00479 bool was_read_; 00480 PropertyCache* property_cache_; 00481 00482 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00483 }; 00484 00485 } 00486 00487 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_