Untitled
unknown
plain_text
a year ago
5.0 kB
14
Indexable
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define GET_BLOCK_INFO(block) (HP_block_info *) ((block) + (BF_BLOCK_SIZE - sizeof(HP_block_info)))
#include "bf.h"
#include "hp_file.h"
#include "record.h"
#define CALL_BF(call) \
{ \
BF_ErrorCode code = call; \
if (code != BF_OK) { \
BF_PrintError(code); \
return HP_ERROR; \
} \
}
int HP_CreateFile(char *fileName) {
int fd1;
void *data = NULL;
CALL_BF(BF_CreateFile(fileName))
CALL_BF(BF_OpenFile(fileName, &fd1));
BF_Block *block;
BF_Block_Init(&block);
CALL_BF(BF_AllocateBlock(fd1, block));
data = BF_Block_GetData(block);
HP_block_info* hpBlockInfo = GET_BLOCK_INFO(data);
hpBlockInfo->num_records = 0;
hpBlockInfo->next_block = -1;
HP_info* info = data;
info->last_free_block_id = 0; //initializing value, no blocks inserted
info->block_record_capacity = (BF_BLOCK_SIZE - sizeof(HP_block_info)) / sizeof(Record);
info->first_block_record_capacity = (BF_BLOCK_SIZE - sizeof(HP_block_info) - sizeof(HP_info)) / sizeof(Record);
BF_Block_SetDirty(block);
CALL_BF(BF_UnpinBlock(block));
CALL_BF(BF_CloseFile(fd1));
return 0;
}
HP_info* HP_OpenFile(char *fileName, int *file_desc){
HP_info* hpInfo;
BF_Block *block;
BF_Block_Init(&block);
BF_OpenFile(fileName, file_desc);
BF_GetBlock(*file_desc, 0, block);
void *data = BF_Block_GetData(block);
hpInfo = (HP_info *) malloc(sizeof(HP_info));
memcpy(hpInfo, data, sizeof(HP_info));
return hpInfo;
}
int HP_CloseFile(int file_desc, HP_info* hp_info) {
free(hp_info);
CALL_BF(BF_CloseFile(file_desc));
return 0;
}
static int allocate_new_block(int file_desc, HP_info *hp_info, BF_Block *old_block, BF_Block** ret_block) {
BF_Block* new_block;
BF_Block_Init(&new_block);
CALL_BF(BF_AllocateBlock(file_desc, new_block));
int blocks_num;
CALL_BF(BF_GetBlockCounter(file_desc, &blocks_num));
hp_info->last_free_block_id = blocks_num - 1;
void* old_block_data = BF_Block_GetData(old_block);
HP_block_info *old_block_info = GET_BLOCK_INFO(old_block_data);
old_block_info->next_block = blocks_num -1;
BF_Block_SetDirty(old_block);
CALL_BF(BF_UnpinBlock(old_block));
void* new_block_data = BF_Block_GetData(new_block);
HP_block_info* new_block_info = GET_BLOCK_INFO(new_block_data);
new_block_info->num_records = 0;
new_block_info->next_block= -1;
*ret_block = new_block;
return 0;
}
static int insert_record_to_block(BF_Block *block, Record record, uint32_t offset) {
void* block_data = BF_Block_GetData(block);
HP_block_info *block_info = GET_BLOCK_INFO(block_data);
void *record_data = block_data + offset + block_info->num_records * sizeof(Record);
memcpy(record_data, &record, sizeof(Record));
block_info->num_records += 1;
BF_Block_SetDirty(block);
CALL_BF(BF_UnpinBlock(block));
return 0;
}
int HP_InsertEntry(int file_desc, HP_info* hp_info, Record record) {
BF_Block* block;
BF_Block_Init(&block);
if (hp_info == NULL) {
fprintf(stderr, "info was not found\n");
return -1;
}
CALL_BF(BF_GetBlock(file_desc, hp_info->last_free_block_id, block));
void* block_data = BF_Block_GetData(block);
HP_block_info *block_info = GET_BLOCK_INFO(block_data);
uint32_t record_capacity, offset;
if (hp_info->last_free_block_id == 0) {
record_capacity = hp_info->first_block_record_capacity;
// HP_info is stored in the beginning of the first block so we have to account for it.
offset = sizeof(HP_info);
} else {
record_capacity = hp_info->block_record_capacity;
offset = 0;
}
if (block_info->num_records < record_capacity) {
insert_record_to_block(block, record, offset);
} else {
BF_Block* new_block;
int err = allocate_new_block(file_desc, hp_info, block, &new_block);
if (err != 0) {
return err;
}
err = insert_record_to_block(new_block, record, 0);
if (err != 0) {
return err;
}
}
return hp_info->last_free_block_id;
}
int HP_GetAllEntries(int file_desc, HP_info* hp_info, int value) {
BF_Block *block;
BF_Block_Init(&block);
for (int i = 0; i != -1 ;) {
CALL_BF(BF_GetBlock(file_desc, i, block));
void *data = BF_Block_GetData(block);
HP_block_info* block_info = GET_BLOCK_INFO(data);
if (i == 0) data += sizeof(HP_info);
for (int j = 0; j < block_info->num_records; j++) {
Record record;
memcpy(&record, data + j * sizeof(Record), sizeof(Record));
if (record.id == value)
printRecord(record);
}
i = block_info->next_block;
CALL_BF(BF_UnpinBlock(block));
}
return 0;
}
Editor is loading...
Leave a Comment