void mark(hvec z) {hvec q,r; int bit=1; q=z/2; r=z%2; if (r==hvec(1,1)) bit=2; if (r==hvec(1,0)) bit=3; if (r==hvec(0,-1)) bit=4; hbits[q]|=1<<bit; }
bool ismarked(hvec z) {hvec q,r; int bit=1; q=z/2; r=z%2; if (r==hvec(1,1)) bit=2; if (r==hvec(1,0)) bit=3; if (r==hvec(0,-1)) bit=4; return (hbits[q]>>bit)&1; }
w_rc_t ShoreTPCCEnv::_post_init_impl() { #ifndef CFG_HACK return (RCOK); #endif TRACE (TRACE_ALWAYS, "Padding WAREHOUSES"); ss_m* db = this->db(); // lock the WH table warehouse_t* wh = warehouse_desc(); index_desc_t* idx = wh->indexes(); int icount = wh->index_count(); stid_t wh_fid = wh->fid(); // lock the table and index(es) for exclusive access W_DO(db->lock(wh_fid, EX)); for(int i=0; i < icount; i++) { for(int j=0; j < idx[i].get_partition_count(); j++) W_DO(db->lock(idx[i].fid(j), EX)); } guard<ats_char_t> pts = new ats_char_t(wh->maxsize()); /* copy and pad all tuples smaller than 4k WARNING: this code assumes that existing tuples are packed densly so that all padded tuples are added after the last unpadded one */ bool eof; static int const PADDED_SIZE = 4096; // we know you can't fit two 4k records on a single page array_guard_t<char> padding = new char[PADDED_SIZE]; std::vector<rid_t> hit_list; { guard<warehouse_man_impl::table_iter> iter; { warehouse_man_impl::table_iter* tmp; W_DO(warehouse_man()->get_iter_for_file_scan(db, tmp)); iter = tmp; } int count = 0; table_row_t row(wh); rep_row_t arep(pts); int psize = wh->maxsize()+1; W_DO(iter->next(db, eof, row)); while (1) { pin_i* handle = iter->cursor(); if (!handle) { TRACE(TRACE_ALWAYS, " -> Reached EOF. Search complete (%d)\n", count); break; } // figure out how big the old record is int hsize = handle->hdr_size(); int bsize = handle->body_size(); if (bsize == psize) { TRACE(TRACE_ALWAYS, " -> Found padded WH record. Stopping search (%d)\n", count); break; } else if (bsize > psize) { // too big... shrink it down to save on logging handle->truncate_rec(bsize - psize); fprintf(stderr, "+"); } else { // copy and pad the record (and mark the old one for deletion) rid_t new_rid; vec_t hvec(handle->hdr(), hsize); vec_t dvec(handle->body(), bsize); vec_t pvec(padding, PADDED_SIZE-bsize); W_DO(db->create_rec(wh_fid, hvec, PADDED_SIZE, dvec, new_rid)); W_DO(db->append_rec(new_rid, pvec)); // for small databases, first padded record fits on this page if (not handle->up_to_date()) handle->repin(); // mark the old record for deletion hit_list.push_back(handle->rid()); // update the index(es) vec_t rvec(&row._rid, sizeof(rid_t)); vec_t nrvec(&new_rid, sizeof(new_rid)); for(int i=0; i < icount; i++) { int key_sz = warehouse_man()->format_key(idx+i, &row, arep); vec_t kvec(arep._dest, key_sz); /* destroy the old mapping and replace it with the new one. If it turns out this is super-slow, we can look into probing the index with a cursor and updating it directly. */ int pnum = _pwarehouse_man->get_pnum(&idx[i], &row); stid_t fid = idx[i].fid(pnum); if(idx[i].is_mr()) { W_DO(db->destroy_mr_assoc(fid, kvec, rvec)); // now put the entry back with the new rid el_filler ef; ef._el.put(nrvec); W_DO(db->create_mr_assoc(fid, kvec, ef)); } else { W_DO(db->destroy_assoc(fid, kvec, rvec)); // now put the entry back with the new rid W_DO(db->create_assoc(fid, kvec, nrvec)); } } fprintf(stderr, "."); } // next! count++; W_DO(iter->next(db, eof, row)); } fprintf(stderr, "\n"); // put the iter out of scope } // delete the old records int hlsize = hit_list.size(); TRACE(TRACE_ALWAYS, "-> Deleting (%d) old unpadded records\n", hlsize); for(int i=0; i < hlsize; i++) { W_DO(db->destroy_rec(hit_list[i])); } return (RCOK); }
w_rc_t ShoreTPCBEnv::_pad_BRANCHES() { ss_m* db = this->db(); // lock the BRANCHES table branch_t* br = branch_man->table(); std::vector<index_desc_t*>& br_idx = br->get_indexes(); // lock the table and index(es) for exclusive access W_DO(ss_m::lm->intent_vol_lock(br->primary_idx()->stid().vol, okvl_mode::IX)); W_DO(ss_m::lm->intent_store_lock(br->primary_idx()->stid(), okvl_mode::X)); for(size_t i=0; i < br_idx.size(); i++) { W_DO(ss_m::lm->intent_store_lock(br_idx[i]->stid(), okvl_mode::X)); } guard<ats_char_t> pts = new ats_char_t(br->maxsize()); // copy and pad all tuples smaller than 4k // WARNING: this code assumes that existing tuples are packed // densly so that all padded tuples are added after the last // unpadded one bool eof; // we know you can't fit two 4k records on a single page static int const PADDED_SIZE = 4096; array_guard_t<char> padding = new char[PADDED_SIZE]; std::vector<rid_t> hit_list; { table_scan_iter_impl<branch_t>* iter = new table_scan_iter_impl<branch_t>(branch_man->table()); int count = 0; table_row_t row(br); rep_row_t arep(pts); int psize = br->maxsize()+1; W_DO(iter->next(db, eof, row)); while (!eof) { // figure out how big the old record is int bsize = row.size(); if (bsize == psize) { TRACE(TRACE_ALWAYS, "-> Found padded BRANCH record. Stopping search (%d)\n", count); break; } else if (bsize > psize) { // too big... shrink it down to save on logging // handle->truncate_rec(bsize - psize); fprintf(stderr, "+"); // CS: no more pin_i -> do nothing } else { // copy and pad the record (and mark the old one for deletion) rid_t new_rid; vec_t hvec(handle->hdr(), hsize); vec_t dvec(handle->body(), bsize); vec_t pvec(padding, PADDED_SIZE-bsize); W_DO(db->create_rec(br_fid, hvec, PADDED_SIZE, dvec, new_rid)); W_DO(db->append_rec(new_rid, pvec)); // mark the old record for deletion hit_list.push_back(handle->rid()); // update the index(es) vec_t rvec(&row._rid, sizeof(rid_t)); vec_t nrvec(&new_rid, sizeof(new_rid)); for(int i=0; i < br_idx_count; i++) { int key_sz = branch_man()->format_key(br_idx+i, &row, arep); vec_t kvec(arep._dest, key_sz); // destroy the old mapping and replace it with the new // one. If it turns out this is super-slow, we can // look into probing the index with a cursor and // updating it directly. int pnum = _pbranch_man->get_pnum(&br_idx[i], &row); stid_t fid = br_idx[i].fid(pnum); W_DO(db->destroy_assoc(fid, kvec, rvec)); // now put the entry back with the new rid W_DO(db->create_assoc(fid, kvec, nrvec)); } fprintf(stderr, "."); } // next! count++; W_DO(iter->next(db, eof, row)); } TRACE(TRACE_ALWAYS, "padded records added\n"); delete iter; } // delete the old records int hlsize = hit_list.size(); TRACE(TRACE_ALWAYS, "-> Deleting (%d) old BRANCH unpadded records\n", hlsize); for(int i=0; i < hlsize; i++) { W_DO(db->destroy_rec(hit_list[i])); } return (RCOK); }