⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scorder.cxx

📁 Windows CE 6.0 Server 源码
💻 CXX
📖 第 1 页 / 共 3 页
字号:

			memset (p, 0, sizeof(*p));
			return p;
		}
	}

	if (! AddNewCluster ())
		return NULL;

	return PersistBlock();
}

int ScSequenceCollection::Compact (void) {
	SVSUTIL_ASSERT (gMem->IsLocked());

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_ORDER, L"Compacting %s...\n", lpszBackupName);
#endif

	uiLastCompactT = GetTickCount ();

	int iUsedSeqs = 0;
	for (int i = 0 ; i < (int)uiClustersCount ; ++i)
		iUsedSeqs += SCSEQUENCE_ENTRIES_PER_BLOCK - ppClusters[i]->iNumFree;

	int iDeltaSeqs = SCSEQUENCE_ENTRIES_PER_BLOCK * uiClustersCount - iUsedSeqs;
	if (iDeltaSeqs < (int)(SCSEQUENCE_ENTRIES_PER_BLOCK * uiClustersCount / 3))
		return TRUE;

	if (iDeltaSeqs < SCSEQUENCE_ENTRIES_PER_BLOCK)
		return TRUE;

	//
	//	We will reset the whole structure now...
	//
	unsigned int	l_uiClustersCount = uiClustersCount;
	unsigned int	l_uiClustersAlloc = uiClustersAlloc;

	ScOrderCluster	**l_ppClusters	  = ppClusters;

	ppClusters      = NULL;
	uiClustersCount = 0;

	int fFaulted = FALSE;

	for (i = 0 ; i < SCSEQUENCE_HASH_BUCKETS ; ++i) {
		ScOrderSeq *pSeq = pSeqBuckets[i];

		while (pSeq) {
			SVSUTIL_ASSERT (pSeq->p->uiLastAccessS);

			ScPersistOrderSeq *p = PersistBlock ();
			if (! p) {
				fFaulted = TRUE;
				break;
			}

			*p = *pSeq->p;
			pSeq->p = p;
			pSeq = pSeq->pNextHash;
		}

		if (fFaulted)
			break;
	}

	if (fFaulted) {
		for (i = 0 ; i < (int)uiClustersCount ; ++i)
			g_funcFree (ppClusters[i], g_pvFreeData);

		g_funcFree (ppClusters, g_pvFreeData);

		ppClusters      = l_ppClusters;
		uiClustersCount = l_uiClustersCount;
		uiClustersAlloc = l_uiClustersAlloc;

		return FALSE;
	}

	for (i = 0 ; i < (int)l_uiClustersCount ; ++i)
		g_funcFree (l_ppClusters[i], g_pvFreeData);

	g_funcFree (l_ppClusters, g_pvFreeData);

	return FlushBackup ();
}

int ScSequenceCollection::Prune (void) {
	SVSUTIL_ASSERT (gMem->IsLocked());

#if defined (SC_VERBOSE)
	scerror_DebugOut (VERBOSE_MASK_ORDER, L"Pruning %s...\n", lpszBackupName);
#endif

	uiLastPruneT = GetTickCount ();

	int iChanges = 0;

	unsigned int uiNowS = scutil_now ();

	for (int i = 0 ; i < SCSEQUENCE_HASH_BUCKETS ; ++i) {
		ScOrderSeq *pSeq = pSeqBuckets[i];
		ScOrderSeq *pParentSeq = NULL;

		while (pSeq) {
			SVSUTIL_ASSERT (pSeq->p->uiLastAccessS);

			if (uiNowS - pSeq->p->uiLastAccessS > gMachine->uiSeqTimeout) {
				SVSUTIL_ASSERT (! pSeq->fActive);

				++iChanges;

				if (! pParentSeq)
					pSeqBuckets[i] = pSeq->pNextHash;
				else
					pParentSeq->pNextHash = pSeq->pNextHash;

				int iCluster = FindCluster (pSeq->p);

				SVSUTIL_ASSERT ((iCluster >= 0) && (iCluster < (int)uiClustersCount));
				SVSUTIL_ASSERT ((ppClusters[iCluster]->h.uiFirstFreeBlock < SCSEQUENCE_ENTRIES_PER_BLOCK) || (ppClusters[iCluster]->h.uiFirstFreeBlock == -1));

				ppClusters[iCluster]->iNumFree++;
				ppClusters[iCluster]->iDirty = TRUE;

				pSeq->p->uiLastAccessS = 0;
				pSeq->p->uiCurrentSeqN = ppClusters[iCluster]->h.uiFirstFreeBlock;
				ppClusters[iCluster]->h.uiFirstFreeBlock = pSeq->p - ppClusters[iCluster]->pos;
				
				SVSUTIL_ASSERT (ppClusters[iCluster]->h.uiFirstFreeBlock < SCSEQUENCE_ENTRIES_PER_BLOCK);

				ScOrderSeq *pSeqNext = pSeq->pNextHash;
				svsutil_FreeFixed (pSeq, pfmOrderSeq);
				pSeq = pSeqNext;
				continue;
			}

			pParentSeq = pSeq;
			pSeq = pSeq->pNextHash;
		}
	}

	int iRes = TRUE;

	if (iChanges) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_ORDER, L"Squeezed %d sequences out of %s\n", iChanges, lpszBackupName);
