/*#io UDBIndex ioDoc( docCopyright("Steve Dekorte", 2004) docLicense("BSD revised") docObject("UDBIndex") docDescription("") */ #include "UDBIndex.h" #include #include #include UDBIndex *UDBIndex_new(void) { UDBIndex *self = (UDBIndex *)calloc(1, sizeof(UDBIndex)); self->file = JFile_new(); UDBIndex_setPath_(self, "default"); self->holes = List_new(); return self; } void UDBIndex_free(UDBIndex *self) { UDBIndex_close(self); JFile_free(self->file); List_free(self->holes); free(self); } JFile *UDBIndex_jfile(UDBIndex *self) { return self->file; } void UDBIndex_delete(UDBIndex *self) { JFile_close(self->file); JFile_delete(self->file); } void UDBIndex_setPath_(UDBIndex *self, const char *path) { JFile_setPath_withExtension_(self->file, path, "udbIndex"); } void UDBIndex_setLogPath_(UDBIndex *self, const char *s) { JFile_setLogPath_(self->file, s); } char *UDBIndex_path(UDBIndex *self) { return JFile_path(self->file); } void UDBIndex_open(UDBIndex *self) { JFile_openWithoutCommitCompletion(self->file); // need to also call UDBIndex_finishOpening UDBIndex_finishOpening(self); self->maxPid = 0; } void UDBIndex_finishOpening(UDBIndex *self) { JFile_begin(self->file); UDBIndex_setPos_forPid_(self, 0, 0); UDBIndex_commit(self); UDBIndex_findHoles(self); } void UDBIndex_close(UDBIndex *self) { JFile_close(self->file); } void UDBIndex_begin(UDBIndex *self) { JFile_begin(self->file); } void UDBIndex_commit(UDBIndex *self) { JFile_commit(self->file); } int UDBIndex_isCommitted(UDBIndex *self) { return JFile_isCommitted(self->file); } // holes ------------------------------------------- void UDBIndex_findHoles(UDBIndex *self) { PID_TYPE pid = UDBIndex_pidCount(self); List_removeAll(self->holes); while (pid --) { if (!UDBIndex_posForPid_(self, pid)) { List_push_(self->holes, (void *)pid); } } } // pid ops ------------------------------------------- PID_TYPE UDBIndex_nextPid(UDBIndex *self) { PID_TYPE hole = (PID_TYPE)List_top(self->holes); if (hole) { return hole; } return JFile_setPositionToEnd(self->file) / sizeof(UDBIndexEntry); } PID_TYPE UDBIndex_allocPid(UDBIndex *self) { PID_TYPE hole = (PID_TYPE)List_pop(self->holes); if (hole) { return hole; } else { PID_TYPE max = JFile_setPositionToEnd(self->file) / sizeof(UDBIndexEntry); if (max > self->maxPid) { self->maxPid = max; } else { self->maxPid ++; } return self->maxPid; } } PID_TYPE UDBIndex_posForPid_(UDBIndex *self, PID_TYPE pid) { UDBIndexEntry entry; JFile_setPosition_(self->file, pid * sizeof(UDBIndexEntry)); //#ifdef JFILE_SUPPORTS_MMAP //JFile_mmapfread(self->file, (unsigned char *)(&pos), sizeof(UDBIndexEntry), 1); //#else JFile_fread(self->file, (unsigned char *)(&entry), sizeof(UDBIndexEntry), 1); //#endif return entry.pos; } void UDBIndex_setPos_forPid_(UDBIndex *self, PID_TYPE pos, PID_TYPE pid) { UDBIndexEntry entry; entry.pos = pos; //entry.size = 0; JFile_setPosition_(self->file, pid * sizeof(UDBIndexEntry)); JFile_fwrite(self->file, (unsigned char *)(&entry), sizeof(UDBIndexEntry), 1); if (pos == 0) { List_push_(self->holes, (void *)pid); } } long UDBIndex_pidCount(UDBIndex *self) { return JFile_setPositionToEnd(self->file) / sizeof(UDBIndexEntry); } void UDBIndex_show(UDBIndex *self) { PID_TYPE pid, maxPid = UDBIndex_pidCount(self); printf("UDBIndex: (pid/pos)\n\n"); for (pid = 0; pid < maxPid; pid ++) { PID_TYPE pos = UDBIndex_posForPid_(self, pid); printf(" %i -> %i\n", (int)pid, (int)pos); } printf("\n"); }