Page Speed Optimization Libraries  1.4.26.1
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 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   typedef std::vector<const Cohort*> CohortVector;
00210 
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   bool IsStable(const PropertyValue* property) const {
00228     return property->IsStable(mutations_per_1000_writes_threshold_);
00229   }
00230 
00239   bool IsExpired(const PropertyValue* property_value, int64 ttl_ms) const;
00240 
00241   void set_mutations_per_1000_writes_threshold(int x) {
00242     mutations_per_1000_writes_threshold_ = x;
00243   }
00244 
00248   const Cohort* AddCohort(const StringPiece& cohort_name);
00249 
00252   const Cohort* AddCohortWithCache(const StringPiece& cohort_name,
00253                                    CacheInterface* cache);
00254 
00258   const Cohort* GetCohort(const StringPiece& cohort_name) const;
00259 
00263   void set_enabled(bool x) { enabled_ = x; }
00264 
00266   bool enabled() const { return enabled_; }
00267 
00272   GoogleString CacheKey(const StringPiece& key, const Cohort* cohort) const;
00273 
00274   const CacheInterface* cache_backend() const { return cache_; }
00275 
00277   static void InitCohortStats(const GoogleString& cohort,
00278                               Statistics* statistics);
00279 
00281   Timer* timer() const { return timer_; }
00282 
00284 
00285  private:
00286   GoogleString cache_key_prefix_;
00287   CacheInterface* cache_;
00288   Timer* timer_;
00289   Statistics* stats_;
00290   ThreadSystem* thread_system_;
00291 
00292   int mutations_per_1000_writes_threshold_;
00293   typedef std::map<GoogleString, Cohort*> CohortMap;
00294   CohortMap cohorts_;
00296   CohortVector cohort_list_;
00297   bool enabled_;
00298 
00299   DISALLOW_COPY_AND_ASSIGN(PropertyCache);
00300 };
00301 
00304 class PropertyPage {
00305  public:
00306   virtual ~PropertyPage();
00307 
00324   virtual PropertyValue* GetProperty(const PropertyCache::Cohort* cohort,
00325                                      const StringPiece& property_name) const;
00326 
00329   virtual void UpdateValue(
00330       const PropertyCache::Cohort* cohort, const StringPiece& property_name,
00331       const StringPiece& value);
00332 
00339   virtual void WriteCohort(const PropertyCache::Cohort* cohort);
00340 
00345   CacheInterface::KeyState GetCacheState(const PropertyCache::Cohort* cohort);
00346 
00353   void set_cache_state_for_tests(const PropertyCache::Cohort* cohort,
00354                                  CacheInterface::KeyState x);
00355 
00365   void DeleteProperty(const PropertyCache::Cohort* cohort,
00366                       const StringPiece& property_name);
00367 
00368   const GoogleString& key() const { return key_; }
00369 
00370   LogRecord* log_record() {
00371     return request_context_->log_record();
00372   }
00373 
00375   virtual void LogPageCohortInfo(LogRecord* log_record, int cohort_index) {}
00376 
00377  protected:
00379   PropertyPage(const StringPiece& key,
00380                const RequestContextPtr& request_context,
00381                AbstractMutex* mutex,
00382                PropertyCache* property_cache);
00383 
00386   virtual bool IsCacheValid(int64 write_timestamp_ms) const { return true; }
00387 
00389   virtual void Done(bool success) = 0;
00390 
00391  private:
00392   class CallbackCollector;
00393   friend class CallbackCollector;
00394   friend class PropertyCache::CacheInterfaceCallback;
00395   friend class PropertyCache;
00396 
00397   void SetupCohorts(const PropertyCache::CohortVector& cohort_list);
00398 
00401   bool EncodeCacheEntry(const PropertyCache::Cohort* cohort,
00402                         GoogleString* value);
00403 
00405   bool HasPropertyValueDeleted(const PropertyCache::Cohort* cohort);
00406 
00407   void CallDone(bool success) {
00408     was_read_ = true;
00409     Done(success);
00410   }
00411 
00412   void AddValueFromProtobuf(const PropertyCache::Cohort* cohort,
00413                             const PropertyValueProtobuf& proto);
00414 
00415   typedef std::map<GoogleString, PropertyValue*> PropertyMap;
00416 
00417   struct PropertyMapStruct {
00418     PropertyMapStruct(LogRecord* log, int index)
00419         : has_deleted_property(false),
00420           log_record(log),
00421           cohort_index(index) {}
00422     PropertyMap pmap;
00423     bool has_deleted_property;
00424     LogRecord* log_record;
00425     int cohort_index;
00426     CacheInterface::KeyState cache_state;
00427   };
00428   typedef std::map<const PropertyCache::Cohort*, PropertyMapStruct*>
00429       CohortDataMap;
00430   CohortDataMap cohort_data_map_;
00431   scoped_ptr<AbstractMutex> mutex_;
00432   GoogleString key_;
00433   RequestContextPtr request_context_;
00434   bool was_read_;
00435   PropertyCache* property_cache_; 
00436 
00437   DISALLOW_COPY_AND_ASSIGN(PropertyPage);
00438 };
00439 
00440 }  
00441 
00442 #endif  ///< NET_INSTAWEB_UTIL_PUBLIC_PROPERTY_CACHE_H_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines