0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
LiveFileTracker.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 "Global.h"
25 #include "LiveFileTracker.h"
26 #include "MetadataNormal.h"
27 #include "MetadataRoot.h"
28 
29 #include <Hypertable/Lib/Key.h>
30 
31 #include <Common/FailureInducer.h>
32 
33 using namespace Hypertable;
34 using namespace std;
35 
37  SchemaPtr &schema_ptr,
38  const RangeSpec *range,
39  const String &ag_name) :
40  m_identifier(*identifier), m_schema_ptr(schema_ptr),
41  m_start_row(range->start_row), m_end_row(range->end_row),
42  m_ag_name(ag_name), m_need_update(false), m_is_root(false),
43  m_last_nextcsid(0), m_cur_nextcsid(0), m_total_blocks(0) {
44 
45  m_is_root = (m_identifier.is_metadata() && *range->start_row == 0
46  && !strcmp(range->end_row, Key::END_ROOT_ROW));
47 
49 
50 }
51 
52 void LiveFileTracker::update_live(const String &add, std::vector<String> &deletes, uint32_t nextcsid, int64_t total_blocks) {
53  lock_guard<mutex> lock(m_mutex);
54  for (size_t i=0; i<deletes.size(); i++)
55  m_live.erase(strip_basename(deletes[i]));
56  if (add != "")
57  m_live.insert(strip_basename(add));
58  m_cur_nextcsid = nextcsid;
59  m_total_blocks = total_blocks;
60  m_need_update = true;
61 }
62 
63 
64 void LiveFileTracker::add_references(const std::vector<String> &filev) {
65  lock_guard<mutex> lock(m_mutex);
66  FileRefCountMap::iterator iter;
67  for (size_t i=0; i<filev.size(); i++) {
68  iter = m_referenced.find(strip_basename(filev[i]));
69  if (iter == m_referenced.end())
70  m_referenced[strip_basename(filev[i])] = 1;
71  else
72  (*iter).second++;
73  }
74 }
75 
81 void LiveFileTracker::remove_references(const std::vector<String> &filev) {
82  lock_guard<mutex> lock(m_mutex);
83  FileRefCountMap::iterator iter;
84  for (size_t i=0; i<filev.size(); i++) {
85  iter = m_referenced.find(strip_basename(filev[i]));
86  HT_ASSERT(iter != m_referenced.end());
87  if (--(*iter).second == 0) {
88  m_referenced.erase(iter);
89  if (m_blocked.count(strip_basename(filev[i])) > 0)
90  m_need_update = true;
91  }
92  }
93 }
94 
95 
97 
98  if (!m_need_update)
99  return;
100 
101  String file_list;
102  String printable_list;
103  String end_row;
104  int retry_count = 0;
105 
106  try_again:
107 
108  file_list.clear();
109  end_row.clear();
110 
111  m_mutex.lock();
112 
113  for (const auto &file : m_live) {
114  file_list += file + ";\n";
115  printable_list += file + "; ";
116  }
117 
118  m_blocked.clear();
119  for (const auto &v : m_referenced) {
120  if (m_live.count(v.first) == 0) {
121  file_list += format("#%s;\n", v.first.c_str());
122  printable_list += String("#") + v.first + "; ";
123  m_blocked.insert(v.first);
124  }
125  }
126 
127  end_row = m_end_row;
128 
129  m_update_mutex.lock();
130  m_mutex.unlock();
131 
132  try {
133  if (m_is_root) {
134  MetadataRoot metadata(m_schema_ptr);
136  metadata.write_files(m_ag_name, file_list, m_total_blocks, m_cur_nextcsid);
138  }
139  else
140  metadata.write_files(m_ag_name, file_list, m_total_blocks);
141  }
142  else {
143  MetadataNormal metadata(&m_identifier, end_row);
145  metadata.write_files(m_ag_name, file_list, m_total_blocks, m_cur_nextcsid);
147  }
148  else
149  metadata.write_files(m_ag_name, file_list, m_total_blocks);
150  }
151  HT_MAYBE_FAIL("LiveFileTracker-update_files_column");
152  }
153  catch (Hypertable::Exception &e) {
154  m_update_mutex.unlock();
155  HT_ERROR_OUT <<"Problem updating 'Files' column of METADATA, retry count=" << retry_count
156  << " : " << e << HT_END;
157  if (retry_count < 6) {
158  ++retry_count;
159  this_thread::sleep_for(chrono::milliseconds(15000));
160  goto try_again;
161  }
162  HT_THROW2(e.code(), e, "Problem updating 'Files' column of METADATA: ");
163  }
164 
165  m_need_update = false;
166  m_update_mutex.unlock();
167 
168 }
169 
170 
171 void LiveFileTracker::get_file_data(String &file_list, int64_t *block_countp, bool include_blocked) {
172  lock_guard<mutex> lock(m_mutex);
173 
174  file_list = "";
175 
176  for (const auto &file : m_live)
177  file_list += file + ";\n";
178 
179  if (include_blocked) {
180  m_blocked.clear();
181  for (const auto &v : m_referenced) {
182  if (m_live.count(v.first) == 0) {
183  file_list += format("#%s;\n", v.first.c_str());
184  m_blocked.insert(v.first);
185  }
186  }
187  }
188 
189  *block_countp = m_total_blocks;
190 }
191 
193  lock_guard<mutex> lock(m_mutex);
194  file_list = "";
195  for (const auto &file : m_live)
196  file_list += file + ";";
197 }
198 
200  size_t basename_len = m_file_basename.length();
201  HT_ASSERT(!strncmp(fname.c_str(), m_file_basename.c_str(), basename_len));
202  return fname.substr(basename_len);
203 }
void add_references(const std::vector< String > &filev)
Adds a set of files to the referenced file set.
The FailureInducer simulates errors.
Range specification.
Definition: RangeSpec.h:40
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
TableIdentifierManaged m_identifier
String format(const char *fmt,...)
Returns a String using printf like format facilities Vanilla snprintf is about 1.5x faster than this...
Definition: String.cc:37
void update_live(const String &add, std::vector< String > &deletes, uint32_t nextcsid, int64_t total_blocks)
Updates the live file set.
STL namespace.
LiveFileTracker(const TableIdentifier *identifier, SchemaPtr &schema_ptr, const RangeSpec *range, const String &ag_name)
void add(const Key &key, uint8_t flag, const void *value, uint32_t value_len, TableMutatorAsync *value_index_mutator, TableMutatorAsync *qualifier_index_mutator)
Definition: IndexTables.cc:34
std::set< String > m_blocked
#define HT_ASSERT(_e_)
Definition: Logger.h:396
void get_file_data(String &file_list, int64_t *block_countp, bool include_blocked)
Returns ' ' separated list of files, suitable for writing into the 'Files' column of METADATA...
const char * end_row
Definition: RangeSpec.h:60
static std::string toplevel_dir
Definition: Global.h:108
void remove_references(const std::vector< String > &filev)
Decrements the reference count of each file in the given vector.
virtual void write_files(const String &ag_name, const String &files, int64_t total_blocks)
Compatibility Macros for C/C++.
#define HT_END
Definition: Logger.h:220
#define HT_ERROR_OUT
Definition: Logger.h:301
Hypertable definitions
void update_files_column()
Updates the 'Files' METADATA column if it needs updating.
const char * start_row
Definition: RangeSpec.h:59
void get_file_list(String &file_list)
Populates string with live files separated by ';'.
String strip_basename(const String &fname)
This is a generic exception class for Hypertable.
Definition: Error.h:314
static const char * END_ROOT_ROW
Definition: Key.h:50
std::shared_ptr< Schema > SchemaPtr
Smart pointer to Schema.
Definition: Schema.h:465
#define HT_MAYBE_FAIL(_label_)
virtual void write_files(const String &ag_name, const String &files, int64_t total_blocks)
int code() const
Returns the error code.
Definition: Error.h:391
#define HT_THROW2(_code_, _ex_, _msg_)
Definition: Error.h:484