0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
TableInfoMap.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 
26 
27 #include <Common/Compat.h>
28 #include "TableInfoMap.h"
29 
32 
36 
37 #include <Common/FailureInducer.h>
38 
39 using namespace Hypertable;
40 using namespace std;
41 
43  m_map.clear();
44 }
45 
46 
47 bool TableInfoMap::lookup(const String &table_id, TableInfoPtr &info) {
48  lock_guard<mutex> lock(m_mutex);
49  InfoMap::iterator iter = m_map.find(table_id);
50  if (iter == m_map.end())
51  return false;
52  info = (*iter).second;
53  return true;
54 }
55 
56 void TableInfoMap::get(const String &table_id, TableInfoPtr &info) {
57  lock_guard<mutex> lock(m_mutex);
58  TableIdentifier table;
59 
60  InfoMap::iterator iter = m_map.find(table_id);
61  if (iter != m_map.end()) {
62  info = (*iter).second;
63  return;
64  }
65 
67 
68  if (m_schema_cache) {
69  if (!m_schema_cache->get(table_id, entry))
71  "Unable to locate schema for table %s", table_id.c_str());
72  }
73  else {
74  String tablefile = Global::toplevel_dir + "/tables/" + table_id;
75 
76  try {
77  DynamicBuffer valbuf;
78  Global::hyperspace->attr_get(tablefile, "schema", valbuf);
79  entry.schema.reset( Schema::new_instance((const char *)valbuf.base) );
80  entry.maintenance_disabled =
81  Global::hyperspace->attr_exists(tablefile, "maintenance_disabled");
82  }
83  catch (Exception &e) {
87  "Table %s does not exist in hyperspace", table_id.c_str());
88  throw;
89  }
90  }
91 
92  table.id = table_id.c_str();
93  table.generation = entry.schema->get_generation();
94 
95  info = make_shared<TableInfo>(&table, entry.schema, entry.maintenance_disabled);
96 
97  m_map[table_id] = info;
98 }
99 
100 
101 
102 void TableInfoMap::promote_staged_range(const TableIdentifier &table, RangePtr &range, const char *transfer_log) {
103  lock_guard<mutex> lock(m_mutex);
104  StringSet linked_logs;
105  int error;
106 
107  InfoMap::iterator iter = m_map.find(table.id);
108  HT_ASSERT(iter != m_map.end());
109 
110  if (transfer_log && *transfer_log) {
111  CommitLogReaderPtr commit_log_reader =
112  make_shared<CommitLogReader>(Global::log_dfs, transfer_log);
113  if (!commit_log_reader->empty()) {
114  CommitLogPtr log;
115  if (range->is_root())
116  log = Global::root_log;
117  else if (table.is_metadata())
118  log = Global::metadata_log;
119  else if (table.is_system())
120  log = Global::system_log;
121  else
122  log = Global::user_log;
123 
124  range->replay_transfer_log(commit_log_reader.get());
125 
126  commit_log_reader->get_linked_logs(linked_logs);
127 
128  if ((error = log->link_log(ClusterId::get(), commit_log_reader.get())) != Error::OK)
129  HT_THROWF(error, "Unable to link transfer log (%s) into commit log(%s)",
130  transfer_log, log->get_log_dir().c_str());
131  }
132  }
133 
134  HT_MAYBE_FAIL_X("add-staged-range-2", !table.is_system());
135 
136  linked_logs.insert(transfer_log);
137 
138  Global::remove_ok_logs->insert(linked_logs);
139 
140  // Record Range and RemoveOkLogs entities in RSML
141  if (Global::rsml_writer == 0)
142  HT_THROW(Error::SERVER_SHUTTING_DOWN, "Pointer to RSML Writer is NULL");
143  std::vector<MetaLog::EntityPtr> entities;
144  entities.push_back(range->metalog_entity());
145  entities.push_back(Global::remove_ok_logs);
146  Global::rsml_writer->record_state(entities);
147 
148  (*iter).second->promote_staged_range(range);
149 }
150 
151 
152 bool TableInfoMap::remove(const String &table_id, TableInfoPtr &info) {
153  lock_guard<mutex> lock(m_mutex);
154  InfoMap::iterator iter = m_map.find(table_id);
155  if (iter == m_map.end())
156  return false;
157  info = (*iter).second;
158  m_map.erase(iter);
159  return true;
160 }
161 
162 
163 void TableInfoMap::get_all(std::vector<TableInfoPtr> &tv) {
164  lock_guard<mutex> lock(m_mutex);
165  for (InfoMap::iterator iter = m_map.begin(); iter != m_map.end(); ++iter)
166  tv.push_back((*iter).second);
167 }
168 
169 
170 void TableInfoMap::get_ranges(Ranges &ranges, StringSet *remove_ok_logs) {
171  lock_guard<mutex> lock(m_mutex);
172  int32_t count = 0;
173 
174  // reserve space in vector
175  for (InfoMap::iterator iter = m_map.begin(); iter != m_map.end(); iter++)
176  count += (*iter).second->get_range_count();
177  ranges.array.reserve(count+10);
178 
179  for (InfoMap::iterator iter = m_map.begin(); iter != m_map.end(); iter++)
180  (*iter).second->get_ranges(ranges);
181 
182  {
183  lock_guard<mutex> lock2(Global::mutex);
184  if (Global::remove_ok_logs && remove_ok_logs)
185  Global::remove_ok_logs->get(*remove_ok_logs);
186  }
187 
188 }
189 
190 
192  lock_guard<mutex> lock(m_mutex);
193  m_map.clear();
194 }
195 
197  lock_guard<mutex> lock(m_mutex);
198  return m_map.empty();
199 }
200 
201 
203  lock_guard<mutex> lock(m_mutex);
204  merge_unlocked(other);
205 }
206 
208  vector<MetaLog::EntityPtr> &entities,
209  StringSet &transfer_logs) {
210  lock_guard<mutex> lock(m_mutex);
211  if (Global::rsml_writer == 0)
213  Global::remove_ok_logs->insert(transfer_logs);
214  entities.push_back(Global::remove_ok_logs);
215  Global::rsml_writer->record_state(entities);
216  merge_unlocked(other);
217  entities.clear();
218 }
219 
220 
222  InfoMap::iterator other_iter, iter;
223  Ranges ranges;
224 
225  for (other_iter = other->m_map.begin();
226  other_iter != other->m_map.end(); ++other_iter) {
227 
228  iter = m_map.find( (*other_iter).first );
229 
230  if (iter == m_map.end()) {
231  m_map[ (*other_iter).first ] = (*other_iter).second;
232  }
233  else {
234  ranges.array.clear();
235  (*other_iter).second->get_ranges(ranges);
236  for (auto &rd : ranges.array)
237  (*iter).second->add_range(rd.range);
238  }
239 
240  }
241  other->clear();
242 }
std::set< String > StringSet
STL Set managing Strings.
Definition: StringExt.h:42
InfoMap m_map
table_id-to-TableInfoPtr map
Definition: TableInfoMap.h:219
The FailureInducer simulates errors.
Cache entry for Hyperspace table data.
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
bool remove(const String &table_id, TableInfoPtr &info)
Removes a table from the map.
Declarations for CommitLogReader.
STL namespace.
void promote_staged_range(const TableIdentifier &table, RangePtr &range, const char *transfer_log)
Adds a staged range.
A dynamic, resizable and reference counted memory buffer.
Definition: DynamicBuffer.h:42
static MetaLogEntityRemoveOkLogsPtr remove_ok_logs
Definition: Global.h:71
std::shared_ptr< CommitLogReader > CommitLogReaderPtr
Smart pointer to CommitLogReader.
#define HT_ASSERT(_e_)
Definition: Logger.h:396
void merge_unlocked(TableInfoMap *other)
Merges in another map (without locking mutex).
void get_ranges(Ranges &ranges, StringSet *remove_ok_logs=0)
Gets set of live RangeData objects and corresponding transfer logs that can be safely removed...
Declarations for TableInfoMap.
static Hyperspace::SessionPtr hyperspace
Definition: Global.h:63
static std::string toplevel_dir
Definition: Global.h:108
std::vector< RangeData > array
Vector of RangeData objects.
Definition: TableInfo.h:85
static CommitLogPtr root_log
Definition: Global.h:80
void merge(TableInfoMap *other)
Merges in another map.
static uint64_t get()
Gets the cluster ID.
Definition: ClusterId.h:85
static MetaLog::WriterPtr rsml_writer
Definition: Global.h:81
Compatibility Macros for C/C++.
virtual ~TableInfoMap()
Destructor.
Definition: TableInfoMap.cc:42
Hypertable definitions
static Schema * new_instance(const std::string &buf)
Creates schema object from XML schema string.
Definition: Schema.cc:202
bool empty()
Determines if map is empty.
static CommitLogPtr system_log
Definition: Global.h:78
void get(const String &table_id, TableInfoPtr &info)
Gets the TableInfo object for a table, creating one if not found.
Definition: TableInfoMap.cc:56
std::shared_ptr< TableInfo > TableInfoPtr
Smart pointer to TableInfo.
Definition: TableInfo.h:312
SchemaPtr schema
Smart pointer to Schema object.
#define HT_THROWF(_code_, _fmt_,...)
Definition: Error.h:490
std::shared_ptr< Range > RangePtr
Smart pointer to Range.
Definition: Range.h:404
uint8_t * base
Pointer to the allocated memory buffer.
std::shared_ptr< CommitLog > CommitLogPtr
Smart pointer to CommitLog.
Definition: CommitLog.h:223
bool lookup(const String &table_id, TableInfoPtr &info)
Returns the TableInfo object for a given table.
Definition: TableInfoMap.cc:47
This is a generic exception class for Hypertable.
Definition: Error.h:314
static std::mutex mutex
Definition: Global.h:62
static CommitLogPtr user_log
Definition: Global.h:77
void clear()
Clears the map.
#define HT_MAYBE_FAIL_X(_label_, _exp_)
void get_all(std::vector< TableInfoPtr > &tv)
Gets all TableInfo objects in map.
static Hypertable::FilesystemPtr log_dfs
Definition: Global.h:65
Declarations for CommitLog.
#define HT_THROW(_code_, _msg_)
Definition: Error.h:478
Manages live range map and set of log names that can be safely removed.
Definition: TableInfoMap.h:67
Declarations for ClusterId.
bool maintenance_disabled
Flag indicating if "maintenance_disabled" attribute is set.
Holds vector of RangeData objects and memory arena.
Definition: TableInfo.h:72
static CommitLogPtr metadata_log
Definition: Global.h:79
int code() const
Returns the error code.
Definition: Error.h:391