Exemplo n.º 1
0
MojErr MojService::dispatchReply(MojServiceMessage* msg)
{
	MojAssert(msg);
	MojAssertMutexUnlocked(m_mutex);
	MojLogTrace(s_log);

	// parse payload
	MojObjectBuilder builder;
	MojObject payload;
	MojErr err = MojErrNone;
	MojInt64 errCode = MojErrNone;
	errCode = err = msg->payload(builder);
	MojErrCatchAll(err);
	if (errCode == MojErrNone)
		payload = builder.object();

	// get errCode
	bool retVal = false;
	if (payload.get(MojServiceMessage::ReturnValueKey, retVal) && !retVal) {
		if (!payload.get(MojServiceMessage::ErrorCodeKey, errCode))
			errCode = MojErrUnknown;
	}
	// find request
	MojRefCountedPtr<MojServiceRequest> req;
	err = getRequest(msg, req);
	MojErrCheck(err);

	// do the dispatch
	err = dispatchReplyImpl(req.get(), msg, payload, (MojErr) errCode);
	MojErrCatchAll(err);

	return MojErrNone;
}
Exemplo n.º 2
0
MojErr MojDbQuery::toObject(MojObject& objOut) const
{
	MojObjectBuilder builder;
	MojErr err = toObject(builder);
	MojErrCheck(err);
	objOut = builder.object();
	return MojErrNone;
}
Exemplo n.º 3
0
MojErr MojDbIsamQuery::parseId(MojObject& idOut)
{
	// parse id out of key
	MojObjectEater eater;
	MojObjectReader reader(m_keyData, m_keySize);
	for (MojSize i = 0; i < m_plan->idIndex(); ++i) {
		MojErr err = reader.nextObject(eater);
		MojErrCheck(err);
	}
	MojObjectBuilder builder;
	MojErr err = reader.nextObject(builder);
	MojErrCheck(err);
	idOut = builder.object();

	return MojErrNone;
}
Exemplo n.º 4
0
MojErr MojDb::get(const MojObject& id, MojObject& objOut, bool& foundOut, MojDbReqRef req)
{
	MojLogTrace(s_log);

	objOut.clear();
	foundOut = false;
	MojObjectBuilder builder;

	MojErr err = get(&id, &id + 1, builder, req);
	MojErrCheck(err);

	objOut = builder.object();
	foundOut = !objOut.undefined();

	return MojErrNone;
}
Exemplo n.º 5
0
MojErr MojDbDistinctTest::check(MojDb& db, const MojDbQuery& query, MojDbCursor& cursor, const MojChar* queryString, const MojChar* expectedIdsJson)
{
	MojErr err = db.find(query, cursor);
	MojTestErrCheck(err);

	MojObjectBuilder builder;
	err = builder.beginArray();
	MojTestErrCheck(err);
	err = cursor.visit(builder);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);
	err = builder.endArray();
	MojTestErrCheck(err);
	MojObject results = builder.object();

	MojString json;
	err = results.toJson(json);
	MojTestErrCheck(err);

	MojObject expected;
	err = expected.fromJson(expectedIdsJson);
	MojTestErrCheck(err);

	// size check
	MojTestAssert(expected.size() == results.size());

	// value check
	MojObject::ConstArrayIterator j = results.arrayBegin();
	for (MojObject::ConstArrayIterator i = expected.arrayBegin();
			i != expected.arrayEnd(); ++i, ++j) {
		MojObject value;
		err = j->getRequired(queryString, value);
		MojTestErrCheck(err);
		MojTestAssert(*i == value);
	}
	return MojErrNone;
}
Exemplo n.º 6
0
MojErr MojDbSearchTest::check(MojDb& db, const MojDbQuery& query, const MojChar* expectedIdsJson)
{
   MojString str;
   MojDbSearchCursor cursor(str);
	MojErr err = db.find(query, cursor);
	MojTestErrCheck(err);

	MojObjectBuilder builder;
	err = builder.beginArray();
	MojTestErrCheck(err);
	err = cursor.visit(builder);
	MojTestErrCheck(err);
	err = cursor.close();
	MojTestErrCheck(err);
	err = builder.endArray();
	MojTestErrCheck(err);
	MojObject results = builder.object();

	MojString json;
	err = results.toJson(json);
	MojTestErrCheck(err);

	MojObject expected;
	err = expected.fromJson(expectedIdsJson);
	MojTestErrCheck(err);

	MojTestAssert(expected.size() == results.size());
	MojObject::ConstArrayIterator j = results.arrayBegin();
	for (MojObject::ConstArrayIterator i = expected.arrayBegin();
			i != expected.arrayEnd(); ++i, ++j) {
		MojObject id;
		err = j->getRequired(MojDb::IdKey, id);
		MojTestErrCheck(err);
		MojTestAssert(*i == id);
	}
	return MojErrNone;
}
Exemplo n.º 7
0
/**
****************************************************************************************************
* @run              MojObject stores key-value pairs.Internally it provides separate implmentation
                    for all data types. Provides facility to push single entry or entire array
                    of data into MojObject.
                    Supports put/get/delete operation.
                    Data having key and value is converted to Node type and then node is inserted
                    into TreeBase. All operation happens on TreeBase are based on key.
                    Provides interface to convert JSON string to JSON object and viceversa.
* @param         :  None
* @retval        :  MojErr
****************************************************************************************************
**/
MojErr MojObjectTest::run()
{
    MojObject obj0;
    MojObject obj1;
    MojObject obj2;
    MojObject obj3;
    MojObject obj4;
    MojString str1;
    MojObjectBuilder builder;
    int count = 0;
    bool found = false;

    // empty object
    MojTestAssert(obj1.type() == MojObject::TypeUndefined);
    MojErr err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeNull);
    MojTestAssert(obj1.type() == MojObject::TypeNull);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeObject);
    MojTestAssert(obj1.type() == MojObject::TypeObject);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeArray);
    MojTestAssert(obj1.type() == MojObject::TypeArray);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeString);
    MojTestAssert(obj1.type() == MojObject::TypeString);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeBool);
    MojTestAssert(obj1.type() == MojObject::TypeBool);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeDecimal);
    MojTestAssert(obj1.type() == MojObject::TypeDecimal);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    obj1.clear(MojObject::TypeInt);
    MojTestAssert(obj1.type() == MojObject::TypeInt);
    err = emptyTest(obj1);
    MojTestErrCheck(err);
    err = obj2.fromJson("{}");
    MojTestAssert(obj2.type() == MojObject::TypeObject);
    MojTestErrCheck(err);
    err = emptyTest(obj2);
    MojTestErrCheck(err);
    err = obj3.put(_T("hello"), 5LL);
    MojTestErrCheck(err);
    err = obj3.del(_T("hello"), found);
    MojTestErrCheck(err);
    MojTestAssert(found);
    err = emptyTest(obj3);
    MojTestErrCheck(err);
    err = obj3.put(_T("hello"), 5LL);
    MojTestErrCheck(err);
    obj3.clear();
    err = emptyTest(obj3);
    MojTestErrCheck(err);

    // put/get/del
    err = putTest(obj1);
    MojTestErrCheck(err);
    err = getTest(obj1);
    MojTestErrCheck(err);
    err = obj1.visit(builder);
    MojTestErrCheck(err);
    err = getTest(builder.object());
    MojTestErrCheck(err);
    err = obj1.toJson(str1);
    MojTestErrCheck(err);
    err = obj2.fromJson(str1);
    MojTestErrCheck(err);
    err = getTest(obj2);
    MojTestErrCheck(err);
    obj3 = obj2;
    err = getTest(obj3);
    MojTestErrCheck(err);
    obj3.clear();
    MojTestAssert(obj3.empty());

    // iterator
    for (MojObject::ConstIterator i = obj2.begin(); i != obj2.end(); ++i) {
        count++;
        obj3.put(i.key(), i.value());
    }
    MojTestAssert(count == 10);
    err = getTest(obj3);
    MojTestErrCheck(err);

    // types
    err = typeTest();
    MojTestErrCheck(err);

    return MojErrNone;
}
Exemplo n.º 8
0
MojErr MojDb::load(const MojChar* path, MojUInt32& countOut, MojUInt32 flags, MojDbReqRef req)
{
	MojAssert(path);
	MojLogTrace(s_log);

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

	MojFile file;
	err = file.open(path, MOJ_O_RDONLY);
	MojErrCheck(err);

	MojJsonParser parser;
	parser.begin();
	MojSize bytesRead = 0;
	MojObjectBuilder visitor;

	int total_mutexes, mutexes_free, mutexes_used, mutexes_used_highwater, mutex_regionsize;
	m_objDb->mutexStats(&total_mutexes, &mutexes_free, &mutexes_used, &mutexes_used_highwater, &mutex_regionsize);

	MojLogDebug(s_log, _T("Starting load of %s, total_mutexes: %d, mutexes_free: %d, mutexes_used: %d, mutexes_used_highwater: %d, &mutex_regionsize: %d\n"),
						path,	total_mutexes, mutexes_free, mutexes_used, mutexes_used_highwater, mutex_regionsize);

	int orig_mutexes_used = mutexes_used;

	struct timeval startTime = {0,0}, stopTime = {0,0};

	gettimeofday(&startTime, NULL);

	int total_transaction_time = 0;

	int total = 0;
	int transactions = 0;

	do {
		MojChar buf[MojFile::MojFileBufSize];
		err = file.read(buf, sizeof(buf), bytesRead);
		MojErrCheck(err);

		const MojChar* parseEnd = buf;
		while (parseEnd < (buf + bytesRead)) {
			err = parser.parseChunk(visitor, parseEnd, bytesRead - (parseEnd - buf), parseEnd);
			MojErrCheck(err);
			if (parser.finished()) {
				//store the object
				err = loadImpl(visitor.object(), flags, req);
				MojErrCheck(err);
				countOut++;
				parser.begin();
				visitor.reset();

				total++;

				if ((total % 10) == 0) {
					// For debugging mutex consumption during load operations, we periodically retrieve the mutex stats.
					m_objDb->mutexStats(&total_mutexes, &mutexes_free, &mutexes_used, &mutexes_used_highwater, &mutex_regionsize);

					MojLogDebug(s_log, _T("Loading %s record %d, total_mutexes: %d, mutexes_free: %d, mutexes_used: %d, mutexes_used_highwater: %d, &mutex_regionsize: %d\n"),
							path, total, total_mutexes, mutexes_free, mutexes_used, mutexes_used_highwater, mutex_regionsize);
				}

				// If a loadStepSize is configured, then break up the load into separate transactions.
				// This is intended to prevent run-away mutex consumption in some particular scenarios.
				// The transactions do not reverse or prevent mutex consumption, but seem to reduce the
				// growth and eventually cause it to level off.

				if ((m_loadStepSize > 0) && ((total % m_loadStepSize) == 0)) {
					// Close and reopen transaction, to prevent a very large transaction from building up.
					MojLogDebug(s_log, _T("Loading %s record %d, closing and reopening transaction.\n"),
							path, total);

					struct timeval transactionStartTime = {0,0}, transactionStopTime = {0,0};

					gettimeofday(&transactionStartTime, NULL);

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

					err = req->endBatch();
					MojErrCheck(err);

					req->beginBatch(); // beginBatch() invocation for first transaction happened in MojDbServiceHandlerBase::invokeImpl

					err = beginReq(req, true);
					MojErrCheck(err);

					gettimeofday(&transactionStopTime, NULL);

					long int elapsedTransactionTimeMS = (transactionStopTime.tv_sec - transactionStartTime.tv_sec) * 1000 +
								(transactionStopTime.tv_usec - transactionStartTime.tv_usec) / 1000;

					total_transaction_time += (int)elapsedTransactionTimeMS;

					transactions++;
				}
			}
		}
	} while (bytesRead > 0);

	err = parser.end(visitor);
	MojErrCheck(err);
	if (parser.finished()) {
		err = loadImpl(visitor.object(), flags, req);
		MojErrCheck(err);
		countOut++;
	} else if (bytesRead > 0) {
		MojErrThrow(MojErrJsonParseEof);
	}

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

	gettimeofday(&stopTime, NULL);
	long int elapsedTimeMS = (stopTime.tv_sec - startTime.tv_sec) * 1000 +
				(stopTime.tv_usec - startTime.tv_usec) / 1000;

	m_objDb->mutexStats(&total_mutexes, &mutexes_free, &mutexes_used, &mutexes_used_highwater, &mutex_regionsize);

	MojLogDebug(s_log, _T("Finished load of %s, total_mutexes: %d, mutexes_free: %d, mutexes_used: %d, mutexes_used_highwater: %d, &mutex_regionsize: %d\n"),
						path, total_mutexes, mutexes_free, mutexes_used, mutexes_used_highwater, mutex_regionsize);

    MojLogDebug(s_log, _T("Loaded %s with %d records in %ldms (%dms of that for %d extra transactions), consuming %d mutexes, afterwards %d are available out of %d\n"),
		path, total, elapsedTimeMS, total_transaction_time, transactions, mutexes_used - orig_mutexes_used, mutexes_free, total_mutexes);

	return MojErrNone;
}