Untitled
unknown
plain_text
5 months ago
5.0 kB
10
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