Page Speed Optimization Libraries
1.4.26.1
|
00001 /* 00002 * Copyright 2011 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 00018 00021 00022 #ifndef NET_INSTAWEB_UTIL_SHARED_MEM_CACHE_DATA_H_ 00023 #define NET_INSTAWEB_UTIL_SHARED_MEM_CACHE_DATA_H_ 00024 00025 #include <cstddef> 00026 00027 #include "base/logging.h" 00028 #include "net/instaweb/util/public/basictypes.h" 00029 #include "net/instaweb/util/public/scoped_ptr.h" 00030 #include "net/instaweb/util/public/shared_mem_cache.h" 00031 #include "net/instaweb/util/public/string.h" 00032 00033 namespace net_instaweb { 00034 00035 class AbstractMutex; 00036 class AbstractSharedMem; 00037 class AbstractSharedMemSegment; 00038 class MessageHandler; 00039 00040 namespace SharedMemCacheData { 00041 00042 const BlockNum kInvalidBlock = -1; 00043 const EntryNum kInvalidEntry = -1; 00044 const size_t kHashSize = 16; 00045 00046 struct SectorStats { 00047 SectorStats(); 00048 00056 int64 num_put; 00057 int64 num_put_update; 00058 int64 num_put_replace; 00059 int64 num_put_concurrent_create; 00060 int64 num_put_concurrent_full_set; 00061 int64 num_put_spins; 00062 int64 num_get; 00063 int64 num_get_hit; 00064 00066 int64 used_entries; 00067 int64 used_blocks; 00068 00070 void Add(const SectorStats& other); 00071 00073 GoogleString Dump(size_t total_entries, size_t total_blocks) const; 00074 }; 00075 00076 struct SectorHeader { 00077 BlockNum free_list_front; 00078 EntryNum lru_list_front; 00079 EntryNum lru_list_rear; 00080 int32 padding; 00081 00082 SectorStats stats; 00083 00085 }; 00086 00087 struct CacheEntry { 00088 char hash_bytes[kHashSize]; 00089 int64 last_use_timestamp_ms; 00090 int32 byte_size; 00091 00095 EntryNum lru_prev; 00096 EntryNum lru_next; 00097 00098 BlockNum first_block; 00099 00101 bool creating : 1; 00102 00104 uint32 open_count : 31; 00105 00106 uint32 padding; 00107 }; 00108 00114 template<size_t kBlockSize> 00115 class Sector { 00116 public: 00126 Sector(AbstractSharedMemSegment* segment, size_t sector_offset, 00127 size_t cache_entries, size_t data_blocks); 00128 00135 bool Attach(MessageHandler* handler); 00136 00140 bool Initialize(MessageHandler* handler); 00141 00144 static size_t RequiredSize(AbstractSharedMem* shmem_runtime, 00145 size_t cache_entries, size_t data_blocks); 00146 00148 00150 void Lock(); 00151 void Unlock(); 00152 00155 BlockNum GetBlockSuccessor(BlockNum block) { 00156 DCHECK_GE(block, 0); 00157 DCHECK_LT(block, static_cast<BlockNum>(data_blocks_)); 00158 return block_successors_[block]; 00159 } 00160 00161 void SetBlockSuccessor(BlockNum block, BlockNum next) { 00162 DCHECK_GE(block, 0); 00163 DCHECK_LT(block, static_cast<BlockNum>(data_blocks_)); 00164 00165 DCHECK_GE(next, kInvalidBlock); 00166 DCHECK_LT(next, static_cast<BlockNum>(data_blocks_)); 00167 00168 block_successors_[block] = next; 00169 } 00170 00173 void LinkBlockSuccessors(const BlockVector& blocks) { 00174 for (size_t pos = 0; pos < blocks.size(); ++pos) { 00175 if (pos == (blocks.size() - 1)) { 00176 SetBlockSuccessor(blocks[pos], kInvalidBlock); 00177 } else { 00178 SetBlockSuccessor(blocks[pos], blocks[pos + 1]); 00179 } 00180 } 00181 } 00182 00185 00194 int AllocBlocksFromFreeList(int goal, BlockVector* blocks); 00195 00200 void ReturnBlocksToFreeList(const BlockVector& blocks); 00201 00204 00206 CacheEntry* EntryAt(EntryNum slot) { 00207 return reinterpret_cast<CacheEntry*>(directory_base_) + slot; 00208 } 00209 00212 void InsertEntryIntoLRU(EntryNum entry_num); 00213 00215 void UnlinkEntryFromLRU(EntryNum entry_num); 00216 00217 EntryNum OldestEntryNum() { 00218 return sector_header_->lru_list_rear; 00219 } 00220 00223 00224 char* BlockBytes(BlockNum block_num) { 00225 return blocks_base_ + kBlockSize * block_num; 00226 } 00227 00231 00233 static size_t DataBlocksForSize(size_t size) { 00234 return NeededPieces(size, kBlockSize); 00235 } 00236 00240 static size_t BytesInPortion(size_t total_bytes, size_t b, size_t total); 00241 00246 int BlockListForEntry(CacheEntry* entry, BlockVector* out_blocks); 00247 00250 00251 SectorStats* sector_stats() { return §or_header_->stats; } 00252 00255 void DumpStats(MessageHandler* handler); 00256 00257 private: 00259 struct MemLayout; 00260 00262 static size_t NeededPieces(size_t total, size_t piece_size) { 00263 return (total + piece_size - 1) / piece_size; 00264 } 00265 00267 size_t cache_entries_; 00268 size_t data_blocks_; 00269 00271 AbstractSharedMemSegment* segment_; 00272 scoped_ptr<AbstractMutex> mutex_; 00273 SectorHeader* sector_header_; 00274 BlockNum* block_successors_; 00275 char* directory_base_; 00276 char* blocks_base_; 00277 size_t sector_offset_; 00278 00279 DISALLOW_COPY_AND_ASSIGN(Sector); 00280 }; 00281 00282 } 00283 00284 } 00285 00286 #endif ///< NET_INSTAWEB_UTIL_SHARED_MEM_CACHE_DATA_H_