Пример #1
0
/*
 * Delete all database entries
 */
bool	CDbManager::deleteAllDatabases(CLog* log)
{
	CHECK_DB_MGR_INIT(getDatabase, false);

	CTimestamp	starttime = _LastUpdateTime;
	CTimestamp	endtime;
	endtime.setToCurrent();

	TDatabaseMap::iterator	it;
	for (it=_DatabaseMap.begin(); it!=_DatabaseMap.end(); ++it)
	{
		CDatabase*	db = (*it).second;

		if (db == NULL)
		{
			log->displayNL("Database '%d' left with as NULL", (*it).first);
		}
		else
		{
			// flush db
			if (!db->buildDelta(starttime, endtime))
				nlwarning("failed to build delta for database '%d' '%s'", (*it).first, db->getName().c_str());

			// delete it
			delete db;
		}

		// unreference it
		(*it).second = NULL;
	}

	_DatabaseMap.clear();

	return true;
}
Пример #2
0
/*
 * Setup file name and path
 */
void	CDBDeltaFile::setup(const std::string& name, const std::string& path, uint32 rowSize, const CTimestamp& startTimestamp, const CTimestamp& endTimestamp)
{
	uint32		tableId;
	CTimestamp	timestamp;
	nlassert(isDeltaFileName(name, tableId, timestamp));

	_Name = name;
	_Path = NLMISC::CPath::standardizePath(path);

	_Header.RowSize = rowSize;
	_Header.FullRowSize = rowSize + getRowHeaderSize();
	//_Header.Timestamp = timestamp.toTime();
	_Header.StartTimestamp = uint32(startTimestamp.toTime());
	_Header.EndTimestamp = uint32(endTimestamp.toTime());
}
Пример #3
0
/*
 * Update
 * Call regularly this method once a tick to apply changes to database
 */
void	CPDSLib::update()
{
	if (_UsePDS)
	{
		// check pds is ready to receive update
		if (!PDSReady())
			return;

		if (_DbMessageQueue.empty())
			return;

		std::list<CDbMessageQueue>::iterator	it;
		for (it=_DbMessageQueue.begin(); it!=_DbMessageQueue.end(); ++it)
		{
			CDbMessageQueue&	queue = (*it);

			// create a new message
			CMessage*	msgupd = new CMessage("PD_UPDATE");
			msgupd->serial(_DatabaseId);
			msgupd->serial(_UpdateId);
			_QueuedMessages.push_back(make_pair<uint32,CMessage*>(_UpdateId, msgupd));
			++_UpdateId;

			// serial queue
			msgupd->serial(queue);

			// send update to the pds
			CUnifiedNetwork::getInstance()->send("PDS", *msgupd);
		}

		// clean up for next update
		_DbMessageQueue.clear();
	}
	else
	{
		uint	i;

		// save log (updates + string manager)
		TTime	ctime = CTime::getLocalTime();

		//
		CTimestamp	timestamp;
		timestamp.setToCurrent();

		// setup update logs with full timestamp
		if (!_DbMessageQueue.empty())
		{
			i = (uint)_UpdateLogs.size();
			_UpdateLogs.resize(_DbMessageQueue.size());

			for (; i<_UpdateLogs.size(); ++i)
			{
				_UpdateLogs[i].StartStamp = _PreviousTickDate;
				_UpdateLogs[i].EndStamp = _PreviousTickDate;
			}

			_UpdateLogs.back().EndStamp = timestamp;
		}

		_PreviousTickDate = timestamp;

		if (ctime - _PreviousLogSave > PDLogUpdate*1000 && !_DbMessageQueue.empty())
		{
//			std::string	logDir = getRemoteLogDirectory();
//			std::string	logFile = _LogStartDate.toString()+"_0000.pd_log";
//
//			// if don't use BS, create logdir directory tree
//			if (!PDUseBS && !CFile::isDirectory(logDir))
//			{
//				if (!CFile::createDirectoryTree(logDir))
//				{
//					nlwarning("Failed to create log root directory '%s'", logDir.c_str());
//				}
//
//				if (!CFile::setRWAccess(logDir))
//				{
//					nlwarning("Failed, can't set RW access to directory '%s'", logDir.c_str());
//				}
//			}
//
//			// map update logs to msg queues
//			nlassert(_UpdateLogs.size() == _DbMessageQueue.size());
//			for (i=0; i<_UpdateLogs.size(); ++i)
//				_UpdateLogs[i].setUpdates(&(_DbMessageQueue.get(i)));
//
//			if (PDUseBS)
//			{
//				CBackupMsgSaveFile	msgBS( logDir+logFile, CBackupMsgSaveFile::AppendFileCheck, PDBsi );
//				msgBS.DataMsg.serialCont(_UpdateLogs);
//				PDBsi.append(msgBS);
//			}
//			else
//			{
//				COFile				file;
//				if (file.open(logDir + logFile))
//				{
//					file.serialCont(_UpdateLogs);
//				}
//				else
//				{
//					nlwarning("Failed to save log file '%s' for database %d", (logDir + logFile).c_str(), _DatabaseId);
//				}
//			}

//			if (PDEnableStringLog && !_StringManager.logEmpty())
//			{
//				std::string			logFile = timestamp.toString()+".string_log";
//
//				if (PDUseBS)
//				{
//					bool				success = false;
//					CBackupMsgSaveFile	msgBS( logDir+logFile, CBackupMsgSaveFile::SaveFileCheck, PDBsi );
//					{
//						COXml				xml;
//
//						if (xml.init(&msgBS.DataMsg))
//						{
//							_StringManager.storeLog(xml);
//							success = true;
//						}
//						else
//						{
//							nlwarning("Failed to save string log file '%s' for database %d", msgBS.FileName.c_str(), _DatabaseId);
//						}
//					}
//
//					if (success)
//					{
//						PDBsi.sendFile(msgBS);
//					}
//				}
//				else
//				{
//					COFile				file;
//					{
//						COXml				xml;
//						if (file.open(logDir + logFile) && xml.init(&file))
//						{
//							_StringManager.storeLog(xml);
//						}
//						else
//						{
//							nlwarning("Failed to save string log file '%s' for database %d", (logDir+logFile).c_str(), _DatabaseId);
//						}
//					}
//				}
//			}

			_PreviousLogSave = ctime;

			// clean up for next update
			_DbMessageQueue.clear();
			_UpdateLogs.clear();

		}

		if (timestamp.toTime()-_LogStartDate.toTime() > sint(PDLogFileTime.get()))
		{
			_LogStartDate = timestamp;
		}

		_DbMessageQueue.forceNextQueue();
	}
}
Пример #4
0
/*
 * Send Delta/Reference build commands
 */
