📄 scorder.cxx
字号:
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 + -