Esempio n. 1
0
void UDBIndex_finishOpening(UDBIndex *self)
{
	JFile_begin(self->file);
	UDBIndex_setPos_forPid_(self, 0, 0);
	UDBIndex_preCommit(self);
	UDBIndex_findHoles(self);
}
Esempio n. 2
0
void UDB_append_withPid_(UDB *self, Datum d, PID_TYPE pid) 
{
	UDBRecord *record = UDBRecords_newRecord(self->records);
	UDBRecord_pid_(record, pid);
	UDBRecord_saveWithDatum_(record, d);
	UDBIndex_setPos_forPid_(self->index, UDBRecord_pos(record), pid);
}
Esempio n. 3
0
File: UDB.c Progetto: argv0/skipdb
void UDB_removeAt_(UDB *self, PID_TYPE pid)
{
	if (UDB_isInTransaction(self))
	{
		UDBRecord *record = UDB_recordAtPid_(self, pid);
		
		if (!record)
		{
			printf("UDB error: missing record with pid %" PID_FORMAT " for remove\n", pid);
			record = UDB_recordAtPid_(self, pid);
			return;
		}
		
		UDBRecords_removeRecord_(self->records, record);
		UDBIndex_setPos_forPid_(self->index, 0, pid);
	}
}
Esempio n. 4
0
int UDB_compactStepFor_(UDB *self, double maxSeconds)
{   
	UDBRecord *firstEmptyRecord = UDBRecords_firstEmptyRecord(self->records);
	
	if (!firstEmptyRecord)
	{
		return 0;
	}
	
	if (!UDBRecord_isEmpty(firstEmptyRecord))
	{
		printf("firstEmptyRecord not empty!\n");
		firstEmptyRecord = UDBRecords_firstEmptyRecord(self->records);
		UDBRecord_isEmpty(firstEmptyRecord);
		exit(1);
	}
	
#ifdef DEBUG
	printf("empty record pid: %i pos: %i size: %i isEmpty: %i\n", 
		  UDBRecord_pid(firstEmptyRecord), 
		  UDBRecord_pos(firstEmptyRecord), 
		  UDBRecord_totalSize(firstEmptyRecord), 
		  UDBRecord_isEmpty(firstEmptyRecord));
#endif
	    
	if (firstEmptyRecord)
	{
		UDBRecord *record = UDBRecords_recordAfter_(self->records, firstEmptyRecord);
		
		if (!record)
		{
			// reached end of file 
			PID_TYPE size = UDBRecord_pos(firstEmptyRecord);
			UDBRecords_truncate_(self->records, size);
			return 0;
		}
		
#ifdef DEBUG
		printf("next  record pid: %i pos: %i size: %i isEmpty: %i\n\n", 
			  UDBRecord_pid(record), 
			  UDBRecord_pos(record), 
			  UDBRecord_totalSize(record), 
			  UDBRecord_isEmpty(record));
#endif
		
		UDB_beginTransaction(self);
		
		if (UDBRecord_isEmpty(record))
		{
			// coalese this empty record into the first empty record 
			PID_TYPE newSize = UDBRecord_totalSize(firstEmptyRecord) 
			- sizeof(UDBRecordHeader) + UDBRecord_totalSize(record);
			UDBRecord_size_(firstEmptyRecord, newSize);
			UDBRecord_saveHeader(firstEmptyRecord);
#ifdef DEBUG
			printf("merge\n");
#endif
			UDBIndex_setPos_forPid_(self->index, 0, UDBRecord_pid(record));
		}
		else
		{
			// swap places with the first empty record 
			PID_TYPE oldEmptyPos = UDBRecord_pos(firstEmptyRecord);
			PID_TYPE newEmptyPos = oldEmptyPos + UDBRecord_totalSize(record);
			UDBRecords_firstEmptyRecordPos_(self->records, newEmptyPos);
			UDBRecord_moveToPos_(record, UDBRecord_pos(firstEmptyRecord));
			UDBRecord_setPos_(firstEmptyRecord, newEmptyPos);
			UDBRecord_saveHeader(firstEmptyRecord);
#ifdef DEBUG
			printf("move\n");
#endif
			UDBIndex_setPos_forPid_(self->index, newEmptyPos, UDBRecord_pid(firstEmptyRecord));
			UDBIndex_setPos_forPid_(self->index, oldEmptyPos, UDBRecord_pid(record));
		}
		
		UDB_commitTransaction(self);
		
		return 1;
	}
	return 0;
}