Esempio n. 1
0
void Rvm::DestroySegment(std::string segname) {
  // Search for a segment with the given name
  std::unordered_map<std::string, RvmSegment*>::iterator segment = name_to_segment_map_.find(segname);
  if (segment == name_to_segment_map_.end()) {
    // Create a one-off transaction that indicates the segment was destroyed
    trans_t tid = get_next_transaction_id();
    // Write to redo log that the segment was destroyed
    RedoRecord* record = new RedoRecord(RedoRecord::DESTROY_SEGMENT, segname);
    std::list<RedoRecord*> records;
    records.push_back(record);
    RvmTransaction* rvm_trans = new RvmTransaction(tid, this, records);
    CommitTransaction(rvm_trans); // Commit the transaction

    std::string segpath = construct_segment_path(segname);
    if (file_exists(segpath)) {
      // Delete the file if it exists
      if (remove(segpath.c_str()) != 0) {
#if DEBUG
        std::cerr << "Rvm::DestroySegment(): Error deleting file" << std::endl;
#endif
      }
    }
  } else {
#if DEBUG
    std::cout << "Rvm::DestroySegment(): Segment " << segname << " already mapped." << std::endl;
#endif
    // Trying to destroy a segment that is currently mapped
    return;
  }
}
Esempio n. 2
0
trans_t Rvm::BeginTransaction(int numsegs, void** segbases) {
  // Check to see that input segment bases are valid
  for (int i = 0; i < numsegs; i++) {
    std::unordered_map<void*, RvmSegment*>::iterator iterator = base_to_segment_map_.find(segbases[i]);
    // Make sure segment exists
    if (iterator != base_to_segment_map_.end()) {
      RvmSegment* rvm_segment = iterator->second;
      // Check if segment is already owned by another transaction
      if (rvm_segment->has_owner()) {
#if DEBUG
        std::cerr << "Rvm::BeginTransaction(): Segment " << rvm_segment->get_name() << " being modified by another transaction" << std::endl;
#endif
        return (trans_t)-1;
      }
    } else {
#if DEBUG
      std::cerr << "Rvm::BeginTransaction(): Segment " << segbases[i] << " does not exist" << std::endl;
#endif
      return (trans_t)-1;
    }
  }

  // Create the transaction
  trans_t tid = get_next_transaction_id();
  RvmTransaction* rvm_trans = new RvmTransaction(tid, this);
  g_trans_map[tid] = rvm_trans;
  for (int i = 0; i < numsegs; i++) {
    RvmSegment* rvm_segment = base_to_segment_map_[segbases[i]];
    rvm_trans->AddSegment(rvm_segment);
  }
  return tid;
}
Esempio n. 3
0
void Rvm::TruncateLog() {
  std::unordered_map<std::string, std::list<RedoRecord*>> commit_map;

  std::list<RedoRecord*> unbacked_records;
  for (RvmTransaction* rvm_trans : committed_transactions_) {
    // Loop through logs and separate based on which backing file
    // the logs apply to
    for (RedoRecord* record : rvm_trans->get_redo_records()) {
      if (record->get_type() == RedoRecord::RecordType::DESTROY_SEGMENT) {
        // If it is a delete record, then clear current list
        commit_map[record->get_segment_name()].clear();
      } else {
        // Regular record, so push back to commit list
        commit_map[record->get_segment_name()].push_back(record);
      }
    }
    // Clear the list of redo records
    rvm_trans->clear_redo_records();
    delete rvm_trans;
  }
  committed_transactions_.clear();

  // Loop through map and commit logs to backing file
  for (auto& pair : commit_map) {
    if (!pair.second.empty()) {
      bool success = ApplyRecordsToBackingFile(pair.first, pair.second);
      if (!success) {
        // Logs not successfully applied, so save them
        for (RedoRecord* record : pair.second) {
          unbacked_records.push_back(record);
        }
      } else {
        // Successfully applied records, so delete them
        for (RedoRecord* record : pair.second) {
          delete record;
        }
      }
    }
  }

  std::ofstream::openmode flags = std::ofstream::out | std::ofstream::binary | std::ofstream::trunc;
  std::ofstream log_file(tmp_log_path_, flags);
  if (!unbacked_records.empty()) {
    RvmTransaction* rvm_trans = new RvmTransaction(get_next_transaction_id(), this, unbacked_records);
    WriteTransactionToLog(log_file, rvm_trans);
    log_file.flush();
    committed_transactions_.push_back(rvm_trans);
  }

  // Make the temporary log file as the new log file
  std::remove(log_path_.c_str());
  std::rename(tmp_log_path_.c_str(), log_path_.c_str());
}
Esempio n. 4
0
void init_isns_hdr(struct isns_hdr *hdr, int function_id, int replace)
{
	hdr->isnsp_version = htons((u16)ISNSP_VERSION);
	hdr->function_id = htons((u16)function_id);
	hdr->pdu_length = 0;
	hdr->flags = 0;
	/* always use one PDU for one command we send */
	set_bit_first_pdu(hdr->flags);
	set_bit_last_pdu(hdr->flags);
	set_bit_sender_client(hdr->flags);
	if (replace)
		set_bit_replace(hdr->flags);
	hdr->flags = htons((u16)hdr->flags);
	get_next_transaction_id(&hdr->transaction_id);
	hdr->transaction_id = htons((u16)hdr->transaction_id);
	hdr->sequence_id = 0;
}