Page Speed Optimization Libraries  1.7.30.2
net/instaweb/util/public/property_cache.h
Go to the documentation of this file.
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_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines