/** * @author Matija Novak, updated by Dino Laktašić * @brief Temporary function that creates table, and inserts an entry to the system_relation catalog * @param table table name * @param header AK_header of the new table * @param type_segment type of the new segment * @return No return value */ void AK_temp_create_table(char *table, AK_header *header, int type_segment) { AK_PRO; /* do we really need this??? Edited by Elvis Popovic*/ /* AK_block *sys_block = (AK_block *) AK_malloc(sizeof (AK_block)); */ AK_block *sys_block; sys_block = (AK_block *) AK_read_block(1); int startAddress = AK_initialize_new_segment(table, type_segment, header); int num = 8; //insert object_id AK_insert_entry(sys_block, TYPE_INT, &num, 8); //insert table name AK_insert_entry(sys_block, TYPE_VARCHAR, table, 9); //insert start address num = startAddress; AK_insert_entry(sys_block, TYPE_INT, &num, 10); //insert end address num = startAddress + 19; AK_insert_entry(sys_block, TYPE_INT, &num, 11); AK_write_block(sys_block); AK_free(sys_block); AK_EPI; }
/** * @author Mislav Čakarić * @brief Function that updates a bucket in block * @param add address of where the bucket is stored * @param data content of bucket stored in char array * @return No return value */ void Ak_update_bucket_in_block(struct_add *add, char *data) { AK_PRO; AK_block *block = (AK_block*) AK_read_block(add->addBlock); int address = block->tuple_dict[add->indexTd].address; int size = block->tuple_dict[add->indexTd].size; memcpy(&block->data[address], data, size); AK_write_block(block); AK_EPI; }
/** * @author Mislav Čakarić * @brief Function that changes a info of hash index * @param indexName name of index * @param modulo value for modulo hash function * @param main_bucket_num number of main buckets * @param hash_bucket_num number of hash buckets * @return No return value */ void AK_change_hash_info(char *indexName, int modulo, int main_bucket_num, int hash_bucket_num) { AK_PRO; table_addresses *hash_addresses = (table_addresses*) AK_get_index_addresses(indexName); int block_add = hash_addresses->address_from[ 0 ]; if (block_add == 0) { printf("Hash index does not exist!\n"); } AK_block *block = (AK_block*) AK_read_block(block_add); hash_info *info = (hash_info*) AK_malloc(sizeof (hash_info)); info->modulo = modulo; info->main_bucket_num = main_bucket_num; info->hash_bucket_num = hash_bucket_num; memcpy(block->data, info, sizeof (hash_info)); block->tuple_dict[0].address = 0; block->tuple_dict[0].type = INFO_BUCKET; block->tuple_dict[0].size = sizeof (hash_info); AK_write_block(block); AK_EPI; }
/** * @author Mislav Čakarić * @brief Function that inserts a bucket to block * @param indexName name of index * @param data content of bucket stored in char array * @param type type of bucket (MAIN_BUCKET or HASH_BUCKET) * @return address structure with data where the bucket is stored */ struct_add* Ak_insert_bucket_to_block(char *indexName, char *data, int type) { int size, id; AK_PRO; struct_add *add = (struct_add*) AK_malloc(sizeof (struct_add)); add->addBlock = 0; add->indexTd = 0; int adr_to_write = (int) AK_find_AK_free_space(AK_get_index_addresses(indexName)); if (adr_to_write == -1) adr_to_write = (int) AK_init_new_extent(indexName, SEGMENT_TYPE_INDEX); if (adr_to_write == 0){ AK_EPI; return add; } AK_block *block = (AK_block*) AK_read_block(adr_to_write); Ak_dbg_messg(HIGH, INDICES, "insert_bucket_to_block: Position to write (tuple_dict_index) %d\n", adr_to_write); switch (type) { case MAIN_BUCKET: size = sizeof (main_bucket); break; case HASH_BUCKET: size = sizeof (hash_bucket); break; } id = block->last_tuple_dict_id + 1; memcpy(&block->data[block->AK_free_space], data, size); block->tuple_dict[id].address = block->AK_free_space; block->AK_free_space += size; block->tuple_dict[id].type = type; block->tuple_dict[id].size = size; block->last_tuple_dict_id = id; AK_write_block(block); add->addBlock = adr_to_write; add->indexTd = id; AK_EPI; return add; }
/** * @author Matija Šestak * @brief Function that flushes memory blocks to disk file * @return EXIT_SUCCESS */ int AK_flush_cache() { int i = 0; int block_written; AK_block *data_block; AK_PRO; while (i < MAX_CACHE_MEMORY) { if (db_cache->cache[i]->dirty == BLOCK_DIRTY) { data_block = db_cache->cache[i]->block; block_written = AK_write_block(data_block); /// if block form cache can not be writed to DB file -> EXIT_ERROR if (block_written != EXIT_SUCCESS) { AK_EPI; exit(EXIT_ERROR); } } i++; } AK_EPI; return EXIT_SUCCESS; }
/** * @author Tomislav Fotak, updated by Matija Šestak * @brief Function reads a block from memory. If the block is cached returns the cached block. Else uses AK_cache_block to read the block to cache and then returns it. * @param num block number (address) * @return segment start address */ AK_mem_block *AK_get_block(int num) { int i = 0; int min = 0; int pos; int oldest_block = db_cache->next_replace; int second_oldest = 0; int found_in_cache = 0; int first_AK_free_mem_block = -1; int block_written = 0; AK_mem_block *cached_block; AK_block *data_block; AK_PRO; /* search cache for already-cached block */ for (i = 0; i < MAX_CACHE_MEMORY; i++) { if (db_cache->cache[i]->block->address == num) { found_in_cache = 1; pos = i; cached_block = db_cache->cache[i]; break; } } if (!found_in_cache) { //printf("Blok NOT FOUND IN CACHE!\n"); /* find first empty slot in cache for block to be read into */ for (i = 0; i < MAX_CACHE_MEMORY; i++) { if (db_cache->cache[i]->timestamp_read == -1) { first_AK_free_mem_block = i; break; } } if (first_AK_free_mem_block != -1) { if (AK_cache_block(num, db_cache->cache[ first_AK_free_mem_block ]) == EXIT_SUCCESS) { cached_block = db_cache->cache[first_AK_free_mem_block]; printf("USPJEH!\n"); } } else { if (db_cache->cache[oldest_block]->dirty == BLOCK_DIRTY) { data_block = db_cache->cache[oldest_block]->block; block_written = AK_write_block(data_block); /// if block form cache can not be writed to DB file -> EXIT_ERROR if (block_written != EXIT_SUCCESS) { AK_EPI; exit(EXIT_ERROR); } else { //printf("BLOK NIJE ZAPISAN!\n"); } } if (AK_cache_block(num, db_cache->cache[ oldest_block ]) == EXIT_SUCCESS) { cached_block = db_cache->cache[ oldest_block ]; } } } else { if (db_cache->cache[pos]->dirty == BLOCK_DIRTY) { data_block = db_cache->cache[pos]->block; block_written = AK_write_block(data_block); /// if block form cache can not be writed to DB file -> EXIT_ERROR if (block_written != EXIT_SUCCESS) { AK_EPI; exit(EXIT_ERROR); } else { //printf("BLOK NIJE ZAPISAN!\n"); } } } /*i = 1;*/ for (i = 0; i < MAX_CACHE_MEMORY; i++) { if (db_cache->cache[i]->timestamp_read != -1 && db_cache->cache[i]->timestamp_read < db_cache->cache[ min ]->timestamp_read) { min = i; } } //printf("KESANI BLOK %i \n",cached_block); db_cache->next_replace = min; AK_EPI; return cached_block; }