#endif
		iRes = Compact ();
		if (iRes)
			iRes = FlushBackup ();
	}

	PruneStringHash ();

	return iRes;
}

ScSequenceCollection::ScSequenceCollection (void) {
	hBackupFile = INVALID_HANDLE_VALUE;
	hStringFile = INVALID_HANDLE_VALUE;

	lpszBackupName = NULL;
    lpszStringName = NULL;

	uiLastBackupAccessT = uiLastStringAccessT = uiLastCompactT = uiLastPruneT = GetTickCount ();

	uiClustersCount = 0;
	uiClustersAlloc = 0;

	ppClusters = NULL;

	memset (pSeqBuckets, 0, sizeof(pSeqBuckets));
	memset (pGuidBuckets, 0, sizeof(pGuidBuckets));
	memset (pStringBuckets, 0, sizeof(pStringBuckets));

	pSeqActive = NULL;

	pfmOrderSeq = svsutil_AllocFixedMemDescr (sizeof (ScOrderCluster), SCSEQUENCE_BLOCKINCR);

	hSequencePulse = CreateEvent (NULL, FALSE, FALSE, NULL);

	fBusy = 0;
}

ScSequenceCollection::~ScSequenceCollection (void) {
	CloseBackup ();
	CloseStrings ();

	CloseHandle (hSequencePulse);

	if (lpszBackupName)
		g_funcFree (lpszBackupName, g_pvFreeData);

	if (lpszStringName)
		g_funcFree (lpszStringName, g_pvFreeData);

	if (ppClusters) {
		for (int i = 0 ; i < (int)uiClustersCount ; ++i)
			g_funcFree (ppClusters[i], g_pvFreeData);

		g_funcFree (ppClusters, g_pvFreeData);
	}

	svsutil_ReleaseFixedNonEmpty (pfmOrderSeq);

	for (int i = 0 ; i < SCSEQUENCE_HASH_BUCKETS ; ++i) {
		while (pStringBuckets[i]) {
			StringGuidHash *pNext = pStringBuckets[i]->pNextInString;
			g_funcFree (pStringBuckets[i], g_pvFreeData);
			pStringBuckets[i] = pNext;
		}
	}

	memset (pGuidBuckets, 0, sizeof(pGuidBuckets));
}

