// Copy this into a new CubitSimpleAttrib CubitSimpleAttrib FacetAttrib::get_CSA() const { // Set initial list size std::vector<CubitString> string_list(numStrings); std::vector<int> int_list(numIntegers); std::vector<double> double_list(numDoubles); // Don't need to 'new' objects in DLIList because // CSA will make copies. Just put addresses in list. int i; for( i = 0; i < numStrings; i++ ) string_list[i] = stringArray[i]; for( i = 0; i < numIntegers; i++ ) int_list[i] = integerArray[i]; for( i = 0; i < numDoubles; i++ ) double_list[i] = doubleArray[i]; return CubitSimpleAttrib( &string_list, &double_list, &int_list ); }
void Row_mvcc::buffer_req(TsType type, txn_man * txn, bool served) { uint32_t access_num = 1; while (true) { for (uint32_t i = 0; i < _req_len; i++) { // TODO No need to keep all read history. // in some sense, only need to keep the served read request with the max ts. // if (!_requests[i].valid) { _requests[i].valid = true; _requests[i].type = type; _requests[i].ts = txn->get_ts(); _requests[i].txn = txn; _requests[i].time = get_sys_clock(); return; } } assert(access_num == 1); double_list(1); access_num ++; } }
row_t * Row_mvcc::reserveRow(ts_t ts, txn_man * txn) { assert(!_exists_prewrite); // Garbage Collection ts_t min_ts = glob_manager->get_min_ts(txn->get_thd_id()); if (_oldest_wts < min_ts && _num_versions == _his_len) { ts_t max_recycle_ts = 0; ts_t idx = _his_len; for (uint32_t i = 0; i < _his_len; i++) { if (_write_history[i].valid && _write_history[i].ts < min_ts && _write_history[i].ts > max_recycle_ts) { max_recycle_ts = _write_history[i].ts; idx = i; } } // some entries can be garbage collected. if (idx != _his_len) { row_t * temp = _row; _row = _write_history[idx].row; _write_history[idx].row = temp; _oldest_wts = max_recycle_ts; for (uint32_t i = 0; i < _his_len; i++) { if (_write_history[i].valid && _write_history[i].ts <= max_recycle_ts) { _write_history[i].valid = false; _write_history[i].reserved = false; assert(_write_history[i].row); _num_versions --; } } } } #if DEBUG_CC uint32_t his_size = 0; uint64_t max_ts = 0; for (uint32_t i = 0; i < _his_len; i++) if (_write_history[i].valid) { his_size ++; if (_write_history[i].ts > max_ts) max_ts = _write_history[i].ts; } assert(his_size == _num_versions); if (_num_versions > 0) assert(max_ts == _latest_wts); #endif uint32_t idx = _his_len; // _write_history is not full, find an unused entry for P_REQ. if (_num_versions < _his_len) { for (uint32_t i = 0; i < _his_len; i++) { if (!_write_history[i].valid && !_write_history[i].reserved && _write_history[i].row != NULL) { idx = i; break; } else if (!_write_history[i].valid && !_write_history[i].reserved) idx = i; } assert(idx < _his_len); } row_t * row; if (idx == _his_len) { if (_his_len >= g_thread_cnt) { // all entries are taken. recycle the oldest version if _his_len is too long already ts_t min_ts = UINT64_MAX; for (uint32_t i = 0; i < _his_len; i++) { if (_write_history[i].valid && _write_history[i].ts < min_ts) { min_ts = _write_history[i].ts; idx = i; } } assert(min_ts > _oldest_wts); assert(_write_history[idx].row); row = _row; _row = _write_history[idx].row; _write_history[idx].row = row; _oldest_wts = min_ts; _num_versions --; } else { // double the history size. double_list(0); _prewrite_ts = ts; #if DEBUG_CC for (uint32_t i = 0; i < _his_len / 2; i++) assert(_write_history[i].valid); assert(!_write_history[_his_len / 2].valid); #endif idx = _his_len / 2; } } assert(idx != _his_len); // some entries are not taken. But the row of that entry is NULL. if (!_write_history[idx].row) { _write_history[idx].row = (row_t *) _mm_malloc(sizeof(row_t), 64); _write_history[idx].row->init(MAX_TUPLE_SIZE); } _write_history[idx].valid = false; _write_history[idx].reserved = true; _write_history[idx].ts = ts; _exists_prewrite = true; _prewrite_his_id = idx; _prewrite_ts = ts; return _write_history[idx].row; }