0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
LocationCache.cc
Go to the documentation of this file.
1 /*
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 #include <Common/Compat.h>
23 
24 #include "LocationCache.h"
25 
26 #include <Common/InetAddr.h>
27 
28 #include <cassert>
29 #include <cstring>
30 #include <fstream>
31 #include <iostream>
32 
33 using namespace Hypertable;
34 using namespace std;
35 
39 void
40 LocationCache::insert(const char *table_name, RangeLocationInfo &range_loc_info,
41  bool pegged) {
42  lock_guard<mutex> lock(m_mutex);
43  Value *newval = new Value;
44  LocationMap::iterator iter;
45  LocationCacheKey key;
46 
47  assert(table_name);
48 
49  /*
50  HT_DEBUG_OUT << table_name << " start=" << start_row << " end=" << end_row
51  << " location=" << location << HT_END;
52  */
53 
54  newval->start_row = range_loc_info.start_row;
55  newval->end_row = range_loc_info.end_row;
56  newval->addrp = get_constant_address(range_loc_info.addr);
57  newval->pegged = pegged;
58 
59  key.table_name = m_strings.get(table_name);
60  key.end_row = (range_loc_info.end_row == "") ? 0 : newval->end_row.c_str();
61 
62  // remove old entry
63  if ((iter = m_location_map.find(key)) != m_location_map.end())
64  remove((*iter).second);
65 
66  // make room for the new entry
67  while (m_location_map.size() >= m_max_entries) {
68  if (m_tail->pegged)
69  move_to_head(m_tail);
70  else
71  remove(m_tail);
72  }
73 
74  // add to head
75  if (m_head == 0) {
76  assert(m_tail == 0);
77  newval->next = newval->prev = 0;
78  m_head = m_tail = newval;
79  }
80  else {
81  m_head->next = newval;
82  newval->prev = m_head;
83  newval->next = 0;
84  m_head = newval;
85  }
86 
87  // Insert the new entry into the map, recording an iterator to the entry
88  {
89  std::pair<LocationMap::iterator, bool> old_entry;
90  LocationMap::value_type map_value(key, newval);
91  old_entry = m_location_map.insert(map_value);
92  assert(old_entry.second);
93  newval->map_iter = old_entry.first;
94  }
95 
96 }
97 
102  for (AddressSet::iterator iter = m_addresses.begin();
103  iter != m_addresses.end(); ++iter)
104  delete *iter;
105  for (LocationMap::iterator lm_it = m_location_map.begin();
106  lm_it != m_location_map.end(); ++lm_it)
107  delete (*lm_it).second;
108 }
109 
110 
114 bool
115 LocationCache::lookup(const char * table_name, const char *rowkey,
116  RangeLocationInfo *range_loc_infop, bool inclusive) {
117  lock_guard<mutex> lock(m_mutex);
118 
119  Value* cacheval;
120  if (!lookup(table_name, rowkey, cacheval, inclusive))
121  return false;
122 
123  range_loc_infop->start_row = cacheval->start_row;
124  range_loc_infop->end_row = cacheval->end_row;
125  range_loc_infop->addr = *cacheval->addrp;
126 
127  return true;
128 }
129 
130 bool
131 LocationCache::lookup(const char * table_name, const char *rowkey,
132  RangeAddrInfo *range_addr_infop, bool inclusive) {
133  lock_guard<mutex> lock(m_mutex);
134 
135  Value* cacheval;
136  if (!lookup(table_name, rowkey, cacheval, inclusive))
137  return false;
138 
139  range_addr_infop->addr = *cacheval->addrp;
140 
141  return true;
142 }
143 
144 bool LocationCache::invalidate(const char *table_name, const char *rowkey) {
145  lock_guard<mutex> lock(m_mutex);
146  LocationMap::iterator iter;
147  LocationCacheKey key;
148 
149  assert(table_name);
150 
151  //cout << table_name << " row=" << rowkey << endl << flush;
152 
153  key.table_name = table_name;
154  key.end_row = rowkey;
155 
156  if ((iter = m_location_map.lower_bound(key)) == m_location_map.end())
157  return false;
158 
159  if (strcmp((*iter).first.table_name, table_name))
160  return false;
161 
162 #if 0
163  if (rowkey && strcmp(rowkey, (*iter).second->start_row.c_str()) < 0)
164  return false;
165 #endif
166  if ((rowkey == 0 && !(*iter).second->start_row.empty()) ||
167  (rowkey && strcmp(rowkey, (*iter).second->start_row.c_str()) < 0))
168  return false;
169 
170  remove((*iter).second);
171  return true;
172 }
173 
174 void LocationCache::invalidate_host(const string &hostname) {
175  lock_guard<mutex> lock(m_mutex);
176  CommAddress addr;
177 
178  addr.set_proxy(hostname);
179  const CommAddress *addrp = get_constant_address(addr);
180 
181  LocationMap::iterator iter = m_location_map.begin();
182  Value *val = 0;
183  while (iter != m_location_map.end()) {
184  val = 0;
185  if (iter->second->addrp == addrp)
186  val = iter->second;
187  ++iter;
188  if (val)
189  remove(val);
190  }
191 }
192 
193 
194 void LocationCache::display(std::ostream &out) {
195  for (Value *value = m_head; value; value = value->prev)
196  out << "DUMP: end=" << value->end_row << " start=" << value->start_row
197  << endl;
198 }
199 
200 bool LocationCache::lookup(const char * table_name, const char *rowkey,
201  Value*& cacheval, bool inclusive) {
202  LocationMap::iterator iter;
203  LocationCacheKey key;
204 
205  assert(table_name);
206 
207  key.table_name = table_name;
208  key.end_row = rowkey;
209 
210  if ((iter = m_location_map.lower_bound(key)) == m_location_map.end())
211  return false;
212 
213  if (strcmp((*iter).first.table_name, table_name))
214  return false;
215 
216  if (inclusive) {
217  if (strcmp(rowkey, (*iter).second->start_row.c_str()) < 0)
218  return false;
219  }
220  else {
221  if (strcmp(rowkey, (*iter).second->start_row.c_str()) <= 0)
222  return false;
223  }
224 
225  cacheval = (*iter).second;
226  move_to_head(cacheval);
227 
228  return true;
229 }
230 
231 
236 
237  if (m_head == cacheval)
238  return;
239 
240  // unstich entry from cache
241  cacheval->next->prev = cacheval->prev;
242  if (cacheval->prev == 0)
243  m_tail = cacheval->next;
244  else
245  cacheval->prev->next = cacheval->next;
246 
247  cacheval->next = 0;
248  cacheval->prev = m_head;
249  m_head->next = cacheval;
250  m_head = cacheval;
251 }
252 
253 
257 void LocationCache::remove(Value *cacheval) {
258  assert(cacheval);
259  if (m_tail == cacheval) {
260  m_tail = cacheval->next;
261  if (m_tail)
262  m_tail->prev = 0;
263  else {
264  assert (m_head == cacheval);
265  m_head = 0;
266  }
267  }
268  else if (m_head == cacheval) {
269  m_head = m_head->prev;
270  m_head->next = 0;
271  }
272  else {
273  cacheval->next->prev = cacheval->prev;
274  cacheval->prev->next = cacheval->next;
275  }
276  m_location_map.erase(cacheval->map_iter);
277  delete cacheval;
278 }
279 
280 
282  AddressSet::iterator iter = m_addresses.find(&addr);
283 
284  if (iter != m_addresses.end())
285  return *iter;
286 
287  CommAddress *new_addr = new CommAddress(addr);
288  m_addresses.insert(new_addr);
289  return new_addr;
290 }
291 
void display(std::ostream &)
const CommAddress * get_constant_address(const CommAddress &addr)
void insert(const char *table_name, RangeLocationInfo &range_loc_info, bool pegged=false)
Insert.
bool invalidate(const char *table_name, const char *rowkey)
Holds range start and end row plus location.
STL namespace.
Holds range location.
void move_to_head(Value *cacheval)
MoveToHead.
void set_proxy(const String &str)
Sets address type to CommAddress::PROXY and proxy name to p.
Definition: CommAddress.h:76
Compatibility Macros for C/C++.
bool lookup(const char *table_name, const char *rowkey, RangeLocationInfo *range_loc_infop, bool inclusive=false)
Lookup.
Hypertable definitions
Key type for Range location cache.
Definition: LocationCache.h:42
Internet address wrapper classes and utility functions.
void invalidate_host(const std::string &hostname)
void remove(Value *cacheval)
remove
Address abstraction to hold either proxy name or IPv4:port address.
Definition: CommAddress.h:52
std::map< LocationCacheKey, Value * >::iterator map_iter
Definition: LocationCache.h:91