0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
FileBlockCache.h
Go to the documentation of this file.
1 /* -*- c++ -*-
2  * Copyright (C) 2007-2015 Hypertable, Inc.
3  *
4  * This file is part of Hypertable.
5  *
6  * Hypertable is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; version 3 of the
9  * License, or any later version.
10  *
11  * Hypertable is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19  * 02110-1301, USA.
20  */
21 
22 #ifndef Hypertable_RangeServer_FileBlockCache_h
23 #define Hypertable_RangeServer_FileBlockCache_h
24 
25 #include <AsyncComm/Event.h>
26 
27 #include <Common/Logger.h>
28 
29 #include <boost/multi_index_container.hpp>
30 #include <boost/multi_index/hashed_index.hpp>
31 #include <boost/multi_index/mem_fun.hpp>
32 #include <boost/multi_index/sequenced_index.hpp>
33 
34 #include <atomic>
35 #include <mutex>
36 
37 namespace Hypertable {
38  using namespace boost::multi_index;
39 
41 
42  static std::atomic<int> ms_next_file_id;
43 
44  public:
45  FileBlockCache(int64_t min_memory, int64_t max_memory, bool compressed)
46  : m_min_memory(min_memory), m_max_memory(max_memory), m_limit(max_memory),
47  m_available(max_memory), m_accesses(0), m_hits(0), m_compressed(compressed)
48  { HT_ASSERT(min_memory <= max_memory); }
49  ~FileBlockCache();
50 
51  bool compressed() { return m_compressed; }
52 
53  bool checkout(int file_id, uint64_t file_offset, uint8_t **blockp,
54  uint32_t *lengthp);
55  void checkin(int file_id, uint64_t file_offset);
56  bool insert(int file_id, uint64_t file_offset,
57  uint8_t *block, uint32_t length,
58  const EventPtr &event, bool checkout);
59  bool contains(int file_id, uint64_t file_offset);
60 
61  void increase_limit(int64_t amount);
62 
71  int64_t decrease_limit(int64_t amount);
72 
73  int64_t get_limit() {
74  std::lock_guard<std::mutex> lock(m_mutex);
75  return m_limit;
76  }
77 
82  void cap_memory_use() {
83  std::lock_guard<std::mutex> lock(m_mutex);
84  int64_t memory_used = m_limit - m_available;
85  if (memory_used > m_min_memory) {
86  m_limit -= m_available;
87  m_available = 0;
88  }
89  else {
90  m_limit = m_min_memory;
91  m_available = m_limit - memory_used;
92  }
93  }
94 
95  int64_t memory_used() {
96  std::lock_guard<std::mutex> lock(m_mutex);
97  return (int64_t)(m_limit - m_available);
98  }
99 
100  int64_t available() {
101  std::lock_guard<std::mutex> lock(m_mutex);
102  return m_available;
103  }
104 
105  static int get_next_file_id() {
106  return ++ms_next_file_id;
107  }
108  void get_stats(uint64_t *max_memoryp, uint64_t *available_memoryp,
109  uint64_t *accessesp, uint64_t *hitsp);
110  private:
111 
112  int64_t make_room(int64_t amount);
113 
114  inline static int64_t make_key(int file_id, uint64_t file_offset) {
115  HT_ASSERT(file_id < 268435456LL); // Can't be larger than 2^28
116  HT_ASSERT(file_offset < 68719476736LL); // Can't be larger than 2^36
117  return ((int64_t)file_id << 36) | (int64_t)file_offset;
118  }
119 
121  public:
123  BlockCacheEntry(int id, uint64_t offset, const EventPtr &e)
124  : file_id(id), file_offset(offset), event(e) {}
125 
126  int file_id {-1};
127  uint32_t length {};
128  uint64_t file_offset {};
129  uint8_t *block {};
130  uint32_t ref_count {};
132  int64_t key() const { return FileBlockCache::make_key(file_id, file_offset); }
133  };
134 
137  entry.ref_count--;
138  }
139  };
140 
141  struct HashI64 {
142  std::size_t operator()(int64_t x) const {
143  return (std::size_t)((x >> 32) * 31) ^ (std::size_t)x;
144  }
145  };
146 
147  typedef boost::multi_index_container<
148  BlockCacheEntry,
149  indexed_by<
150  sequenced<>,
151  hashed_unique<const_mem_fun<BlockCacheEntry, int64_t,
152  &BlockCacheEntry::key>, HashI64>
153  >
155 
156  typedef BlockCache::nth_index<0>::type Sequence;
157  typedef BlockCache::nth_index<1>::type HashIndex;
158 
161  int64_t m_min_memory;
162  int64_t m_max_memory;
163  int64_t m_limit;
164  int64_t m_available;
165  uint64_t m_accesses;
166  uint64_t m_hits;
168  };
169 
170 }
171 
172 #endif // Hypertable_RangeServer_FileBlockCache_h
FileBlockCache(int64_t min_memory, int64_t max_memory, bool compressed)
static std::mutex mutex
Definition: Logger.cc:43
static std::atomic< int > ms_next_file_id
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
Definition: Event.h:228
Declarations for Event.
boost::multi_index_container< BlockCacheEntry, indexed_by< sequenced<>, hashed_unique< const_mem_fun< BlockCacheEntry, int64_t,&BlockCacheEntry::key >, HashI64 > > > BlockCache
#define HT_ASSERT(_e_)
Definition: Logger.h:396
static int64_t make_key(int file_id, uint64_t file_offset)
uint32_t ref_count
Logging routines and macros.
int64_t key() const
BlockCacheEntry()
void cap_memory_use()
Sets limit to memory currently used, it will not reduce the limit below min_memory.
Hypertable definitions
BlockCache::nth_index< 0 >::type Sequence
std::size_t operator()(int64_t x) const
BlockCacheEntry(int id, uint64_t offset, const EventPtr &e)
EventPtr event
BlockCache::nth_index< 1 >::type HashIndex