Page Speed Optimization Libraries
1.3.25.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 PropertyCache(const GoogleString& cache_key_prefix, 00210 CacheInterface* cache, Timer* timer, 00211 Statistics* stats, ThreadSystem* threads); 00212 ~PropertyCache(); 00213 00217 void Read(PropertyPage* property_page) const; 00218 00221 void ReadWithCohorts(PropertyPage* property_page, 00222 const StringVector cohort_names) const; 00223 00227 void MultiRead(PropertyPageStarVector* property_page_list) const; 00228 00234 void MultiReadWithCohorts(PropertyPageStarVector* property_page_list, 00235 const StringVector cohort_name_list) const; 00236 00237 void SetupCohorts(PropertyPage* property_page) const; 00238 00245 void WriteCohort(const Cohort* cohort, 00246 PropertyPage* property_page) const; 00247 00249 bool IsStable(const PropertyValue* property) const { 00250 return property->IsStable(mutations_per_1000_writes_threshold_); 00251 } 00252 00261 bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const; 00262 00265 void UpdateValue(const StringPiece& value, PropertyValue* property) const; 00266 00267 void set_mutations_per_1000_writes_threshold(int x) { 00268 mutations_per_1000_writes_threshold_ = x; 00269 } 00270 00274 const Cohort* AddCohort(const StringPiece& cohort_name); 00275 00278 const Cohort* AddCohortWithCache(const StringPiece& cohort_name, 00279 CacheInterface* cache); 00280 00284 const Cohort* GetCohort(const StringPiece& cohort_name) const; 00285 00289 void set_enabled(bool x) { enabled_ = x; } 00290 00292 bool enabled() const { return enabled_; } 00293 00298 GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const; 00299 00300 const CacheInterface* cache_backend() const { return cache_; } 00301 00303 static void InitCohortStats(const GoogleString& cohort, 00304 Statistics* statistics); 00305 00307 00308 private: 00309 GoogleString cache_key_prefix_; 00310 CacheInterface* cache_; 00311 Timer* timer_; 00312 Statistics* stats_; 00313 ThreadSystem* thread_system_; 00314 00315 int mutations_per_1000_writes_threshold_; 00316 typedef std::map<GoogleString, Cohort*> CohortMap; 00317 CohortMap cohorts_; 00319 StringVector cohort_name_list_; 00320 bool enabled_; 00321 00322 DISALLOW_COPY_AND_ASSIGN(PropertyCache); 00323 }; 00324 00327 class PropertyPage { 00328 public: 00329 virtual ~PropertyPage(); 00330 00347 PropertyValue* GetProperty(const PropertyCache::Cohort* cohort, 00348 const StringPiece& property_name); 00349 00359 void DeleteProperty(const PropertyCache::Cohort* cohort, 00360 const StringPiece& property_name); 00361 00362 const GoogleString& key() const { return key_; } 00363 00364 LogRecord* log_record() { 00365 return request_context_->log_record(); 00366 } 00367 00369 virtual void LogPageCohortInfo(LogRecord* log_record, int cohort_index) {} 00370 00371 protected: 00373 PropertyPage(AbstractMutex* mutex, 00374 const PropertyCache& property_cache, 00375 const StringPiece& key, 00376 const RequestContextPtr& request_context); 00377 00380 virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; } 00381 00383 virtual void Done(bool success) = 0; 00384 00385 private: 00386 class CallbackCollector; 00387 friend class CallbackCollector; 00388 friend class PropertyCache::CacheInterfaceCallback; 00389 friend class PropertyCache; 00390 00393 bool EncodeCacheEntry(const PropertyCache::Cohort* cohort, 00394 GoogleString* value); 00395 00397 bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort); 00398 00399 void CallDone(bool success) { 00400 was_read_ = true; 00401 Done(success); 00402 } 00403 00404 void AddValueFromProtobuf(const PropertyCache::Cohort* cohort, 00405 const PropertyValueProtobuf& proto); 00406 00407 typedef std::map<GoogleString, PropertyValue*> PropertyMap; 00408 00409 struct PropertyMapStruct { 00410 PropertyMapStruct(LogRecord* log, int index) 00411 : has_deleted_property(false), 00412 log_record(log), 00413 cohort_index(index) {} 00414 PropertyMap pmap; 00415 bool has_deleted_property; 00416 LogRecord* log_record; 00417 int cohort_index; 00418 }; 00419 typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*> 00420 CohortDataMap; 00421 CohortDataMap cohort_data_map_; 00422 scoped_ptr<AbstractMutex> mutex_; 00423 GoogleString key_; 00424 RequestContextPtr request_context_; 00425 bool was_read_; 00426 00427 DISALLOW_COPY_AND_ASSIGN(PropertyPage); 00428 }; 00429 00430 } 00431 00432 #endif ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_