/*#io
UDBIndex ioDoc(
docCopyright("Steve Dekorte", 2004)
docLicense("BSD revised")
docObject("UDBIndex")
docDescription("")
*/
#include "UDBIndex.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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");
}
syntax highlighted by Code2HTML, v. 0.9.1