Example #1
0
bool Compatible::isdup(const Row& row) {
	if (disjoint != "")
		return false;

	// test if row is in source2
	if (nil(hdr1)) {
		hdr1 = source->header();
		hdr2 = source2->header();
	}
	Record key = row_to_key(hdr1, row, ki);
	source2->select(ki, key);
	Row row2 = source2->get(NEXT);
	if (row2 == Eof)
		return false;
	return equal(row, row2);
}
Example #2
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;
		}
	}