Beispiel #1
0
MojErr MojService::CategoryHandler::invoke(const MojChar* method, MojServiceMessage* msg, MojObject& payload)
{
	MojAssert(method && msg);
	MojLogTrace(s_log);

	MojTime startTime;
	MojErr err = MojGetCurrentTime(startTime);
	MojErrCheck(err);

	// lookup callback
	CallbackInfo cb;
	if (!m_callbackMap.get(method, cb)) {
		MojErrThrow(MojErrMethodNotFound);
	}
	// validate schema
	if (cb.m_schema.get()) {
		MojSchema::Result res;
		err = cb.m_schema->validate(payload, res);
		MojErrCheck(err);
		if (!res.valid()) {
			MojErrThrowMsg(MojErrInvalidArg, _T("invalid parameters: caller='%s' error='%s'"), msg->senderName(), res.msg().data());
		}
	}
	// invoke method
	err = invoke(cb.m_callback, msg, payload);
	MojErrCheck(err);

	// log timing
	MojTime endTime;
	err = MojGetCurrentTime(endTime);
	MojErrCheck(err);
	MojLogInfo(s_log, _T("%s invoked: %.3fms"), method, (double) (endTime.microsecs() - startTime.microsecs()) / 1000);

	return MojErrNone;
}
Beispiel #2
0
MojErr MojDbPerfCreateTest::run()
{
	MojErr err = file.open(CreateTestFileName, MOJ_O_RDWR | MOJ_O_CREAT | MOJ_O_TRUNC, MOJ_S_IRUSR | MOJ_S_IWUSR);

	MojString buf;
	err = buf.format("MojoDb Create Performance Test,,,,,\n\nOperation,Kind,Total Time,Time Per Iteration,Time Per Object\n");
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	err = testCreate();
	MojTestErrCheck(err);

	err = MojPrintF("\n\n TOTAL TEST TIME: %llu microseconds\n\n", totalTestTime.microsecs());
	MojTestErrCheck(err);
	err = MojPrintF("\n-------\n");
	MojTestErrCheck(err);

	err = buf.format("\n\nTOTAL TEST TIME,,%llu,,,", totalTestTime.microsecs());
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	err = file.close();
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #3
0
MojErr MojDbIdGenerator::id(MojObject& idOut)
{
	// an id consists of  a timestamp (in microsecs) concatenated with a 32-bit random number.
	// The goal is to have a very low likelihood of id collision among multiple devices owned
	// by the same user (so they can can share an id-space) while still keeping them sequential
	// to minimize db fragmentation.

	MojThreadGuard guard(m_mutex);
	MojUInt32 randNum;
	MojErr err = MojRandom(&m_randBuf, &randNum);
	MojErrCheck(err);
	guard.unlock();

	MojTime time;
	err = MojGetCurrentTime(time);
	MojErrCheck(err);

	MojBuffer buf;
	MojDataWriter writer(buf);
	err = writer.writeInt64(time.microsecs());
	MojErrCheck(err);
	err = writer.writeUInt32(randNum);
	MojErrCheck(err);

	MojVector<MojByte> byteVec;
	err = buf.toByteVec(byteVec);
	MojErrCheck(err);
	MojString str;
	err = str.base64Encode(byteVec, false);
	MojErrCheck(err);
	idOut = str;

	return MojErrNone;
}
Beispiel #4
0
MojErr MojDbPerfUpdateTest::updateKind(MojDb& db, const MojChar* kindId, const MojChar* kindJson, const MojChar* extraIdxJson, MojErr (MojDbPerfTest::*createFn) (MojObject&, MojUInt64))
{
	// register all the kinds
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// put objects using createFn
	MojObject objs;
	err = putObjs(db, kindId, numObjectsBeforeUpdateKind, createFn, objs);
	MojTestErrCheck(err);

	// add an index
	MojObject kindObj;
	err = kindObj.fromJson(kindJson);
	MojTestErrCheck(err);
	MojObject indexes;
	kindObj.get(_T("indexes"), indexes);
	MojTestErrCheck(err);

	MojObject extraIdx;
	err = extraIdx.fromJson(extraIdxJson);
	MojTestErrCheck(err);
	indexes.push(extraIdx);

	err = kindObj.put(_T("indexes"), indexes);
	MojTestErrCheck(err);

	MojTime addIndexTime;
	MojTime dropIndexTime;
	err = timeUpdateKind(db, kindJson, kindObj, addIndexTime, dropIndexTime);
	MojTestErrCheck(err);

	MojUInt64 addTime = addIndexTime.microsecs();
	MojUInt64 dropTime = dropIndexTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   updating kind %s - adding index %s %llu times took: %llu microsecs\n", kindId, extraIdxJson, numUpdateKindIterations, addTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per add/reindex: %llu microsecs\n", (addTime) / (numUpdateKindIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   updating kind %s - dropping index %s %llu times took: %llu microsecs\n", kindId, extraIdxJson, numUpdateKindIterations, dropTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per drop: %llu microsecs", (dropTime) / (numUpdateKindIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	MojString buf;
	err = buf.format("Updating kind %s - adding index %s %llu times,%s,%llu,%llu,%llu,\nUpdating kind %s - dropping index %s %llu times,%s,%llu,%llu,%llu,\n",
			kindId, extraIdxJson, numUpdateKindIterations, kindId, addTime, addTime/numUpdateKindIterations, addTime/(1*numUpdateKindIterations),
			kindId, extraIdxJson, numUpdateKindIterations, kindId, dropTime, dropTime/numUpdateKindIterations, dropTime/(1*numUpdateKindIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #5
0
MojErr MojDbPerfUpdateTest::updateObjsViaPut(MojDb& db, const MojChar* kindId, MojErr (MojDbPerfTest::*createFn) (MojObject&, MojUInt64))
{
	// register all the kinds
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// put objects using createFn
	MojObject objs;
	err = putObjs(db, kindId, numInsertForPut, createFn, objs);
	MojTestErrCheck(err);

	MojObject midObj;
	bool found = objs.at(numInsertForPut/2, midObj);
	MojTestAssert(found);

	MojTime objTime;
	err = putObj(db, midObj, objTime);
	MojTestErrCheck(err);
	MojUInt64 putTime = objTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   putting single object - index %llu - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/2, kindId, numPutIterations, putTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per put: %llu microsecs", (putTime) / (numPutIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	MojString buf;
	err = buf.format("Put single object - index %llu - %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/2, numPutIterations, kindId, putTime, putTime/numPutIterations, putTime/(1*numPutIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	MojTime batchTime;
	MojObject::ArrayIterator beginArr;
	err = objs.arrayBegin(beginArr);
	MojErrCheck(err);
	err = batchPutObj(db, beginArr, beginArr + (numInsertForPut / 10), batchTime);
	putTime = batchTime.microsecs();
	MojTestErrCheck(err);
	err = MojPrintF("   putting batch - %llu objects - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/10, kindId, numBatchPutIterations, putTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per batch put: %llu microsecs\n", (putTime) / (numBatchPutIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (putTime) / (numInsertForPut/10 * numBatchPutIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	err = buf.format("Batch put %llu objects %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/10, numBatchPutIterations, kindId, putTime, putTime/numBatchPutIterations, putTime/(numInsertForPut/10*numBatchPutIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #6
0
MojErr MojTimeTest::run()
{
	MojTimevalT tv;
	tv.tv_sec = 400;
	tv.tv_usec = 54321;
	MojTime time = -8;
	time.fromTimeval(&tv);
	MojTestAssert(time == 400054321);
	MojTestAssert(time.secs() == 400);
	MojTestAssert(time.millisecs() == 400054);
	MojTestAssert(time.microsecs() == 400054321);
	MojTestAssert(time.millisecsPart() == 54);
	MojTestAssert(time.microsecsPart() == 54321);
	MojTimevalT tv2;
	time.toTimeval(&tv2);
	MojTestAssert(tv.tv_sec == tv2.tv_sec && tv.tv_usec == tv2.tv_usec);
	MojTimespecT ts;
	ts.tv_sec = 400;
	ts.tv_nsec = 54321;
	time.fromTimespec(&ts);
	MojTestAssert(time == 400000054);
	MojTimespecT ts2;
	time.toTimespec(&ts2);
	MojTestAssert(ts2.tv_sec = 400 && ts2.tv_nsec == 54000);

	time = MojSecs(3);
	MojTestAssert(time == 3000000);
	time = MojMillisecs(45);
	MojTestAssert(time == 45000);
	time = MojMicrosecs(5);
	MojTestAssert(time == 5);
	time = MojSecs(1) + MojMillisecs(2) + MojMicrosecs(3);
	MojTestAssert(time == 1002003);

	time = 1;
	MojTestAssert(time++ == 1);
	MojTestAssert(time == 2);
	MojTestAssert(++time == 3);
	MojTestAssert(--time == 2);
	MojTestAssert(time-- == 2);
	MojTestAssert(time == 1);
	MojTestAssert((time += 2) == 3);
	MojTestAssert((time -= 4) == -1);
	MojTestAssert((time *= -10) == 10);
	MojTestAssert((time /= 2) == 5);
	time = MojTime(1) + MojTime(2);
	MojTestAssert(time == 3);
	time = MojTime(8) - MojTime(6);
	MojTestAssert(time == 2);
	time = MojTime(8) * MojTime(6);
	MojTestAssert(time == 48);
	time = MojTime(8) / MojTime(4);
	MojTestAssert(time == 2);

	return MojErrNone;
}
Beispiel #7
0
MojErr MojDbIdGenerator::init()
{
	MojThreadGuard guard(m_mutex);

	MojTime time;
	MojErr err = MojGetCurrentTime(time);
	MojErrCheck(err);
	MojZero(&m_randBuf, sizeof(m_randBuf));
	err = MojInitRandom((MojUInt32) time.microsecs(), m_randStateBuf, sizeof(m_randStateBuf), &m_randBuf);
	MojErrCheck(err);

	return MojErrNone;
}
Beispiel #8
0
MojErr MojLocalTime(const MojTime& time, MojTmT& tmOut)
{
	time_t timet = (time_t) time.secs();
	if (localtime_r(&timet, &tmOut) == NULL)
		MojErrThrowErrno(_T("localtime_r"));

	return MojErrNone;
}
Beispiel #9
0
MojErr MojSleep(const MojTime& time)
{
	MojTimespecT ts;
	time.toTimespec(&ts);
	if (nanosleep(&ts, NULL) < 0)
		MojErrThrowErrno(_T("nanosleep"));

	return MojErrNone;
}
Beispiel #10
0
MojErr MojFileAppender::append(MojLogger::Level level, MojLogger* logger, const MojChar* format, va_list args)
{
	MojAssertNoLog(format);
	MojAssertNoLog(m_file != MojInvalidFile);

	// get current time
	MojTime time = 0;
	MojErr err = MojGetCurrentTime(time);
	MojErrCheckNoLog(err);
	MojTmT tm;
	err = MojLocalTime(time, tm);
	MojErrCheckNoLog(err);

	// format message
	err =  m_buf.format(_T("[%04d-%02d-%02d %02d:%02d:%02d:%03d] [%p] [%s]"),
			tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour,
			tm.tm_min, tm.tm_sec, time.millisecsPart(),
			(void*) (MojIntPtr) MojThreadCurrentId(),
			MojLogger::stringFromLevel(level));
	MojErrCheckNoLog(err);
	if (logger) {
		err = m_buf.appendFormat(_T(" [%s]: "), logger->name());
		MojErrCheckNoLog(err);
	} else {
		err = m_buf.append(_T(": "));
		MojErrCheckNoLog(err);
	}
	err =  m_buf.appendVFormat(format, args);
	MojErrCheckNoLog(err);
	err = m_buf.append(_T('\n'));
	MojErrCheckNoLog(err);

	// append to file
	const MojByte* begin = (const MojByte*) m_buf.begin();
	const MojByte* end = (const MojByte*) m_buf.end();
	while (begin < end) {
		MojSize written = 0;
		err = MojFileWrite(m_file, begin, end - begin, written);
		MojErrCheckNoLog(err);
		begin += written;
	}
	return MojErrNone;
}
Beispiel #11
0
MojErr MojGetCurrentTime(MojTime& timeOut)
{
	MojTimevalT tv;
	int ret = gettimeofday(&tv, NULL);
	if(ret < 0)
		MojErrThrowErrno(_T("gettimeofday"));
	timeOut.fromTimeval(&tv);

	return MojErrNone;
}
Beispiel #12
0
MojErr MojDbPerfCreateTest::testBatchInsertLgArrayObj(MojDb& db, const MojChar* kindId)
{
	// register all the kinds again
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// time put with large array objects (20 properties + 2 arrays of 5 elements each)
	MojTime batchLgArrayObjTime = 0;
	for (int i = 0; i < numRepetitions; i++) {
		err = putLargeArrayObj(db, kindId, batchLgArrayObjTime);
		MojTestErrCheck(err);
		MojDbQuery q;
		err = q.from(kindId);
		MojTestErrCheck(err);
		MojUInt32 count = 0;
		err = db.del(q, count);
		MojTestErrCheck(err);
	}

	MojUInt64 putTime = batchLgArrayObjTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   time to batch put %llu %s objects %d times: %llu microsecs\n", numInsert, kindId, numRepetitions, putTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per batch: %llu microsecs", (putTime) / (numRepetitions));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (putTime) / (numInsert * numRepetitions));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);
	MojString buf;
	err = buf.format("batch put %llu objects %d times,%s,%llu,%llu,%llu,\n", numInsert, numRepetitions, kindId, putTime, putTime/numRepetitions, putTime / (numInsert * numRepetitions));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #13
0
MojErr MojDbPerfCreateTest::testInsertMedArrayObj(MojDb& db, const MojChar* kindId)
{
	// register all the kinds again
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// time put with med array objects (10 properties + 1 array of 5 elements)
	MojTime medArrayObjTime;
	for (int i = 0; i < numRepetitions; i++) {
		err = putMedArrayObj(db, kindId, medArrayObjTime);
		MojTestErrCheck(err);
		MojDbQuery q;
		err = q.from(kindId);
		MojTestErrCheck(err);
		MojUInt32 count = 0;
		err = db.del(q, count, MojDb::FlagPurge);
		MojTestErrCheck(err);
	}

	MojUInt64 putTime = medArrayObjTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   time to put %llu %s objects %d times: %llu microsecs\n", numInsert, kindId, numRepetitions, putTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (putTime) / (numInsert * numRepetitions));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);
	MojString buf;
	err = buf.format("put %llu objects %d times,%s,%llu,%llu,%llu,\n", numInsert, numRepetitions, kindId, putTime, putTime/numRepetitions, putTime / (numInsert * numRepetitions));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);


	return MojErrNone;
}
Beispiel #14
0
MojErr MojSelect(int& nfdsOut, int nfds, MojFdSetT* readfds, MojFdSetT* writefds,
		MojFdSetT* exceptfds, const MojTime& timeout)
{
	MojTimevalT tv;
	timeout.toTimeval(&tv);
	int ret = select(nfds, readfds, writefds, exceptfds, &tv);
	if (ret < 0) {
		nfdsOut = 0;
		MojErrThrowErrno(_T("select"));
	}
	nfdsOut = ret;

	return MojErrNone;
}
Beispiel #15
0
MojErr MojDbPerfUpdateTest::updateObjsViaMerge(MojDb& db, const MojChar* kindId, MojErr (MojDbPerfTest::*createFn) (MojObject&, MojUInt64))
{
	// register all the kinds
	MojTime time;
	MojErr err = putKinds(db, time);
	MojTestErrCheck(err);

	// put objects using createFn
	MojObject objs;
	err = putObjs(db, kindId, numInsertForPut, createFn, objs);
	MojTestErrCheck(err);

	MojObject midObj;
	bool found = objs.at(numInsertForPut/2, midObj);
	MojTestAssert(found);

	MojTime objTime;
	err = mergeObj(db, midObj, objTime);
	MojTestErrCheck(err);
	MojUInt64 mergeTime = objTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   merging single object - index %llu - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/2, kindId, numMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per merge: %llu microsecs", (mergeTime) / (numMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	MojString buf;
	err = buf.format("Merge single object - index %llu - %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/2, numMergeIterations, kindId, mergeTime, mergeTime/numMergeIterations, mergeTime/(1*numMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	MojTime batchTime;
	MojObject::ArrayIterator beginArr;
	err = objs.arrayBegin(beginArr);
	MojErrCheck(err);
	err = batchMergeObj(db, beginArr, beginArr + (numInsertForPut / 10), batchTime);
	MojTestErrCheck(err);
	mergeTime = batchTime.microsecs();
	err = MojPrintF("   merging batch - %llu objects - of kind %s %llu times took: %llu microsecs\n", numInsertForPut/10, kindId, numBatchMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per batch merge: %llu microsecs\n", (mergeTime) / (numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (mergeTime) / (numInsertForPut/10 * numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	err = buf.format("Batch merge %llu objects %llu times,%s,%llu,%llu,%llu,\n", numInsertForPut/10, numBatchMergeIterations, kindId, mergeTime, mergeTime/numBatchMergeIterations, mergeTime/(numInsertForPut/10*numBatchMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	MojTime mergeQueryTime;
	MojTestErrCheck(err);
	MojDbQuery query;
	err = query.from(kindId);
	MojTestErrCheck(err);
	query.limit(numInsertForPut/5);
	query.desc(true);

	MojObject queryObj;
	err = query.toObject(queryObj);
	MojTestErrCheck(err);
	MojString queryStr;
	err = queryObj.stringValue(queryStr);
	MojTestErrCheck(err);

	MojObject props;
	err = props.putString(_T("newKey"), _T("here's a new value"));
	MojTestErrCheck(err);
	MojUInt32 count;
	err = queryMergeObj(db, query, props, count, mergeQueryTime);
	MojTestErrCheck(err);
	mergeTime = mergeQueryTime.microsecs();
	err = MojPrintF("   merging with query - %d objects - of kind %s %llu times took: %llu microsecs\n", count, kindId, numBatchMergeIterations, mergeTime);
	MojTestErrCheck(err);
	err = MojPrintF("   time per merge: %llu microsecs\n", (mergeTime) / (numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("   time per object: %llu microsecs", (mergeTime) / (count * numBatchMergeIterations));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	err = buf.format("Merge with query %s,,,,,\nMerge with query - %d objects - %llu times,%s,%llu,%llu,%llu,\n", queryStr.data(), count, numBatchMergeIterations, kindId, mergeTime, mergeTime/numBatchMergeIterations, mergeTime/(count*numBatchMergeIterations));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #16
0
MojErr MojDbPerfCreateTest::testCreate()
{

	//setup the test storage engine
#ifdef MOJ_USE_BDB
	MojRefCountedPtr<MojDbStorageEngine> engine(new MojDbBerkeleyEngine());
#elif MOJ_USE_LDB
	MojRefCountedPtr<MojDbStorageEngine> engine(new MojDbLevelEngine());
#else
    MojRefCountedPtr<MojDbStorageEngine> engine;
#endif
	MojAllocCheck(engine.get());
    MojDb db;

	MojErr err = db.open(MojDbTestDir, engine.get());
	MojTestErrCheck(err);

	// time put kind
	MojTime putKindTime;
	for (int i = 0; i < numRepetitions; i++) {
		err = putKinds(db, putKindTime);
		MojTestErrCheck(err);
		err = delKinds(db);
		MojTestErrCheck(err);
	}

	MojUInt64 putKind = putKindTime.microsecs();
	err = MojPrintF("\n -------------------- \n");
	MojTestErrCheck(err);
	err = MojPrintF("   putKind took: %llu microsecs", (putKind / (numKinds * numRepetitions)));
	MojTestErrCheck(err);
	err = MojPrintF("\n\n");
	MojTestErrCheck(err);

	MojString buf;
	err = buf.format("put Kind,all %llu kinds,%llu,%llu,%llu,\n", numKinds, putKind, putKind/numRepetitions, putKind / (numKinds * numRepetitions));
	MojTestErrCheck(err);
	err = fileWrite(file, buf);
	MojTestErrCheck(err);

	// insert objects with one index
	err = testInsertSmallObj(db, MojPerfSmKindId);
	MojTestErrCheck(err);
	err = testInsertMedObj(db, MojPerfMedKindId);
	MojTestErrCheck(err);
	err = testInsertLgObj(db, MojPerfLgKindId);
	MojTestErrCheck(err);
	err = testInsertMedNestedObj(db, MojPerfMedNestedKindId);
	MojTestErrCheck(err);
	err = testInsertLgNestedObj(db, MojPerfLgNestedKindId);
	MojTestErrCheck(err);
	err = testInsertMedArrayObj(db, MojPerfMedArrayKindId);
	MojTestErrCheck(err);
	err = testInsertLgArrayObj(db, MojPerfLgArrayKindId);
	MojTestErrCheck(err);

	// insert objects with two indices
	err = testInsertSmallObj(db, MojPerfSmKind2Id);
	MojTestErrCheck(err);
	err = testInsertMedObj(db, MojPerfMedKind2Id);
	MojTestErrCheck(err);
	err = testInsertLgObj(db, MojPerfLgKind2Id);
	MojTestErrCheck(err);
	err = testInsertMedNestedObj(db, MojPerfMedNestedKind2Id);
	MojTestErrCheck(err);
	err = testInsertLgNestedObj(db, MojPerfLgNestedKind2Id);
	MojTestErrCheck(err);
	err = testInsertMedArrayObj(db, MojPerfMedArrayKind2Id);
	MojTestErrCheck(err);
	err = testInsertLgArrayObj(db, MojPerfLgArrayKind2Id);
	MojTestErrCheck(err);

	// batch insert with one index
	err = testBatchInsertLgObj(db, MojPerfLgKindId);
	MojTestErrCheck(err);
	err = testBatchInsertLgNestedObj(db, MojPerfLgNestedKindId);
	MojTestErrCheck(err);
	err = testBatchInsertLgArrayObj(db, MojPerfLgArrayKindId);
	MojTestErrCheck(err);

	// batch insert with two indices
	err = testBatchInsertLgObj(db, MojPerfLgKind2Id);
	MojTestErrCheck(err);
	err = testBatchInsertLgNestedObj(db, MojPerfLgNestedKind2Id);
	MojTestErrCheck(err);
	err = testBatchInsertLgArrayObj(db, MojPerfLgArrayKind2Id);
	MojTestErrCheck(err);

	err = db.close();
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #17
0
MojErr MojDbPurgeTest::run()
{
	MojDb db;
	MojErr err = db.open(MojDbTestDir);
	MojTestErrCheck(err);

	// put type
	MojObject obj;
	err = obj.fromJson(MojKindStr);
	MojTestErrCheck(err);
	err = db.putKind(obj);
	MojTestErrCheck(err);

	MojObject revNums[10];
	MojObject ids[10];
	//put 10 objects in the db
	for(int i = 0; i < 10; i++) {
		err = obj.fromJson(MojTestObjStr1);
		MojTestErrCheck(err);
		err = db.put(obj);
		MojTestErrCheck(err);
		// get _rev and id
		MojObject rev;
		err = obj.getRequired(MojDb::RevKey, rev);
		MojTestErrCheck(err);
		revNums[i] = rev;
		MojObject id;
		err = obj.getRequired(MojDb::IdKey, id);
		MojTestErrCheck(err);
		ids[i] = id;
	}

	//purge now, there are no RevTimestamp entries
	MojUInt32 count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 1, -1);
	MojTestErrCheck(err);

	//create a RevTimestamp entry - that's not more than PurgeNumDays days ago
	MojTime time;
	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revNums[0], time.microsecs());
	MojTestErrCheck(err);

	//purge now, there are no RevTimestamp entries that are more than
	//PurgeNumDays ago, so nothing should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 3, -1);
	MojTestErrCheck(err);

	//create a RevTimestamp entry for more than PurgeNumDays days ago
	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revNums[9], time.microsecs() - (((MojInt64)40) * MojTime::UnitsPerDay));
	MojTestErrCheck(err);

	//purge now, since nothing has been deleted, nothing should be purged,
	//but the RevTimestamp object should be deleted
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 10, 4, -1);
	MojTestErrCheck(err);

	//delete something - this will set its revision number higher
	bool found;
	err = db.del(ids[0], found);
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	//purge now, since nothing has been deleted prior to the revision
	//number, nothing should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 0, 9, 5, -1);
	MojTestErrCheck(err);

	//delete another object
	err = db.del(ids[1], found);
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	//create a RevTimestamp entry for more than PurgeNumDays days ago,
	//with the rev number of the 1st obj we deleted
	MojDbQuery query;
	err = query.from(_T("PurgeTest:1"));
	MojTestErrCheck(err);
	err = query.where(MojDb::IdKey, MojDbQuery::OpEq, ids[0]);
	MojTestErrCheck(err);
	err = query.includeDeleted();
	MojTestErrCheck(err);

	MojDbCursor cursor;
	err = db.find(query, cursor);
	MojTestErrCheck(err);

	MojObject objFromDb;
	err = cursor.get(objFromDb, found);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);
	MojTestAssert(found == true);

	MojObject revFromDb;
	err = objFromDb.getRequired(MojDb::RevKey, revFromDb);
	MojTestErrCheck(err);

	err = MojGetCurrentTime(time);
	MojTestErrCheck(err);
	err = createRevTimestamp(db, revFromDb, time.microsecs() - (((MojInt64)35) * MojTime::UnitsPerDay));
	MojTestErrCheck(err);

	//now purge, only id[0] should be purged
	count = 0;
	err = db.purge(count, 30);
	MojTestErrCheck(err);

	err = checkObjectsPurged(db, count, 1, 8, 6, revFromDb);
	MojTestErrCheck(err);

	//TODO 2.12.10 - this test does not pass yet, we need to fix calling delKind after a purge
	//err = delKindTest(db);
	//MojTestErrCheck(err);

	err = db.close();
	MojTestErrCheck(err);

	return MojErrNone;
}
Beispiel #18
0
MojErr MojDb::purge(MojUInt32& countOut, MojInt64 numDays, MojDbReqRef req)
{
	MojLogTrace(s_log);

	countOut = 0;
	if (numDays <= -1) {
		numDays = m_purgeWindow;
	}

	MojErr err = beginReq(req);
	MojErrCheck(err);

	MojLogDebug(s_log, _T("purging objects deleted more than %lld days ago..."), numDays);

	MojTime time;
	err = MojGetCurrentTime(time);
	MojErrCheck(err);

	// store the revision number to current timestamp mapping
	MojObject revTimeMapping;
	MojInt64 rev;
	err = nextId(rev);
	MojErrCheck(err);
	err = revTimeMapping.put(RevNumKey, rev);
	MojErrCheck(err);
	err = revTimeMapping.put(TimestampKey, time.microsecs());
	MojErrCheck(err);
	err = revTimeMapping.putString(KindKey, MojDbKindEngine::RevTimestampId);
	MojErrCheck(err);

	err = putImpl(revTimeMapping, MojDb::FlagNone, req);
	MojErrCheck(err);

	// find the revision number for numDays prior to now
	MojInt64 purgeTime = time.microsecs() - (MojTime::UnitsPerDay * numDays);
	MojDbQuery query;
	err = query.from(MojDbKindEngine::RevTimestampId);
	MojErrCheck(err);
	query.limit(1);
	err = query.where(TimestampKey, MojDbQuery::OpLessThanEq, purgeTime);
	MojErrCheck(err);
	err = query.order(TimestampKey);
	MojErrCheck(err);
	query.desc(true);

	MojDbCursor cursor;
	err = findImpl(query, cursor, NULL, req, OpDelete);
	MojErrCheck(err);
	bool found = false;
	MojObject obj;
	err = cursor.get(obj, found);
	MojErrCheck(err);
	err = cursor.close();
	MojErrCheck(err);

	MojUInt32 batchCount = 0;
	MojUInt32 totalCount = 0;

	while ((found))
	{
		// Do it in AutoBatchSize batches
		batchCount = 0;
		req->fixmode(true);		// purge even if index mis-matches
		err = purgeImpl(obj, batchCount, req);
		MojLogDebug(s_log, _T("purge batch processed: batch: %d; total: %d; err = %d\n"),
					batchCount, (totalCount + batchCount), err);
		MojErrCheck(err);
		totalCount += batchCount;
		countOut = totalCount;
		if (batchCount < AutoBatchSize)	// last batch
			break;
		err = commitBatch(req);
		MojErrCheck(err);
		continue;
	}

	// end request
	err = req->end();
	MojErrCheck(err);

	MojLogDebug(s_log, _T("purged %d objects"), countOut);


	return MojErrNone;
}