/** * @author Markus Schatten, Matija Šestak(revised) * @brief Function initializes the global cache memory (variable db_cache) * @return EXIT_SUCCESS if the cache memory has been initialized, EXIT_ERROR otherwise */ int AK_cache_AK_malloc() { int i; AK_PRO; if ((db_cache = (AK_db_cache *) AK_malloc(sizeof(AK_db_cache))) == NULL) { AK_EPI; return EXIT_ERROR; } db_cache->next_replace = 0; for (i = 0; i < MAX_CACHE_MEMORY; i++) { db_cache->cache[ i ] = (AK_mem_block *) AK_malloc(sizeof(AK_mem_block)); db_cache->cache[ i ]->block = (AK_block *) AK_malloc(sizeof(AK_block)); if ((AK_cache_block(i, db_cache->cache[ i ])) == EXIT_ERROR) { AK_EPI; return EXIT_ERROR; } //printf( "Cached block %d with address %d\n", i, &db_cache->cache[ i ]->block->address ); } AK_EPI; return EXIT_SUCCESS; }
/** * @author Dejan Sambolić updated by Dražen Bandić * @brief Function initializes the global redo log memory (variable redo_log) * @return EXIT_SUCCESS if the redo log memory has been initialized, EXIT_ERROR otherwise */ int AK_redo_log_AK_malloc() { AK_PRO; if ((redo_log = (AK_redo_log *) AK_malloc(sizeof ( AK_redo_log))) == NULL) { AK_EPI; return EXIT_ERROR; } redo_log->number = 0; redo_log->table_name = AK_malloc(MAX_REDO_LOG_ENTRIES * sizeof(char*)); redo_log->command = AK_malloc(MAX_REDO_LOG_ENTRIES * sizeof(char*)); redo_log->attributes = AK_malloc(MAX_REDO_LOG_ENTRIES * sizeof(char*)); int i = 0; for (i = 0; i < MAX_REDO_LOG_ENTRIES; i++) { redo_log->table_name[i] = AK_calloc(MAX_VARCHAR_LENGTH, sizeof(char)); redo_log->command[i] = AK_calloc(MAX_VARCHAR_LENGTH, sizeof(char)); redo_log->attributes[i] = AK_calloc(MAX_VARCHAR_LENGTH, sizeof(char)); } AK_EPI; return EXIT_SUCCESS; }
/** * @author Samuel Picek * @brief Function for retrieving large objects * @return returns 0 for true and 1 for false */ int AK_lo_export(char *oid, char *filepath) { printf("-----------------------------------------------------------------\n"); printf("[INFO] EXPORTING\n"); printf("-----------------------------------------------------------------\n"); AK_File_Metadata metadata = AK_read_metadata(oid); char *destination_name = (char) AK_malloc(sizeof(char) * 128); char *destination_path = (char) AK_malloc(sizeof(char) * 512); AK_split_path_file(&destination_path, &destination_name, filepath); if (metadata != 0x0) { if ( AK_copy(metadata->new_path, filepath) == 0 ) { printf("[INFO] File exported successfully.\n"); } else { printf("[INFO] There was an error exporting a file.\n"); } } else { return -1; } return 0; }
/** * @author Matija Šestak. * @brief Function that converts tuple value to string * @param *tuple tuple in the list * @return tuple value as a string */ char * AK_tuple_to_string(struct list_node *tuple) { int temp_int; float temp_float; char temp_char[ MAX_VARCHAR_LENGTH ]; AK_PRO; char *buff = (char*) AK_malloc(MAX_VARCHAR_LENGTH); //assert(tuple->type); switch (tuple->type) { case TYPE_INT: memcpy(&temp_int, tuple->data, tuple->size); sprintf(buff, "%d", temp_int); AK_EPI; return buff; break; case TYPE_FLOAT: memcpy(&temp_float, tuple->data, tuple->size); sprintf(buff, "%f", temp_float); AK_EPI; return buff; break; case TYPE_VARCHAR: memcpy(temp_char, tuple->data, tuple->size); temp_char[ tuple->size ] = '\0'; sprintf(buff, "%s", temp_char); AK_EPI; return buff; break; } AK_free(buff); AK_EPI; return NULL; }
/** * @author Frane Jakelić * @brief Function that adds an element to the doubly linked list. * @param blockAddress integer representation of memory address. * @param type of lock issued to the provided memory address. * @return pointer to the newly created doubly linked element. */ AK_transaction_elem_P AK_add_hash_entry_list(int blockAddress, int type) { AK_PRO; AK_transaction_elem_P root = AK_search_existing_link_for_hook(blockAddress); AK_transaction_elem_P bucket; if(root){ AK_EPI; return root; } root = AK_search_empty_link_for_hook(blockAddress); if(!root->nextBucket){ bucket = root; root->nextBucket = root; root->prevBucket = root; }else{ bucket = (AK_transaction_elem_P) AK_malloc(sizeof (AK_transaction_elem)); memset(bucket, 0, sizeof (AK_transaction_elem)); bucket->nextBucket = root; bucket->prevBucket = root->prevBucket; (*root->prevBucket).nextBucket = bucket; root->prevBucket = bucket; } bucket->address = blockAddress; bucket->lock_type = type; bucket->observer_lock = AK_init_observer_lock(); AK_transaction_register_observer(observable_transaction, bucket->observer_lock->observer); AK_EPI; return bucket; }
/** * @author Krunoslav Bilić * @brief Function for selection operator testing * */ void AK_op_selection_test2() { AK_PRO; printf("\n********** SELECTION TEST 2**********\n"); struct list_node *expr = (struct list_node *) AK_malloc(sizeof(struct list_node)); Ak_Init_L3(&expr); char *srcTable = "student"; char *destTable = "selection_test2"; char num = 23; strcpy(expr->table,destTable); Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "year", sizeof ("year"), expr); Ak_InsertAtEnd_L3(TYPE_INT, &num, sizeof (int), expr); Ak_InsertAtEnd_L3(TYPE_OPERATOR, ">", sizeof (">"), expr); Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr); Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Mislav", sizeof ("Mislav"), expr); Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr); Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr); printf("\nQUERY: SELECT * FROM student WHERE year > 2023 OR firstname = 'Mislav';\n\n"); AK_selection(srcTable, destTable, expr); //AK_print_table("selection_test"); Ak_DeleteAll_L3(&expr); AK_free(expr); AK_EPI; }
/** * @author Mislav Čakarić * @brief Function that fetches nth main bucket * @param indexName name of index * @param n number of main bucket * @return address structure with data where the bucket is stored */ struct_add* Ak_get_nth_main_bucket_add(char *indexName, int n) { int i = 0, j = 0, k = 0, counter = 0, end = 0; AK_PRO; struct_add *add = (struct_add*) AK_malloc(sizeof (struct_add)); add->addBlock = 301; add->indexTd = 2; table_addresses *addresses = (table_addresses*) AK_get_index_addresses(indexName); while (addresses->address_from[i]) { for (j = addresses->address_from[i]; j < addresses->address_to[i]; j++) { AK_block *temp = (AK_block*) AK_read_block(j); for (k = 0; k < DATA_BLOCK_SIZE; k++) { if (temp->tuple_dict[k].type == FREE_INT) break; if (temp->tuple_dict[k].type == MAIN_BUCKET) { if (n == counter) { add->addBlock = j; add->indexTd = k; end = 1; break; } counter++; } } if (end) break; } i++; } AK_EPI; return add; AK_free(add); }
/** * @author Frane Jakelić * @brief Function that adds an element to the locks doubly linked list. * @param memoryAddress integer representation of memory address. * @param type of lock issued to the provided memory address. * @param transactionId integer representation of transaction id. * @return pointer to the newly created Locks doubly linked element. */ AK_transaction_lock_elem_P AK_add_lock(AK_transaction_elem_P HashList, int type, pthread_t transactionId) { AK_PRO; AK_transaction_lock_elem_P root = HashList->DLLLocksHead; AK_transaction_lock_elem_P lock = (AK_transaction_lock_elem_P) AK_malloc(sizeof (AK_transaction_lock_elem)); memset(lock, 0, sizeof (AK_transaction_lock_elem)); if (!root) { HashList->DLLLocksHead = lock; lock->prevLock = lock; lock->nextLock = lock; } else { lock->nextLock = root; lock->prevLock = root->prevLock; (*root->prevLock).nextLock = lock; root->prevLock = lock; } lock->TransactionId = transactionId; lock->lock_type = type; lock->isWaiting = AK_isLock_waiting(HashList, type, transactionId, lock); AK_EPI; return lock; }
/** * @author Samuel Picek * @brief Function for generating GUID * @return returns globaly universal identifier based on kernel implementation */ char *AK_GUID() { srand (clock()); char *GUID = (char*) AK_malloc(sizeof(char) * 40); int t = 0; char *szTemp = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"; char *szHex = "0123456789ABCDEF-"; int nLen = strlen (szTemp); for (t = 0; t < nLen + 1; t++) { int r = rand () % 16; char c = ' '; switch (szTemp[t]) { case 'x' : { c = szHex [r]; } break; case 'y' : { c = szHex [r & 0x03 | 0x08]; } break; case '-' : { c = '-'; } break; case '4' : { c = '4'; } break; } GUID[t] = ( t < nLen ) ? c : 0x00; } return GUID; }
/** * @author Frane Jakelić * @brief Function that appends all addresses affected by the transaction * @param addressList pointer to the linked list where the addresses are stored. * @param tblName table name used in the transaction * @return OK or NOT_OK based on the success of the function. */ int AK_get_memory_blocks(char *tblName, AK_memoryAddresses_link addressList) { AK_PRO; table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName); if (addresses->address_from[0] == 0){ AK_EPI; return NOT_OK; } if (addressList->nextElement != NULL) { addressList->nextElement = NULL; } int i = 0, j; AK_memoryAddresses_link tmp = addressList; for (j = addresses->address_from[ i ]; j < addresses->address_to[ i ]; j++) { tmp->adresa = j; tmp->nextElement = (AK_memoryAddresses_link) AK_malloc(sizeof(struct memoryAddresses)); memset(tmp->nextElement, 0, sizeof (struct memoryAddresses)); tmp = tmp->nextElement; } AK_EPI; return OK; }
/** * @author Matija Šestak. * @brief Function that fetches all values in some column and put on the list * @param num zero-based column index * @param *tblName table name * @return column values list */ struct list_node *AK_get_column(int num, char *tblName) { AK_PRO; int num_attr = AK_num_attr(tblName); if (num >= num_attr || num < 0){ AK_EPI; return NULL; } struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&row_root); table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName); int i, j, k; char data[ MAX_VARCHAR_LENGTH ]; i = 0; while (addresses->address_from[i] != 0) { for (j = addresses->address_from[i]; j < addresses->address_to[i]; j++) { AK_mem_block *temp = (AK_mem_block*) AK_get_block(j); if (temp->block->last_tuple_dict_id == 0) break; for (k = num; k < DATA_BLOCK_SIZE; k += num_attr) { if (temp->block->tuple_dict[k].type != FREE_INT) { int type = temp->block->tuple_dict[k].type; int size = temp->block->tuple_dict[k].size; int address = temp->block->tuple_dict[k].address; memcpy(data, &(temp->block->data[address]), size); data[ size ] = '\0'; Ak_InsertAtEnd_L3(type, data, size, row_root); } } } i++; } AK_EPI; return row_root; }
/** * @author Dino Laktašić. * @brief Function for filtering and returning attributes from condition * @param *cond condition array that contains condition data * @result pointer to array that contains attributes for a given condition */ char *AK_rel_eq_cond_attributes(char *cond) { int next_chr = 0; int next_address = 0; int attr_end = -1; AK_PRO; if (cond == NULL) { AK_EPI; return NULL; } char *temp_cond = (char *) AK_malloc(strlen(cond)); memcpy(temp_cond, cond, strlen(cond)); char *attr = (char *) AK_malloc(sizeof (char)); while (next_chr < strlen(cond)) { if (temp_cond[next_chr] == ATTR_ESCAPE) { next_chr++; if (++attr_end) { attr_end = -1; } else { if (next_address > 0) { memcpy(attr + next_address++, ATTR_DELIMITER, 1); attr = (char *) AK_realloc(attr, next_address + 1); } } } if (!attr_end) { memcpy(attr + next_address++, &temp_cond[next_chr], 1); attr = (char *) AK_realloc(attr, next_address + 1); } next_chr++; } AK_free(temp_cond); if (next_address > 0) { memcpy(attr + next_address, "\0", 1); AK_EPI; return attr; } else { AK_free(attr); AK_EPI; return NULL; } }
//TODO: Add description of the function AK_create_table_parameter* AK_create_create_table_parameter(int type, char* name) { AK_PRO; AK_create_table_parameter* par = AK_malloc(sizeof (AK_create_table_parameter)); par->type = type; strcpy(par->name, name); AK_EPI; return par; }
/** * @author Matija Šestak. * @brief Function that fetches a value in some row and column * @param row zero-based row index * @param column zero-based column index * @param *tblName table name * @return value in the list */ struct list_node *AK_get_tuple(int row, int column, char *tblName) { AK_PRO; int num_rows = AK_get_num_records(tblName); int num_attr = AK_num_attr(tblName); if (row >= num_rows || column >= num_attr){ AK_EPI; return NULL; } table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName); struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&row_root); int i, j, k, counter; char data[ MAX_VARCHAR_LENGTH ]; i = 0; counter = -1; while (addresses->address_from[ i ] != 0) { for (j = addresses->address_from[ i ]; j < addresses->address_to[ i ]; j++) { AK_mem_block *temp = (AK_mem_block*) AK_get_block(j); if (temp->block->last_tuple_dict_id == 0) break; for (k = 0; k < DATA_BLOCK_SIZE; k += num_attr) { if (temp->block->tuple_dict[k].size > 0) counter++; if (counter == row) { struct list_node *next; int type = temp->block->tuple_dict[ k + column ].type; int size = temp->block->tuple_dict[ k + column ].size; int address = temp->block->tuple_dict[ k + column ].address; memcpy(data, &(temp->block->data[address]), size); data[ size ] = '\0'; Ak_InsertAtEnd_L3(type, data, size, row_root); AK_free(addresses); next = Ak_First_L2(row_root); //store next AK_free(row_root); //now we can free base AK_EPI; //returns next in row_root leaving base of the list allocated, so we made some corrections //return (struct list_node *) Ak_First_L2(row_root); return next; //returns next } } } i++; } AK_free(addresses); Ak_DeleteAll_L3(&row_root); AK_free(row_root); AK_EPI; return NULL; }
/** * @author Unknown * @brief Function for inserting a new element into linked list * @param addBlock address block * @param indexTd index table destination * @param *attname attribute name * @param elementBefore address of the node after which the new node will be inserted * @return No return value * */ void Ak_Insert_NewelementAd(int addBlock, int indexTd, char *attName, element_ad elementBefore) { AK_PRO; list_structure_ad* newelement_op = (list_structure_ad*)AK_malloc(sizeof (list_structure_ad)); newelement_op->add.addBlock = addBlock; newelement_op->add.indexTd = indexTd; newelement_op->attName = attName; newelement_op->next = elementBefore->next; elementBefore->next = (list_structure_ad*)newelement_op; AK_EPI; }
/** * @author Matija Šestak, updated by Dino Laktašić,Nikola Miljancic * @brief Function for selection operator testing * */ void AK_op_selection_test() { AK_PRO; printf("\n********** SELECTION TEST **********\n"); struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&expr); char *srcTable = "student"; char *destTable = "selection_test"; int num = 2010; strcpy(expr->table,destTable); Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "year", sizeof ("year"), expr); Ak_InsertAtEnd_L3(TYPE_INT, &num, sizeof (int), expr); Ak_InsertAtEnd_L3(TYPE_OPERATOR, ">", sizeof (">"), expr); Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr); Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Robert", sizeof ("Robert"), expr); Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr); //Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr); Ak_InsertAtEnd_L3( TYPE_OPERATOR, "AND", sizeof("AND"), expr ); printf("\nQUERY: SELECT * FROM student WHERE year > 2010 AND firstname = 'Robert';\n\n"); AK_selection(srcTable, destTable, expr); Ak_DeleteAll_L3(&expr); AK_free(expr); struct list_node *expr1 = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&expr1); char *srcTable1 = "student"; char *destTable1 = "selection_test1"; float weight = 83.750; strcpy(expr1->table,destTable1); Ak_InsertAtEnd_L3( TYPE_ATTRIBS, "weight", sizeof("weight"), expr1 ); Ak_InsertAtEnd_L3( TYPE_FLOAT, &weight, sizeof(float), expr1 ); Ak_InsertAtEnd_L3( TYPE_OPERATOR, ">", sizeof(">"), expr1 ); Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "firstname", sizeof ("firstname"), expr1); Ak_InsertAtEnd_L3(TYPE_VARCHAR, "Dino", sizeof ("Robert"), expr1); Ak_InsertAtEnd_L3(TYPE_OPERATOR, "=", sizeof ("="), expr1); Ak_InsertAtEnd_L3(TYPE_OPERATOR, "OR", sizeof ("OR"), expr1); printf("\nQUERY: SELECT * FROM student WHERE weight > 83.750 OR firstname = 'Dino';\n\n"); AK_selection(srcTable1, destTable1, expr1); printf("\n Test is successful :) \n"); Ak_DeleteAll_L3(&expr1); AK_free(expr1); AK_EPI; }
/** * @author Samuel Picek * @brief Function for AK_concatinating 2 strings * @return returns new string */ char* AK_concat(char *s1, char *s2) { char *result = AK_malloc( strlen(s1) + strlen(s2) + 1); // +1 for the zero-terminator if (result != NULL) { strcpy(result, s1); strcat(result, s2); return result; } else return NULL; }
/** * @author Dino Laktašić. * @brief Break conjunctive conditions to individual conditions * (currently not used - commented in main AK_rel_eq_selection function), it can be usefull in some optimization cases * <ol> * <li>For each delimited item (' AND ') insert item to the struct list_node</li> * <li>Remove unused pointers and return the conditions list</li> * </ol> * @param *cond condition expression * @result conditions list */ struct list_node *AK_rel_eq_split_condition(char *cond) { AK_PRO; struct list_node *list_attr = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&list_attr); int token_id = 0; int attr_address = 0; int len_token; char *token_cond, *save_token_cond; //it's much safe to allocate MAX_VARCHAR_LENGHT, and remove all AK_realloc from function char *temp_attr = (char *) AK_calloc(1, sizeof (char)); //memset(temp_attr, '\0', MAX_VARCHAR_LENGHT); char *temp_cond = (char *) AK_calloc(strlen(cond), sizeof (char)); memcpy(temp_cond, cond, strlen(cond)); for ((token_cond = strtok_r(temp_cond, " ", &save_token_cond)); token_cond; (token_cond = strtok_r(NULL, " ", &save_token_cond)), token_id++) { if (token_id < MAX_TOKENS - 1) { len_token = strlen(token_cond); if (strcmp(token_cond, "AND") == 0) { Ak_InsertAtEnd_L3(TYPE_CONDITION, temp_attr, strlen(temp_attr), list_attr); attr_address = 0; AK_free(temp_attr); temp_attr = (char *) AK_calloc(1, sizeof (char)); } else { if (attr_address > 0) { temp_attr = (char *) AK_realloc(temp_attr, attr_address + len_token + 2); //memcpy(temp_attr + attr_address, " ", 1); strcpy(temp_attr + attr_address, " "); //memcpy(temp_attr + ++attr_address, "\0", 1); attr_address++; } else { temp_attr = (char *) AK_realloc(temp_attr, attr_address + len_token + 1); } strcpy(temp_attr + attr_address, token_cond); //memcpy(temp_attr + attr_address, token_cond, len_token); attr_address += len_token; } } } //memcpy(temp_attr + attr_address, "\0", 1); Ak_InsertAtEnd_L3(TYPE_CONDITION, temp_attr, strlen(temp_attr), list_attr); AK_free(temp_cond); AK_free(temp_attr); AK_EPI; return list_attr; }
/** * @author Frane Jakelić updated by Ivan Pusic * @brief Function that receives all the data and gives an id to that data and starts a thread that executes the transaction * @param commandArray array filled with commands that need to be secured using transactions * @param lengthOfArray length of commandArray */ void AK_transaction_manager(command * commandArray, int lengthOfArray) { AK_PRO; AK_transaction_data* params = AK_malloc(sizeof(AK_transaction_data)); params->array = AK_malloc(sizeof(command)); params->array = commandArray; params->lengthOfArray = lengthOfArray; transactionsCount++; if(activeTransactionsCount < MAX_ACTIVE_TRANSACTIONS_COUNT) { pthread_mutex_lock(&accessLockMutex); AK_create_new_transaction_thread(params); pthread_mutex_unlock(&accessLockMutex); } else { // wait until some transaction finishes pthread_mutex_lock(&newTransactionLockMutex); AK_create_new_transaction_thread(params); } AK_EPI; }
/** * @author Frane Jakelić updated by Ivan Pusic * @brief Function that is called in a separate thread that is responsible for acquiring locks, releasing them and finding the associated block addresses * @todo Check multithreading, check if it's working correctly * @param commandArray array filled with commands that need to be secured using transactions * @param lengthOfArray length of commandArray * @param transactionId associated with the transaction * @return ABORT or COMMIT based on the success of the function. */ int AK_execute_commands(command * commandArray, int lengthOfArray) { int i = 0, status = 0; AK_memoryAddresses addresses; AK_PRO; AK_memoryAddresses_link address = (AK_memoryAddresses_link) AK_malloc(sizeof(struct memoryAddresses)); for (i = 0; i < lengthOfArray; i++) { if (!AK_get_memory_blocks(commandArray[i].tblName, &addresses)) { printf("Error reading block Addresses. Aborting\n"); AK_EPI; return ABORT; }; address = &addresses; while (address->nextElement != NULL) { switch (commandArray[i].id_command) { case UPDATE: status = AK_acquire_lock(address->adresa, EXCLUSIVE_LOCK, pthread_self()); break; case DELETE: status = AK_acquire_lock(address->adresa, EXCLUSIVE_LOCK, pthread_self()); break; case INSERT: status = AK_acquire_lock(address->adresa, EXCLUSIVE_LOCK, pthread_self()); break; case SELECT: status = AK_acquire_lock(address->adresa, SHARED_LOCK, pthread_self()); break; default: break; } if (status == NOT_OK) { printf("Error acquiring lock. Aborting\n"); AK_release_locks(&addresses, pthread_self()); AK_EPI; return ABORT; } address = address->nextElement; } } if(AK_command(commandArray, lengthOfArray) == EXIT_ERROR){ AK_EPI; return ABORT; } AK_release_locks(&addresses, pthread_self()); AK_EPI; return COMMIT; }
/** * @author Frane Jakelić * @brief Adds a entry to the stack * @param id of the element that is being added to the stack * @return pointer to the newly added stack node */ AK_stack AK_push_to_stack(int id) { AK_stack node; AK_PRO; node = (AK_stack) AK_malloc(sizeof (struct Stack)); memset(node, 0, sizeof (struct Stack)); AK_search_empty_stack_link(&S)->nextElement = node; node->link = AK_search_vertex(id); AK_EPI; return node; }
/** * @author Frane Jakelić * @brief Function that adds a new graph node * @param id of the vertex that needs to be added * @param graphRoot root node of the graph structure * @return pointer to the newly created node */ AK_vertex AK_add_vertex(int id) { AK_vertex node; AK_PRO; node = (AK_vertex) AK_malloc(sizeof (struct Vertex)); memset(node, 0, sizeof (struct Vertex)); AK_search_empty_link(&G)->nextVertex = node; node->vertexId = id; node->index = -1; node->lowLink = -1; AK_EPI; return node; }
/** * @author Samuel Picek * @brief Function for importing large objects to database * @return OID (object ID) */ char *AK_lo_import(char *filepath) { printf("-----------------------------------------------------------------\n"); printf("[INFO] IMPORTING\n"); printf("-----------------------------------------------------------------\n"); AK_File_Metadata meta = AK_File_Metadata_malloc(); char *oid = AK_GUID(); meta->checksum = ""; char *old_name = (char) AK_malloc(sizeof(char) * 128); // filename char *old_path = (char) AK_malloc(sizeof(char) * 512); // filepath from where file is imported (without trailing slash) AK_split_path_file(&old_path, &old_name, filepath); strcpy(meta->new_name, oid); strcpy(meta->old_name, old_name); strcpy(meta->old_path, old_path); meta->new_path = AK_concat(AK_concat(AK_BLOBS_PATH, "/"), oid); if ( AK_copy(filepath, meta->new_path) == 0 ) { printf("[INFO] Large object imported successfully.\n\t[+] Object is at %s\n", meta->new_path); printf("[INFO] Importing metadata to catalog\n"); if (AK_write_metadata(oid, meta) == 0) { printf("[INFO] Success\n"); } else { printf("[INFO] There was an error writing metadata\n"); } } else { printf("[ERROR] There was an error while importing large object.\n"); } return oid; }
/** * @author Mario Kolmacic updated by Ivan Pusic and Tomislav Ilisevic * @brief Function for executing given commands (SELECT, UPDATE, DELETE AND INSERT) * @param komande Commands array to execute * @param brojkomandi Number of commands in array */ int AK_command(command * komande, int brojkomandi) { int i; AK_PRO; for (i = 0; i < brojkomandi; ++i) { switch(komande[i].id_command){ case SELECT: printf("***SELECT***\n"); char *ext = "_selection_tmp_table"; char *dest_table = AK_malloc(strlen(ext) + strlen(komande[i].tblName)+1); strcpy(dest_table, komande[i].tblName); strcat(dest_table, ext); if(AK_selection(komande[i].tblName, dest_table, (struct list_node*)komande[i].parameters) == EXIT_ERROR){ // unutar funkcije je ispis privremene tablice AK_EPI; return EXIT_ERROR; } break; case UPDATE: printf("***UPDATE***\n"); if(Ak_update_row( ((struct list_node *) (komande[i].parameters))) == EXIT_ERROR){ AK_EPI; return EXIT_ERROR; } AK_print_table(komande[i].tblName); break; case DELETE: printf("***DELETE***\n"); if(Ak_delete_row( ((struct list_node *) (komande[i].parameters))) == EXIT_ERROR){ AK_EPI; return EXIT_ERROR; } AK_print_table(komande[i].tblName); break; case INSERT: printf("***INSERT***\n"); if(Ak_insert_row( ((struct list_node *) (komande[i].parameters))) == EXIT_ERROR){ AK_EPI; return EXIT_ERROR; } AK_print_table(komande[i].tblName); break; default: break; } } AK_EPI; return EXIT_SUCCESS; }
char* Ak_Retrieve_L2(struct list_node *current, struct list_node *L) { char *data; AK_PRO; if (current == NULL || L == NULL) { return NULL; } data = (char*) AK_malloc(MAX_VARCHAR_LENGTH); memcpy(data, current->data, MAX_VARCHAR_LENGTH); AK_EPI; return data; }
/** * @author Frane Jakelić * @brief Function that searches for a empty link for new active block, helper method in case of address collision * @param blockAddress integer representation of memory address. * @return pointer to empty location to store new active address */ AK_transaction_elem_P AK_search_empty_link_for_hook(int blockAddress){ AK_PRO; int hash = AK_memory_block_hash(blockAddress); if(!LockTable[hash].DLLHead){ LockTable[hash].DLLHead = (AK_transaction_elem_P) AK_malloc(sizeof (AK_transaction_elem)); memset(LockTable[hash].DLLHead, 0, sizeof (AK_transaction_elem)); AK_EPI; return LockTable[hash].DLLHead; }else{ AK_EPI; return LockTable[hash].DLLHead; } AK_EPI; }
/** * @author Mislav Čakarić * @brief Function that fetches the info for hash index * @param indexName name of index * @return info bucket with info data for hash index */ hash_info* AK_get_hash_info(char *indexName) { AK_PRO; table_addresses *hash_addresses = (table_addresses*) AK_get_index_addresses(indexName); int block_add = hash_addresses->address_from[ 0 ]; hash_info *info = (hash_info*) AK_malloc(sizeof (hash_info)); memset(info, 0, sizeof (hash_info)); if (block_add == 0) { printf("Hash index does not exist!\n"); AK_EPI; return info; } AK_block *block = (AK_block*) AK_read_block(block_add); memcpy(info, block->data, sizeof (hash_info)); AK_EPI; return info; }
/** * @author Matija Šestak, modified for indexes by Lovro Predovan * @brief Function that gets value in some row and column * @param row zero-based row index * @param column zero-based column index * @param *tblName table name * @return value in the list */ struct list_node *AK_get_index_tuple(int row, int column, char *indexTblName) { AK_PRO; int num_rows = AK_get_index_num_records(indexTblName); int num_attr = AK_num_index_attr(indexTblName); if (row >= num_rows || column >= num_attr){ AK_EPI; return NULL; } table_addresses *addresses = (table_addresses*) AK_get_index_addresses(indexTblName); struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node)); Ak_Init_L3(&row_root); int i, j, k, counter; char data[ MAX_VARCHAR_LENGTH ]; i = 0; counter = -1; while (addresses->address_from[ i ] != 0) { for (j = addresses->address_from[ i ]; j < addresses->address_to[ i ]; j++) { AK_mem_block *temp = (AK_mem_block*) AK_get_block(j); if (temp->block->last_tuple_dict_id == 0) break; for (k = 0; k < DATA_BLOCK_SIZE; k += num_attr) { if (temp->block->tuple_dict[k].size > 0) counter++; if (counter == row) { int type = temp->block->tuple_dict[ k + column ].type; int size = temp->block->tuple_dict[ k + column ].size; int address = temp->block->tuple_dict[ k + column ].address; memcpy(data, &temp->block->data[address], size); data[ size ] = '\0'; Ak_InsertAtEnd_L3(type, data, size, row_root); AK_free(addresses); AK_EPI; return (struct list_node *) Ak_First_L2(row_root); } } } i++; } AK_free(addresses); AK_EPI; return NULL; }
AK_File_Metadata AK_File_Metadata_malloc() { AK_File_Metadata meta = (AK_File_Metadata) AK_malloc(sizeof(AK_Metadata)); meta->new_path = (char*) AK_malloc(sizeof(char) * 512); meta->new_name = (char*) AK_malloc(sizeof(char) * 128); meta->old_path = (char*) AK_malloc(sizeof(char) * 512); meta->old_name = (char*) AK_malloc(sizeof(char) * 128); meta->checksum = (char*) AK_malloc(sizeof(char) * 128); return meta; }
void Ak_InsertAfter_L2(int type, char* data, int size, struct list_node **current, struct list_node **L) { AK_PRO; struct list_node *new_elem; new_elem = (struct list_node*) AK_malloc(sizeof(struct list_node)); new_elem->size = size; new_elem->type = type; memcpy(new_elem->data, data, MAX_VARCHAR_LENGTH); if ((*current) == NULL) { (*L)->next = new_elem; new_elem->next = NULL; AK_EPI; return; } new_elem->next = (*current)->next; (*current)->next = new_elem; AK_EPI; }