Beispiel #1
0
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));
}
Beispiel #2
0
 // FIXME: Made non-ref in the hope that it would work better.
 void lp(ASTNode node)
 {
   cout << lisp(node) << endl;
 }
Beispiel #3
0
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;
		}
	}
Beispiel #4
0
Header Project::header()
	{
	return strategy == COPY
		? source->header().project(flds)
		: Header(lisp(Fields(), flds), flds);
	}
Beispiel #5
0
Header HistoryTable::header() {
	return Header(lisp(Fields(), lisp(gcstring("_date"), gcstring("_action")),
					  Fields(), theDB()->get_fields(table)),
		columns());
}
Beispiel #6
0
Indexes HistoryTable::keys() {
	return lisp(lisp(gcstring("_date")));
}