# $Id: heap.m,v 1.2 2001/06/27 20:52:57 ksb Exp $ # the heap of misery -- files to be deleted require "util_ppm.m" %i typedef struct THnode { char *pcdir; char *pcfile; int iweight; } TRASH_HEAP; static void HeapDump(FILE *); extern int HeapInsert(char*, char*, int); extern int HeapDequeue(char **, char **, int *); #if !defined(TRASH_CAN_SIZE) #define TRASH_CAN_SIZE 8192 #endif %% init 'util_ppm_init(& PPMTrash, sizeof(TRASH_HEAP), TRASH_CAN_SIZE);' %c static int iTrashCur = 0; static PPM_BUF PPMTrash; /* debug routine to output the heap (ksb) */ static void HeapOut(FILE *fp, int iDeep, int iDx, TRASH_HEAP *pTRCur) { register int i; printf("%*.*s", iDeep, iDeep, " "); if (iDx >= iTrashCur) { printf(".\n"); return; } fprintf(fp, "%s/%s <%d>\n", pTRCur[iDx].pcdir, pTRCur[iDx].pcfile, pTRCur[iDx].iweight); i = 2*(iDx+1)-1; if (i < iTrashCur) { HeapOut(fp, iDeep+1, i, pTRCur); HeapOut(fp, iDeep+1, i+1, pTRCur); } } static void HeapDump(FILE *fp) { HeapOut(fp, 0, 0, util_ppm_size(& PPMTrash, 0)); } /* put the heap back in heap order (ksb) */ int HeapDrop(pTRHeap, iDrop) TRASH_HEAP *pTRHeap; int iDrop; { register int iPar; auto TRASH_HEAP THSwap; for (/* param */; iDrop > 0; iDrop = iPar) { iPar = (iDrop-1)/2; if (pTRHeap[iDrop].iweight <= pTRHeap[iPar].iweight) { break; } THSwap = pTRHeap[iPar]; pTRHeap[iPar] = pTRHeap[iDrop]; pTRHeap[iDrop] = THSwap; } return 1; } /* put this in the heap of misery (ksb) */ int HeapInsert(pcDir, pcFile, iWeight) char *pcDir, *pcFile; int iWeight; { register TRASH_HEAP *pTRList, *pTREnd; register int i; static char *pcLastDir = (char *)0; i = iTrashCur++; if ((TRASH_HEAP *)0 == (pTRList = util_ppm_size(& PPMTrash, iTrashCur))) { return 0; } pTREnd = & pTRList[i]; if ((char *)0 == pcLastDir || 0 != strcmp(pcLastDir, pcDir)) { pcLastDir = strdup(pcDir); } pTREnd->pcdir = pcLastDir; pTREnd->pcfile = strdup(pcFile); pTREnd->iweight = iWeight; return HeapDrop(pTRList, i); } /* Find the next contestant (ksb) * return false when we don't have one. */ int HeapDequeue(ppcDir, ppcFile, piWeight) char **ppcDir, **ppcFile; int *piWeight; { register TRASH_HEAP *pTRCur, *pTRList; register int iLeft, iRight; if (0 == iTrashCur || (TRASH_HEAP *)0 == (pTRList = util_ppm_size(& PPMTrash, 0))) { return 0; } pTRCur = pTRList; *ppcDir = pTRCur->pcdir; *ppcFile = pTRCur->pcfile; *piWeight = pTRCur->iweight; iLeft = 1, iRight = 2; pTRCur->iweight = -1; /* inv.: empty slot at pTRCur, kids at iLeft and maybe iRight * fill this slot, find next slot. */ while (iLeft < iTrashCur) { if (iRight < iTrashCur && pTRList[iRight].iweight >= pTRList[iLeft].iweight) { iLeft = iRight; } pTRCur->pcdir = pTRList[iLeft].pcdir; pTRCur->pcfile = pTRList[iLeft].pcfile; pTRCur->iweight = pTRList[iLeft].iweight; pTRCur = & pTRList[iLeft]; iRight = (iLeft + 1)*2; iLeft = iRight-1; } if (pTRCur == & pTRList[--iTrashCur]) { return 1; } pTRCur->pcdir = pTRList[iTrashCur].pcdir; pTRCur->pcfile = pTRList[iTrashCur].pcfile; pTRCur->iweight = pTRList[iTrashCur].iweight; return HeapDrop(pTRList, pTRCur-pTRList); } %%