int ScSequenceCollection::Load (void) {
	WCHAR szBuffer[_MAX_PATH];

	if (FAILED(StringCchPrintfW(szBuffer,_MAX_PATH,L"%s\\" SCSEQUENCE_FILENAME, gMachine->lpszDirName))) {
		SVSUTIL_ASSERT(0);
		return FALSE;
	}

	lpszBackupName = svsutil_wcsdup (szBuffer);
	if (!lpszBackupName)
		return FALSE;

	if (FAILED(StringCchPrintfW(szBuffer,_MAX_PATH,L"%s\\" SCSEQUENCE_FILENAME_STRING, gMachine->lpszDirName))) {
		SVSUTIL_ASSERT(0);
		return FALSE;
	}

	lpszStringName = svsutil_wcsdup (szBuffer);
	if (! lpszStringName)
		return FALSE;

	if (! LoadStringHash ()) {
#if defined (SC_VERBOSE)
		scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't load %s\n", lpszStringName);
#endif
		return FALSE;
	}

	HANDLE hFile = CreateFile (lpszBackupName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, NULL);

	if (hFile == INVALID_HANDLE_VALUE) {
		hFile = CreateFile (lpszBackupName, GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_FLAG_RANDOM_ACCESS, NULL);

		if (hFile == INVALID_HANDLE_VALUE) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't create %s\n", lpszBackupName);
#endif
			return FALSE;
		}

		CloseHandle (hFile);
		return TRUE;
	}

	for ( ; ; ) {
		if (! AddNewCluster()) {
			CloseHandle (hFile);
			return FALSE;
		}

		ScOrderCluster *pCluster = ppClusters[uiClustersCount - 1];

		DWORD dwBytes;

		if ((! ReadFile (hFile, pCluster->ac, sizeof(ppClusters[0]->ac), &dwBytes, NULL)) ||
			(dwBytes != sizeof(ppClusters[0]->ac))) {
			//
			//	Last cluster unused - delete...
			//
			--uiClustersCount;
			g_funcFree (pCluster, g_pvFreeData);
			break;
		}
		//
		//	Check integrity of a file
		//
		if ((pCluster->h.uiMagic1 != SCSEQUENCE_MAGIC1) ||
			(pCluster->h.uiMagic2 != SCSEQUENCE_MAGIC2) ||
			(pCluster->h.uiVersion != SCSEQUENCE_VERSION)) {
#if defined (SC_VERBOSE)
			scerror_DebugOut (VERBOSE_MASK_ORDER, L"File %s corrupted - unrecognized cluster structure\n", lpszBackupName);
#endif
			CloseHandle (hFile);
			return FALSE;
		}

		pCluster->iNumFree = 0;
		pCluster->iDirty   = FALSE;

		int iFreePos = pCluster->h.uiFirstFreeBlock;
		while (iFreePos != -1) {
			if (iFreePos < 0 || iFreePos >= SCSEQUENCE_ENTRIES_PER_BLOCK) {
#if defined (SC_VERBOSE)
				scerror_DebugOut (VERBOSE_MASK_ORDER, L"File %s corrupted - free position %d out of range\n", lpszBackupName, iFreePos);
#endif
				CloseHandle (hFile);
				return FALSE;
			}

			if (pCluster->pos[iFreePos].uiLastAccessS) {
#if defined (SC_VERBOSE)
				scerror_DebugOut (VERBOSE_MASK_ORDER, L"File %s corrupted - free position %d not really free\n", lpszBackupName, iFreePos);
#endif
				CloseHandle (hFile);
				return FALSE;
			}

			++pCluster->iNumFree;

			iFreePos = pCluster->pos[iFreePos].uiCurrentSeqN;
		}

		//
		//	Build hashes...
		//
		int iUsed = 0;

		for (int i = 0 ; i < SCSEQUENCE_ENTRIES_PER_BLOCK ; ++i) {
			if (pCluster->pos[i].uiLastAccessS) {
				++iUsed;

				ScQueueList *pql = gQueueMan->pqlIncoming;

				ScQueue *pQueueLocal = NULL;

				while (pql) {
					if (pql->pQueue->qp.guid == pCluster->pos[i].guidQ) {
						pQueueLocal = pql->pQueue;
						break;
					}

					pql = pql->pqlNext;
				}

				//
				//	Queue or endpoint bindings disappeared since; free the entry
				//
				if ((! pQueueLocal) || (! GetStringFromGUID (&pCluster->pos[i].guidOrderAck)) ||
				                       (! GetStringFromGUID (&pCluster->pos[i].guidQueueName))) {
#if defined (SC_VERBOSE)
					if (! pQueueLocal)
						scerror_DebugOut (VERBOSE_MASK_ORDER, L"Queue for guid " SC_GUID_FORMAT L" had disappeared. \n",
										SC_GUID_ELEMENTS((&(pCluster->pos[i].guidQ))));

					if (! GetStringFromGUID (&pCluster->pos[i].guidOrderAck))
						scerror_DebugOut (VERBOSE_MASK_ORDER, L"Order Ack Queue name for guid " SC_GUID_FORMAT L" had disappeared. \n",
										SC_GUID_ELEMENTS((&(pCluster->pos[i].guidOrderAck))));

					if (! GetStringFromGUID (&pCluster->pos[i].guidOrderAck))
						scerror_DebugOut (VERBOSE_MASK_ORDER, L"Queue name for guid " SC_GUID_FORMAT L" had disappeared. \n",
										SC_GUID_ELEMENTS((&(pCluster->pos[i].guidQueueName))));

					scerror_DebugOut (VERBOSE_MASK_ORDER, L"Element at position %d in cluster %d is now freed\n", i, uiClustersCount);
#endif
					--iUsed;
					++pCluster->iNumFree;

					pCluster->iDirty = TRUE;

					pCluster->pos[i].uiLastAccessS = 0;
					pCluster->pos[i].uiCurrentSeqN = pCluster->h.uiFirstFreeBlock;

					pCluster->h.uiFirstFreeBlock = i;

					continue;
				}

				SVSUTIL_ASSERT (pQueueLocal->qp.bIsIncoming && pQueueLocal->qp.bTransactional);

				ScOrderSeq *pSeq = (ScOrderSeq *)svsutil_GetFixed (pfmOrderSeq);

				if (! pSeq) {
#if defined (SC_VERBOSE)
					scerror_DebugOut (VERBOSE_MASK_ORDER, L"Can't get sequence - no memory\n");
#endif
					CloseHandle (hFile);
					return FALSE;
				}

				int iPos = Hash (&pCluster->pos[i].guidStreamId, &pCluster->pos[i].guidQueueName);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -