Example #1
0
/* Read a page from the write-ahead log, if it is present. */
int sqlite3WalFindFrame(Wal *pWal, Pgno pgno, u32 *piRead)
{
	// db_thread * const thread = enif_tsd_get(g_tsd_thread);
	#if ATOMIC
	db_thread *thread = g_tsd_thread;
	#else
	db_thread* thread = enif_tsd_get(g_tsd_thread);
	#endif
	/*if (thr->isreadonly)
	{
		u64 readSafeEvnum, readSafeTerm;
		#ifndef _TESTAPP_
		enif_mutex_lock(pWal->mtx);
		#endif
		readSafeEvnum = pWal->rthread->readSafeEvnum;
		readSafeTerm = pWal->rthread->readSafeTerm;
		#ifndef _TESTAPP_
		enif_mutex_unlock(pWal->mtx);
		#endif

		return findframe(pWal->rthread, pWal, pgno, piRead, readSafeTerm, readSafeEvnum, NULL, NULL);
	}
	else*/ if (pWal->inProgressTerm > 0 || pWal->inProgressEvnum > 0)
		return findframe(thread, pWal, pgno, piRead, pWal->inProgressTerm, 
			pWal->inProgressEvnum, NULL, NULL);
	else
		return findframe(thread, pWal, pgno, piRead, pWal->lastCompleteTerm, 
			pWal->lastCompleteEvnum, NULL, NULL);
}
Example #2
0
int
main(int argc, char *argv[]) {
	char *s;

	fmtinstall('r', errfmt);
extern int fmtevent(Fmt*);
	fmtinstall('E', fmtevent);

	ARGBEGIN{
	default:
		usage();
	}ARGEND;

	s = EARGF(usage());
	if(!getulong(s, &win.xid))
		usage();

	if(argc)
		usage();

	setlocale(LC_CTYPE, "");

	initdisplay();

	frame = findframe(&win);
	getwinsize(&frame);
	restrut();
	sethandler(&frame, &handlers);
	selectinput(&frame, StructureNotifyMask);

	running = true;
	xevent_loop();

	XCloseDisplay(display);
	return 0;
}
Example #3
0
// return number of bytes written
static int wal_iterate(Wal *pWal, iterate_resource *iter, u8 *buf, int bufsize, u8 *hdr, u32 *done)
{
	// db_thread* const thr = enif_tsd_get(g_tsd_thread);
	#if ATOMIC
	db_thread *thr 		 = g_tsd_thread;
	#else
	db_thread* thr = enif_tsd_get(g_tsd_thread);
	#endif
	mdbinf* const mdb 	 = &thr->mdb;
	u32 mxPage;
	u64 readSafeEvnum, readSafeTerm;
	
	#ifndef _TESTAPP_
	enif_mutex_lock(pWal->mtx);
	#endif
	readSafeEvnum = pWal->lastCompleteEvnum;
	readSafeTerm = pWal->lastCompleteTerm;
	mxPage = pWal->mxPage;
	#ifndef _TESTAPP_
	enif_mutex_unlock(pWal->mtx);
	#endif

	if (!iter->started)
	{
		if (iter->evnum + iter->evterm == 0)
		{
			// If any writes come after iterator started, we must ignore those pages.
			iter->evnum = readSafeEvnum;
			iter->evterm = readSafeTerm;
			iter->pgnoPos = 1;
			iter->entiredb = 1;
			iter->mxPage = mxPage;
			if (pWal->mxPage == 0)
			{
				DBG("ERROR: Iterate on empty DB %llu",pWal->lastCompleteEvnum);
				*done = 1;
				return 0;
			}
		}
		else
		{
			// set mxPage to highest pgno we find.
			iter->pgnoPos = iter->mxPage = 0;
			DBG("Iterate rsterm=%llu rsevnum=%llu",readSafeTerm,readSafeEvnum);
		}
		iter->started = 1;
	}

	// send entire db (without history)
	if (iter->entiredb)
	{
		u32 iRead = 0;
		findframe(thr, pWal, iter->pgnoPos, &iRead, iter->evterm, iter->evnum, NULL, NULL);

		if (!iRead)
		{
			DBG("Iterate did not find page");
			*done = iter->mxPage;
			return 0;
		}
		DBG("Iter pos=%u, mx=%u, safemx=%u",iter->pgnoPos, iter->mxPage, mxPage);
		if (iter->pgnoPos == iter->mxPage)
			*done = iter->mxPage;
		put8byte(hdr,                           iter->evterm);
		put8byte(hdr+sizeof(u64),               iter->evnum);
		put4byte(hdr+sizeof(u64)*2,             iter->pgnoPos);
		put4byte(hdr+sizeof(u64)*2+sizeof(u32), *done);
		iter->pgnoPos++;
		return fillbuff(thr, pWal, iter, buf, bufsize);
	}
	else
	{
		MDB_val logKey, logVal;
		int logop;
		u8 logKeyBuf[sizeof(u64)*3];
		int rc;
		// ** - Log DB: {<<ActorIndex:64, Evterm:64, Evnum:64>>, <<Pgno:32/unsigned>>}

		memcpy(logKeyBuf,                 &pWal->index,  sizeof(u64));
		memcpy(logKeyBuf + sizeof(u64),   &iter->evterm, sizeof(u64));
		memcpy(logKeyBuf + sizeof(u64)*2, &iter->evnum, sizeof(u64));
		logKey.mv_data = logKeyBuf;
		logKey.mv_size = sizeof(logKeyBuf);
		DBG("iterate looking for, matchterm=%llu matchevnum=%llu",iter->evterm,iter->evnum);
		if (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_SET) != MDB_SUCCESS)
		{
			// Evterm/evnum combination not found. Check if evnum is there.
			// If so return evterm. It will mean a node is in conflict.
			DBG("Key not found in log");
			if (readSafeEvnum == iter->evnum)
			{
				iter->evterm = readSafeTerm;
				iter->termMismatch = 1;
			}
			else
			{
				memcpy(logKeyBuf,                 &pWal->index,  sizeof(u64));
				memcpy(logKeyBuf + sizeof(u64),   &readSafeTerm, sizeof(u64));
				memcpy(logKeyBuf + sizeof(u64)*2, &readSafeEvnum,sizeof(u64));
				if (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_SET) != MDB_SUCCESS)
				{
					DBG("Key not found in log for undo");
					*done = 1;
					return 0;
				}
				while (mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,MDB_PREV_NODUP) == MDB_SUCCESS)
				{
					u64 aindex, term, evnum;

					mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT);
					memcpy(&aindex, logKey.mv_data,              sizeof(u64));
					memcpy(&term,   (u8*)logKey.mv_data+sizeof(u64),  sizeof(u64));
					memcpy(&evnum,  (u8*)logKey.mv_data+sizeof(u64)*2,sizeof(u64));

					DBG("Iterate on term=%llu, evnum=%llu, looking for=%llu",term,evnum,iter->evnum);

					if (aindex != pWal->index)
						break;
					if (iter->evnum == evnum)
					{
						iter->evterm = term;
						iter->termMismatch = 1;
						break;
					}
				}
			}

			*done = 1;
			return 0;
		}

		// We start iterate from next evnum not current. Input evterm/evnum is match_index and match_term.
		// It needs next.
		if (iter->started == 1 &&
			(rc = mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_NEXT_NODUP)) != MDB_SUCCESS)
		{
			*done = 1;
			return 0;
		}
		else
		{
			u64 aindex;

			rc = mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT);
			if (rc != MDB_SUCCESS)
			{
				*done = 1;
				return 0;
			}
			memcpy(&aindex,       (u8*)logKey.mv_data,              sizeof(u64));
			memcpy(&iter->evterm, (u8*)logKey.mv_data+sizeof(u64),  sizeof(u64));
			memcpy(&iter->evnum,  (u8*)logKey.mv_data+sizeof(u64)*2,sizeof(u64));
			if (aindex != pWal->index)
			{
				*done = 1;
				return 0;
			}
			// To keep from moving iter->evterm/iter->evnum forward more than once.
			iter->started = 2;
		}

		logop = MDB_FIRST_DUP;
		while ((rc = mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,logop)) == MDB_SUCCESS)
		{
			u64 evnum,evterm;
			u32 pgno;
			u32 iRead;

			logop = MDB_NEXT_DUP;

			mdb_cursor_get(mdb->cursorLog,&logKey, &logVal, MDB_GET_CURRENT);
			memcpy(&pgno,logVal.mv_data,sizeof(u32));

			DBG("iterate at pgno=%u, pgnopos=%u",pgno,iter->pgnoPos);

			if (pgno <= iter->pgnoPos)
				continue;

			findframe(thr, pWal, pgno, &iRead, iter->evterm, iter->evnum, &evterm, &evnum);

			if (iRead == 0)
			{
				DBG("ERROR: Did not find frame for pgno=%u, evterm=%llu, evnum=%llu",
					pgno, iter->evterm, iter->evnum);
				*done = 1;
				return 0;
			}

			if (evterm != iter->evterm || evnum != iter->evnum)
			{
				DBG("ERROR: Evterm/evnum does not match,looking for: evterm=%llu, evnum=%llu, "
				"got: evterm=%llu, evnum=%llu", iter->evterm, iter->evnum, evterm, evnum);
				*done = 1;
				return 0;
			}

			iter->pgnoPos = pgno;
			if ((rc = mdb_cursor_get(mdb->cursorLog,&logKey,&logVal,logop)) == MDB_SUCCESS)
				*done = 0;
			else
				*done = iter->pgnoPos;
			DBG( "logcursor get next %d, done=%u",rc,*done);
			put8byte(hdr,                           iter->evterm);
			put8byte(hdr+sizeof(u64),               iter->evnum);
			put4byte(hdr+sizeof(u64)*2,             iter->pgnoPos);
			put4byte(hdr+sizeof(u64)*2+sizeof(u32), *done);
			return fillbuff(thr, pWal, iter, buf, bufsize);
		}
		*done = 1;
		return 0;
	}
}