Mmoffset HistoryTable::next() { Commit* commit = 0; if (rewound) iter = theDB()->mmf->begin(); else commit = (Commit*) *iter; rewound = false; const Mmfile::iterator end = theDB()->mmf->end(); while (iter != end) { if (commit) { if (id + 1 < commit->ndeletes) return commit->deletes()[++id].unpack(); id = commit->ndeletes; if (ic + 1 < commit->ncreates) return commit->creates()[++ic].unpack(); ic = commit->ncreates; } do if (++iter == end) { rewind(); return 0; } while (iter.type() != MM_COMMIT); commit = (Commit*) *iter; id = ic = -1; } rewind(); return 0; }
static void load_data_record(Istream& fin, const gcstring& table, int tran, int n) { try { if (n > loadbuf_size) { loadbuf_size = max(n, 2 * loadbuf_size); mem_release(loadbuf); loadbuf = (char*) mem_committed(loadbuf_size); verify(loadbuf); } fin.read(loadbuf, n); Record rec(loadbuf); if (rec.cursize() != n) except_err(table << ": rec size " << rec.cursize() << " not what was read " << n); if (table == "views") theDB()->add_any_record(tran, table, rec); else theDB()->add_record(tran, table, rec); } catch (const Except& e) { errlog("load: skipping corrupted record in: ", table.str(), e.str()); alert("skipping corrupted record in: " << table << ": " << e); alerts = true; } }
Mmoffset HistoryTable::prev() { Commit* commit = 0; if (rewound) iter = theDB()->mmf->end(); else commit = (Commit*) *iter; rewound = false; const Mmfile::iterator begin = theDB()->mmf->begin(); while (iter != begin) { if (commit) { if (ic > 0) return commit->creates()[--ic].unpack(); ic = -1; if (id > 0) return commit->deletes()[--id].unpack(); id = -1; } do if (--iter == begin) { rewind(); return 0; } while (iter.type() != MM_COMMIT); commit = (Commit*) *iter; id = commit->ndeletes; ic = commit->ncreates; } rewind(); return 0; }
static int load1(Istream& fin, gcstring tblspec) { int n = tblspec.find(' ', 7); gcstring table = tblspec.substr(7, n - 7); if (table != "views") { if (theDB()->istable(table)) theDB()->remove_table(table); database_admin(tblspec.str()); } return load_data(fin, table); }
~Loading() { theDB()->loading = false; mem_release(loadbuf); loadbuf = 0; loadbuf_size = 0; }
Loading() { theDB()->loading = true; loadbuf_size = 100000; loadbuf = (char*) mem_committed(loadbuf_size); verify(loadbuf); }
void CAVolumeCurve::AddRange(SInt32 inMinRaw, SInt32 inMaxRaw, Float64 inMinDB, Float64 inMaxDB) { CARawPoint theRaw(inMinRaw, inMaxRaw); CADBPoint theDB(inMinDB, inMaxDB); bool isOverlapped = false; bool isDone = false; CurveMap::iterator theIterator = mCurveMap.begin(); while((theIterator != mCurveMap.end()) && !isOverlapped && !isDone) { isOverlapped = CARawPoint::Overlap(theRaw, theIterator->first); isDone = theRaw >= theIterator->first; if(!isOverlapped && !isDone) { std::advance(theIterator, 1); } } if(!isOverlapped) { mCurveMap.insert(CurveMap::value_type(theRaw, theDB)); } else { DebugMessage("CAVolumeCurve::AddRange: new point overlaps"); } }
Row HistoryTable::get(Dir dir) { void* p; Mmoffset offset; do { offset = dir == NEXT ? next() : prev(); if (offset == 0) return Eof; p = theDB()->mmf->adr(offset - sizeof(int)); } while (*(int*) p != tblnum); Record r1; Commit* commit = (Commit*) *iter; r1.addval(SuDate::parse(ctime(&commit->t))); r1.addval(dir == NEXT ? 0 <= ic && ic < commit->ncreates ? "create" : "delete" : 0 <= id && id < commit->ndeletes ? "delete" : "create"); Record r2(theDB()->mmf, offset); static Record emptyrec; return Row(lisp(emptyrec, r1, emptyrec, r2)); }
static int load_data(Istream& fin, const gcstring& table) { int nrecs = 0; int tran = theDB()->transaction(READWRITE); for (;; ++nrecs) { int n; fin.read((char*) &n, sizeof n); if (fin.gcount() != sizeof n) except("unexpected eof"); if (n == 0) break ; load_data_record(fin, table, tran, n); if (nrecs % recsPerTran == recsPerTran - 1) { verify(theDB()->commit(tran)); tran = theDB()->transaction(READWRITE); } } verify(theDB()->commit(tran)); return nrecs; }
TranCloser::~TranCloser() { theDB()->abort(t); }
Row Project::get(Dir dir) { static Record emptyrec; if (first) { first = false; src_hdr = source->header(); proj_hdr = src_hdr.project(flds); if (strategy == LOOKUP) { if (idx) idx->free(); idx = new VVtree(td = new TempDest); indexed = false; } } if (strategy == COPY) { return source->get(dir); } else if (strategy == SEQUENTIAL) { if (dir == NEXT) { // output the first of each group // i.e. skip over rows the same as previous output Row row; do if (Eof == (row = source->get(NEXT))) return Eof; while (! rewound && equal(proj_hdr, row, currow)); rewound = false; prevrow = currow; currow = row; // output the first row of a new group return Row(lisp(emptyrec, row_to_key(src_hdr, row, flds))); } else // dir == PREV { // output the last of each group // i.e. output when *next* record is different // (to get the same records as NEXT) if (rewound) prevrow = source->get(PREV); rewound = false; Row row; do { if (Eof == (row = prevrow)) return Eof; prevrow = source->get(PREV); } while (equal(proj_hdr, row, prevrow)); // output the last row of a group currow = row; return Row(lisp(emptyrec, row_to_key(src_hdr, row, flds))); } } else { verify(strategy == LOOKUP); if (rewound) { rewound = false; if (dir == PREV && ! indexed) { // pre-build the index Row row; while (Eof != (row = source->get(NEXT))) { Record key = row_to_key(src_hdr, row, flds); Vdata data(row.data); for (Lisp<Record> rs = row.data; ! nil(rs); ++rs) td->addref(rs->ptr()); // insert will only succeed on first of dups idx->insert(VVslot(key, &data)); } source->rewind(); indexed = true; } } Row row; while (Eof != (row = source->get(dir))) { Record key = row_to_key(src_hdr, row, flds); VVtree::iterator iter = idx->find(key); if (iter == idx->end()) { for (Lisp<Record> rs = row.data; ! nil(rs); ++rs) td->addref(rs->ptr()); Vdata data(row.data); verify(idx->insert(VVslot(key, &data))); return Row(lisp(emptyrec, key)); } else { Vdata* d = iter->data; Records rs; for (int i = d->n - 1; i >= 0; --i) rs.push(Record::from_int(d->r[i], theDB()->mmf)); Row irow(rs); if (row == irow) return Row(lisp(emptyrec, key)); } } if (dir == NEXT) indexed = true; return Eof; } }
Header HistoryTable::header() { return Header(lisp(Fields(), lisp(gcstring("_date"), gcstring("_action")), Fields(), theDB()->get_fields(table)), columns()); }
Fields HistoryTable::columns() { Fields flds = theDB()->get_columns(table); flds.push("_action"); flds.push("_date"); return flds; }
HistoryTable::HistoryTable(const gcstring& t) : table(t), tblnum(theDB()->ck_get_table(t)->num) { }