bool	CDatabase::sendBuildCommands(const CTimestamp& current)
{
	checkUpdateRates();

	while (current - _MinuteUpdateTimestamp >= MinuteUpdateRate)
	{
		CTimestamp	start = _MinuteUpdateTimestamp;
		CTimestamp	end = start + MinuteUpdateRate;
		CTimestamp	keep = end - MinuteUpdateRate*KeepSecondsAtMinuteUpdate;

		string					outputPath = _Reference.getMinutesUpdatePath();
		string					hoursUpdatePath = _Reference.getHoursUpdatePath();
		string					minutesUpdatePath = _Reference.getMinutesUpdatePath();
		string					secondsUpdatePath = _Reference.getSecondsUpdatePath();
		string					mintimestamp = start.toString();
		string					maxtimestamp = end.toString();
		CDeltaBuilder::TDelta	type = CDeltaBuilder::Minute;
		string					keeptimestamp = keep.toString();

		CMessage&				msgdelta = CDbManager::addTask("RB_GEN_DELTA", NULL, NULL);
		msgdelta.serial(outputPath);
		msgdelta.serial(hoursUpdatePath);
		msgdelta.serial(minutesUpdatePath);
		msgdelta.serial(secondsUpdatePath);
		msgdelta.serial(mintimestamp);
		msgdelta.serial(maxtimestamp);
		msgdelta.serialEnum(type);
		msgdelta.serial(keeptimestamp);

		_MinuteUpdateTimestamp = end;
	}


	while (current - _HourUpdateTimestamp >= HourUpdateRate)
	{
		CTimestamp	start = _HourUpdateTimestamp;
		CTimestamp	end = start + HourUpdateRate;
		CTimestamp	keep = end - HourUpdateRate*KeepMinutesAtHourUpdate;

		string					outputPath = _Reference.getHoursUpdatePath();
		string					hoursUpdatePath = _Reference.getHoursUpdatePath();
		string					minutesUpdatePath = _Reference.getMinutesUpdatePath();
		string					secondsUpdatePath = _Reference.getSecondsUpdatePath();
		string					mintimestamp = start.toString();
		string					maxtimestamp = end.toString();
		CDeltaBuilder::TDelta	type = CDeltaBuilder::Hour;
		string					keeptimestamp = keep.toString();

		CMessage&				msgdelta = CDbManager::addTask("RB_GEN_DELTA", NULL, NULL);
		msgdelta.serial(outputPath);
		msgdelta.serial(hoursUpdatePath);
		msgdelta.serial(minutesUpdatePath);
		msgdelta.serial(secondsUpdatePath);
		msgdelta.serial(mintimestamp);
		msgdelta.serial(maxtimestamp);
		msgdelta.serialEnum(type);
		msgdelta.serial(keeptimestamp);

		_HourUpdateTimestamp = end;
	}

	while (current - _DayUpdateTimestamp >= ReferenceUpdateRate)
	{
		CTimestamp	start = _DayUpdateTimestamp;
		CTimestamp	end = start + ReferenceUpdateRate;
		CTimestamp	keep = end - ReferenceUpdateRate*KeepHoursAtReferenceUpdate;

		CRefIndex*	next = new CRefIndex(_State.Id);
		*next = _Reference;
		next->buildNext();

		string		rootRefPath = _Reference.getRootPath();
		string		previousReferencePath = _Reference.getPath();
		string		nextReferencePath = next->getPath();

		string		logUpdatePath = _Reference.getLogPath();
		string		hoursUpdatePath = _Reference.getHoursUpdatePath();
		string		minutesUpdatePath = _Reference.getMinutesUpdatePath();
		string		secondsUpdatePath = _Reference.getSecondsUpdatePath();

		string		mintimestamp = start.toString();
		string		maxtimestamp = end.toString();
		string		keeptimestamp = keep.toString();

		CMessage&	msgref = CDbManager::addTask("RB_GEN_REF", this, (void*)next);
		msgref.serial(rootRefPath);
		msgref.serial(previousReferencePath);
		msgref.serial(nextReferencePath);
		msgref.serial(hoursUpdatePath);
		msgref.serial(minutesUpdatePath);
		msgref.serial(secondsUpdatePath);
		msgref.serial(logUpdatePath);
		msgref.serial(mintimestamp);
		msgref.serial(maxtimestamp);
		msgref.serial(keeptimestamp);

		_DayUpdateTimestamp = end;
	}

	return true;
}
Пример #5
0
/*
 * Update manager
 */
bool	CDbManager::update()
{
	H_AUTO(PDS_DbManager_update);

	CHECK_DB_MGR_INIT(update, false);

	// update stamp
	CTableBuffer::updateCommonStamp();

	TDatabaseMap::iterator	it;

	CDatabase::checkUpdateRates();


	// check evently if database need to write some delta
	TTime	tm = CTime::getLocalTime();
	if (tm >= _NextTimeDelta)
	{

		CTimestamp	starttime = _LastUpdateTime;
		CTimestamp	endtime;
		endtime.setToCurrent();

		std::vector<uint32>	ack;

		for (it=_DatabaseMap.begin(); it!=_DatabaseMap.end(); ++it)
		{
			CDatabase*	database = (*it).second;

			// generate deltas
			if (!database->buildDelta(starttime, endtime))
				nlwarning("failed to build delta for database '%d' '%s'", (*it).first, database->getName().c_str());

			// obsolete? since RBS build references and tells PDS of success/failure
			database->checkReferenceChange();

			// acknowledge last updates
			database->flushUpdates(ack);

			if (!ack.empty() && database->getMappedService().get() != 0xffff)
			{
				CMessage	msgack("PD_ACK_UPD");
				uint32		databaseId = (*it).first;
				msgack.serial(databaseId);
				msgack.serialCont(ack);
				CUnifiedNetwork::getInstance()->send(database->getMappedService(), msgack);
			}
		}

		_NextTimeDelta = tm - (tm%(DeltaUpdateRate*1000)) + (DeltaUpdateRate*1000);

		_LastUpdateTime = endtime;
	}

	CTimestamp	ts;
	ts.setToCurrent();

	// check databases require some delta packing/reference generation
	for (it=_DatabaseMap.begin(); it!=_DatabaseMap.end(); ++it)
	{
		CDatabase*	database = (*it).second;
		database->sendBuildCommands(ts);
	}

	// send messages to RBS if ready
	while (_RBSUp && !_RBSMessages.empty())
	{
		CUnifiedNetwork::getInstance()->send("RBS", *(_RBSMessages.front()));
		delete _RBSMessages.front();
		_RBSMessages.pop_front();
	}

	return true;
}