0.9.8.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
OperationDropTable.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 
28 #include <Common/Compat.h>
29 #include "OperationDropTable.h"
30 
34 
35 #include <Hypertable/Lib/Key.h>
36 
37 #include <Hyperspace/Session.h>
38 
39 #include <Common/Error.h>
40 #include <Common/FailureInducer.h>
41 #include <Common/ScopeGuard.h>
42 #include <Common/Serialization.h>
43 
44 #include <boost/algorithm/string.hpp>
45 
46 #include <algorithm>
47 #include <iterator>
48 #include <vector>
49 
50 using namespace Hypertable;
51 using namespace Hyperspace;
52 using namespace std;
53 
55  bool if_exists, TableParts parts)
56  : Operation(context, MetaLog::EntityType::OPERATION_DROP_TABLE),
57  m_params(name, if_exists), m_parts(parts) {
58 }
59 
61  const MetaLog::EntityHeader &header_)
62  : Operation(context, header_) {
63 }
64 
66  : Operation(context, event, MetaLog::EntityType::OPERATION_DROP_TABLE) {
67  const uint8_t *ptr = event->payload;
68  size_t remaining = event->payload_len;
69  m_params.decode(&ptr, &remaining);
70  m_exclusivities.insert(m_params.name());
72 }
73 
160  String index_id;
161  String qualifier_index_id;
162  String index_name = Filesystem::dirname(m_params.name());
163  if (index_name == "/")
164  index_name += String("^") + Filesystem::basename(m_params.name());
165  else
166  index_name += String("/^") + Filesystem::basename(m_params.name());
167  String qualifier_index_name = Filesystem::dirname(m_params.name());
168  if (qualifier_index_name == "/")
169  qualifier_index_name += String("^^") + Filesystem::basename(m_params.name());
170  else
171  qualifier_index_name += String("/^^") + Filesystem::basename(m_params.name());
172  bool is_namespace;
173  DispatchHandlerOperationPtr op_handler;
174  TableIdentifier table;
175  int32_t state = get_state();
176 
177  HT_INFOF("Entering DropTable-%lld(%s, if_exists=%s, parts=%s) state=%s",
178  (Lld)header.id, m_params.name().c_str(),
179  m_params.if_exists() ? "true" : "false",
180  m_parts.to_string().c_str(), OperationState::get_text(state));
181 
182  switch (state) {
183 
185  // Check to see if namespace exists
186  if(m_context->namemap->name_to_id(m_params.name(), m_id, &is_namespace)) {
187  if (is_namespace && !m_params.if_exists()) {
188  complete_error(Error::TABLE_NOT_FOUND, format("%s is a namespace", m_params.name().c_str()));
189  break;
190  }
191  }
192  else {
193  if (m_params.if_exists())
194  complete_ok();
195  else
197  break;
198  }
200  m_context->mml_writer->record_state(shared_from_this());
201  HT_MAYBE_FAIL("drop-table-INITIAL");
202  // drop through ...
203 
205 
207 
208  if (m_parts.value_index() &&
209  m_context->namemap->name_to_id(index_name, index_id)) {
210  HT_INFOF(" Dropping index table %s (id %s)",
211  index_name.c_str(), index_id.c_str());
212  stage_subop(make_shared<OperationDropTable>(m_context, index_name, false,
214  HT_MAYBE_FAIL("drop-table-DROP_VALUE_INDEX-1");
215  record_state();
216  HT_MAYBE_FAIL("drop-table-DROP_VALUE_INDEX-2");
217  break;
218  }
219  // drop through ...
220 
222 
223  if (!validate_subops())
224  break;
225 
226  {
227  lock_guard<mutex> lock(m_mutex);
228  m_dependencies.clear();
230  m_dependencies.insert(m_id + " move range");
232  }
233 
234  if (m_parts.qualifier_index() &&
235  m_context->namemap->name_to_id(qualifier_index_name,
236  qualifier_index_id)) {
237  HT_INFOF(" Dropping qualifier index table %s (id %s)",
238  qualifier_index_name.c_str(), qualifier_index_id.c_str());
239  stage_subop(make_shared<OperationDropTable>(m_context, qualifier_index_name,
241  HT_MAYBE_FAIL("drop-table-DROP_QUALIFIER_INDEX-1");
242  record_state();
243  HT_MAYBE_FAIL("drop-table-DROP_QUALIFIER_INDEX-2");
244  }
245  break;
246 
248 
249  if (!validate_subops())
250  break;
251 
252  if (!m_parts.primary()) {
253  complete_ok();
254  break;
255  }
256 
257  {
258  StringSet servers;
260  {
261  lock_guard<mutex> lock(m_mutex);
262  for (StringSet::iterator iter=servers.begin(); iter!=servers.end(); ++iter) {
263  if (m_completed.count(*iter) == 0) {
264  m_dependencies.insert(*iter);
265  m_servers.insert(*iter);
266  }
267  }
269  }
270  }
271  m_context->mml_writer->record_state(shared_from_this());
272  HT_MAYBE_FAIL("drop-table-SCAN_METADATA");
273  break;
274 
276  {
277  if (!m_context->test_mode) {
278  table.id = m_id.c_str();
279  table.generation = 0;
280  op_handler = make_shared<DispatchHandlerOperationDropTable>(m_context, table);
281  op_handler->start(m_servers);
282  if (!op_handler->wait_for_completion()) {
283  std::set<DispatchHandlerOperation::Result> results;
284  op_handler->get_results(results);
285  for (const auto &result : results) {
286  if (result.error == Error::OK ||
287  result.error == Error::TABLE_NOT_FOUND) {
288  lock_guard<mutex> lock(m_mutex);
289  m_completed.insert(result.location);
290  }
291  else
292  HT_WARNF("Drop table error at %s - %s (%s)", result.location.c_str(),
293  Error::get_text(result.error), result.msg.c_str());
294  }
295  {
296  lock_guard<mutex> lock(m_mutex);
297  m_servers.clear();
299  m_dependencies.insert(m_id + " move range");
301  }
302  m_context->mml_writer->record_state(shared_from_this());
303  break;
304  }
305  m_context->monitoring->invalidate_id_mapping(m_id);
306  }
307  HT_MAYBE_FAIL("drop-table-ISSUE_REQUESTS");
309  record_state();
310  break;
311  }
312 
314 
315  try {
316  m_context->namemap->drop_mapping(m_params.name());
317  string filename = m_context->toplevel_dir + "/tables/" + m_id;
318  m_context->hyperspace->unlink(filename.c_str());
319  }
320  catch (Exception &e) {
323  HT_THROW2F(e.code(), e, "Error executing DropTable %s",
324  m_params.name().c_str());
325  }
326  complete_ok();
327  break;
328 
329  default:
330  HT_FATALF("Unrecognized state %d", state);
331  }
332 
333  HT_INFOF("Leaving DropTable-%lld(%s) state=%s",
334  (Lld)header.id, m_params.name().c_str(), OperationState::get_text(m_state));
335 }
336 
337 
338 void OperationDropTable::display_state(std::ostream &os) {
339  os << " name=" << m_params.name() << " id=" << m_id << " ";
340 }
341 
343  return 1;
344 }
345 
347  size_t length = m_params.encoded_length() +
349  length += 4;
350  for (auto &location : m_completed)
351  length += Serialization::encoded_length_vstr(location);
352  length += 4;
353  for (auto &location : m_servers)
354  length += Serialization::encoded_length_vstr(location);
355  length += m_parts.encoded_length();
356  return length;
357 }
358 
359 void OperationDropTable::encode_state(uint8_t **bufp) const {
360  m_params.encode(bufp);
363  for (auto &location : m_completed)
364  Serialization::encode_vstr(bufp, location);
365  Serialization::encode_i32(bufp, m_servers.size());
366  for (auto &location : m_servers)
367  Serialization::encode_vstr(bufp, location);
368  m_parts.encode(bufp);
369 }
370 
371 void OperationDropTable::decode_state(uint8_t version, const uint8_t **bufp, size_t *remainp) {
372  m_params.decode(bufp, remainp);
373  m_id = Serialization::decode_vstr(bufp, remainp);
374  size_t length = Serialization::decode_i32(bufp, remainp);
375  for (size_t i=0; i<length; i++)
376  m_completed.insert( Serialization::decode_vstr(bufp, remainp) );
377  length = Serialization::decode_i32(bufp, remainp);
378  for (size_t i=0; i<length; i++)
379  m_servers.insert( Serialization::decode_vstr(bufp, remainp) );
380  m_parts.decode(bufp, remainp);
381 }
382 
383 void OperationDropTable::decode_state_old(uint8_t version, const uint8_t **bufp, size_t *remainp) {
384  {
385  bool if_exists = Serialization::decode_bool(bufp, remainp);
386  string name = Serialization::decode_vstr(bufp, remainp);
388  }
389  m_id = Serialization::decode_vstr(bufp, remainp);
390  size_t length = Serialization::decode_i32(bufp, remainp);
391  for (size_t i=0; i<length; i++)
392  m_completed.insert( Serialization::decode_vstr(bufp, remainp) );
393  if (version >= 2) {
394  length = Serialization::decode_i32(bufp, remainp);
395  for (size_t i=0; i<length; i++)
396  m_servers.insert( Serialization::decode_vstr(bufp, remainp) );
397  if (version >= 3) {
398  int8_t parts = (int8_t)Serialization::decode_byte(bufp, remainp);
399  m_parts = TableParts(parts);
400  }
401  }
402 }
403 
405  return "OperationDropTable";
406 }
407 
409  return String("DropTable ") + m_params.name();
410 }
411 
std::set< String > StringSet
STL Set managing Strings.
Definition: StringExt.h:42
#define HT_THROW2F(_code_, _ex_, _fmt_,...)
Definition: Error.h:494
char * decode_vstr(const uint8_t **bufp, size_t *remainp)
Decode a vstr (vint64, data, null).
#define HT_WARNF(msg,...)
Definition: Logger.h:290
The FailureInducer simulates errors.
ContextPtr m_context
Pointer to Master context.
Definition: Operation.h:553
static String filename
Definition: Config.cc:48
TableParts m_parts
Specification for which parts of table to drop.
std::string String
A String is simply a typedef to std::string.
Definition: String.h:44
Declarations for OperationDropTable.
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
bool validate_subops()
Handles the results of sub operations.
Definition: Operation.cc:512
virtual size_t encoded_length() const
Returns serialized object length.
Definition: Serializable.cc:37
int64_t id
Unique ID of entity.
std::mutex m_mutex
Mutex for serializing access to members
OperationDropTable(ContextPtr &context, const String &name, bool if_exists, TableParts parts)
Constructor.
const String label() override
Returns descriptive label for operation.
std::shared_ptr< Event > EventPtr
Smart pointer to Event.
Definition: Event.h:228
STL namespace.
StringSet m_servers
Set of participating range servers.
EntityHeader header
Entity header
size_t encoded_length_vstr(size_t len)
Computes the encoded length of vstr (vint64, data, null)
const char * get_text(int32_t state)
Definition: Operation.cc:609
StringSet m_completed
Range servers for which drop table operation has completed successfuly
Represents a set of table parts (sub-tables).
Definition: TableParts.h:47
const string & name() const
Gets name of table to drop.
Definition: DropTable.h:63
void encode_state(uint8_t **bufp) const override
Writes serialized encoding of object state.
void display_state(std::ostream &os) override
Writes human readable representation of object to output stream.
uint32_t decode_i32(const uint8_t **bufp, size_t *remainp)
Decode a 32-bit integer in little-endian order.
Declarations for ReferenceManager.
std::shared_ptr< Context > ContextPtr
Smart pointer to Context.
Definition: Context.h:265
Hyperspace definitions
Request parameters for drop table operation.
Definition: DropTable.h:46
virtual void encode(uint8_t **bufp) const
Writes serialized representation of object to a buffer.
Definition: Serializable.cc:64
void set_state(int32_t state)
Definition: Operation.h:473
bool decode_bool(const uint8_t **bufp, size_t *remainp)
Decodes a boolean value from the given buffer.
Definition: Serialization.h:96
const char * get_text(int error)
Returns a descriptive error message.
Definition: Error.cc:330
const char * INIT
Definition: Operation.cc:45
void encode_i32(uint8_t **bufp, uint32_t val)
Encode a 32-bit integer in little-endian order.
Compatibility Macros for C/C++.
void stage_subop(std::shared_ptr< Operation > operation)
Stages a sub operation for execution.
Definition: Operation.cc:536
Lib::Master::Request::Parameters::DropTable m_params
Request parmaeters.
void execute() override
Carries out the drop table operation.
Functions to serialize/deserialize primitives to/from a memory buffer.
void record_state()
Records operation state to the MML.
Definition: Operation.h:401
static String basename(String name, char separator= '/')
A posix-compliant basename() which strips directory names from a filename.
Definition: Filesystem.cc:154
const char * METADATA
Definition: Operation.cc:48
virtual void decode(const uint8_t **bufp, size_t *remainp)
Reads serialized representation of object from a buffer.
Definition: Serializable.cc:70
bool primary() const
Test if primary table is included in set.
Definition: TableParts.h:70
void decode_state(uint8_t version, const uint8_t **bufp, size_t *remainp) override
Decodes state from serialized object.
void lock()
Locks the entity's mutex.
Definition: MetaLogEntity.h:97
void encode_vstr(uint8_t **bufp, const void *buf, size_t len)
Encode a buffer as variable length string (vint64, data, null)
Hypertable definitions
#define HT_FATALF(msg,...)
Definition: Logger.h:343
long long int Lld
Shortcut for printf formats.
Definition: String.h:53
Declarations for general-purpose utility functions.
DependencySet m_dependencies
Set of dependencies.
Definition: Operation.h:595
#define HT_INFOF(msg,...)
Definition: Logger.h:272
bool value_index() const
Test if value index is included in set.
Definition: TableParts.h:75
void get_table_server_set(ContextPtr &context, const String &id, const String &row, StringSet &servers)
Gets set of servers holding ranges for a given table.
Definition: Utility.cc:57
Abstract base class for master operations.
Definition: Operation.h:124
This is a generic exception class for Hypertable.
Definition: Error.h:314
void decode_state_old(uint8_t version, const uint8_t **bufp, size_t *remainp) override
size_t encoded_length_state() const override
Returns serialized state length.
const String name() override
Returns name of operation ("OperationDropTable")
uint8_t encoding_version_state() const override
Returns version of encoding format of state.
const std::string to_string() const
Returns human readable string describing table parts.
Definition: TableParts.cc:63
static String dirname(String name, char separator= '/')
A posix-compliant dirname() which strips the last component from a file name.
Definition: Filesystem.cc:127
DependencySet m_exclusivities
Set of exclusivities.
Definition: Operation.h:592
#define HT_MAYBE_FAIL(_label_)
void complete_ok(std::vector< MetaLog::EntityPtr > &additional)
Definition: Operation.cc:436
uint8_t decode_byte(const uint8_t **bufp, size_t *remainp)
Decodes a single byte from the given buffer.
Definition: Serialization.h:73
Error codes, Exception handling, error logging.
void complete_error(int error, const String &msg, std::vector< MetaLog::EntityPtr > &additional)
Completes operation with error.
Definition: Operation.cc:400
std::shared_ptr< DispatchHandlerOperation > DispatchHandlerOperationPtr
Smart pointer to DispatchHandlerOperation.
int code() const
Returns the error code.
Definition: Error.h:391
Executes user-defined functions when leaving the current scope.
bool qualifier_index() const
Test if qualifier index is included in set.
Definition: TableParts.h:80