Beispiel #1
0
/**
 * @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;
}
Beispiel #2
0
/**
 * @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;
}
Beispiel #3
0
/**
 * @author Matija Šestak.
 * @brief  Function that determines the number of rows in the table
 * <ol>
 * <li>Read addresses of extents</li>
 * <li>If there is no extents in the table, return EXIT_WARNING</li>
 * <li>For each extent from table</li>
 * <li>For each block in the extent</li>
 * <li>Get a block</li>
 * <li>Exit if there is no records in block</li>
 * <li>Count tuples in block</li>
 * <li>Return the number of tuples divided by number of attributes</li>
 * </ol>
 * @param *tableName table name
 * @return number of rows in the table
 */
int AK_get_num_records(char *tblName) {
    int num_rec = 0;
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    if (addresses->address_from[0] == 0){
        AK_EPI;
        return EXIT_WARNING;
    }
    int i = 0, j, k;
    AK_mem_block *temp = (AK_mem_block*) AK_get_block(addresses->address_from[0]);
    while (addresses->address_from[ i ] != 0) {
        for (j = addresses->address_from[ i ]; j < addresses->address_to[ i ]; j++) {
            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++) {
                if (temp->block->tuple_dict[ k ].size > 0) {
                    num_rec++;
                }
            }
        }
        i++;
    }

AK_free(addresses);
    int num_head = AK_num_attr(tblName);
    AK_EPI;
    return num_rec / num_head;
}
Beispiel #4
0
/**
 * @author Matija Šestak.
 * @brief  Function that checks whether the table is empty
 * @param *tblName table name
 * @return true/false
 */
int AK_table_empty(char *tblName) {
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    AK_mem_block *temp = (AK_mem_block*) AK_get_block(addresses->address_from[0]);
    AK_free(addresses);
    AK_EPI;
    return (temp->block->last_tuple_dict_id == 0) ? 1 : 0;
}
Beispiel #5
0
/**
 * @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;
}
Beispiel #6
0
/**
 * @author Mislav Čakarić edited by Ljubo Barać
 * @brief Function for renaming table and/or attribute in table (moved from rename.c)
 * @param old_table_name old name of the table
 * @param new_table_name new name of the table
 * @param old_attr name of the attribute to rename
 * @param new_attr new name for the attribute to rename
 * @return EXIT_ERROR or EXIT_SUCCESS
 */
int AK_rename(char *old_table_name, char *old_attr, char *new_table_name, char *new_attr) {
    AK_PRO;
    table_addresses *adresses = (table_addresses *) AK_get_table_addresses(old_table_name);
    int tab_addresses[MAX_NUM_OF_BLOCKS];
    int num_extents = 0, num_blocks = 0;
    register int i, j;
    AK_mem_block *mem_block;

    if (strcmp(old_attr, new_attr) != 0) {
        //SEARCH FOR ALL BLOCKS IN SEGMENT
        i = 0;
        while (adresses->address_from[i]) {
            for (j = adresses->address_from[i]; j <= adresses->address_to[i]; j++) {
                tab_addresses[num_blocks] = j;
                num_blocks++;
            }
            num_extents++;
            i++;
        }

        AK_header newHeader[MAX_ATTRIBUTES];
        mem_block = (AK_mem_block *) AK_get_block(tab_addresses[0]);
        memcpy(&newHeader, mem_block->block->header, sizeof (mem_block->block->header));

        for (i = 0; i < MAX_ATTRIBUTES; i++) {
            if (strcmp(newHeader[i].att_name, old_attr) == 0) {
                Ak_dbg_messg(HIGH, REL_OP, "AK_rename: the attribute names are the same at position %d!\n", i);
                memset(&newHeader[i].att_name, 0, MAX_ATT_NAME);
                memcpy(&newHeader[i].att_name, new_attr, strlen(new_attr));
                break;
            } else if (strcmp(newHeader[i].att_name, "\0") == 0) { //if there is no more attributes
                Ak_dbg_messg(MIDDLE, REL_OP, "AK_rename: ERROR: atribute: %s does not exist in this table\n", old_attr);
                AK_EPI;
                return (EXIT_ERROR);
            }
        }

        //replacing old headers with new ones
        for (i = 0; i < num_blocks; i++) {
            mem_block = AK_get_block(tab_addresses[i]);
            memcpy(&mem_block->block->header, newHeader, sizeof (AK_header) * MAX_ATTRIBUTES);
            AK_mem_block_modify(mem_block, BLOCK_DIRTY);
        }
    }

    if (strcmp(old_table_name, new_table_name) != 0) {//new name is different than old, and old needs to be replaced
        struct list_node *expr;
        expr = 0;
        AK_selection(old_table_name, new_table_name, expr);
        AK_delete_segment(old_table_name, SEGMENT_TYPE_TABLE);
    }
    AK_EPI;
    return EXIT_SUCCESS;
}
Beispiel #7
0
/**
 * @author Matija Šestak.
 * @brief  Function that fetches the table header
 * <ol>
 * <li>Read addresses of extents</li>
 * <li>If there is no extents in the table, return 0</li>
 * <li>else read the first block</li>
 * <li>allocate array</li>
 * <li>copy table header to the array</li>
 * </ol>
 * @param  *tblName table name
 * @result array of table header
 */
AK_header *AK_get_header(char *tblName) {
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    if (addresses->address_from[0] == 0){
        AK_EPI;
        return EXIT_WARNING + 2;
    }
    AK_mem_block *temp = (AK_mem_block*) AK_get_block(addresses->address_from[0]);

    int num_attr = AK_num_attr(tblName);
    AK_header *head = (AK_header*) AK_calloc(num_attr, sizeof (AK_header));
    memcpy(head, temp->block->header, num_attr * sizeof (AK_header));
	AK_free(addresses);
    AK_EPI;
    return head;
}
Beispiel #8
0
/**
 * @author Matija Šestak.
 * @brief  Functions that determines the number of attributes in the table
 * <ol>
 * <li>Read addresses of extents</li>
 * <li>If there is no extents in the table, return EXIT_WARNING</li>
 * <li>else read the first block</li>
 * <li>while  header tuple exists in the block, increment num_attr</li>
 * </ol>
 * @param  * tblName table name
 * @return number of attributes in the table
 */
int AK_num_attr(char * tblName) {
    int num_attr = 0;
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    if (addresses->address_from[0] == 0)
        num_attr = -2;
    else {
        AK_mem_block *temp_block = (AK_mem_block*) AK_get_block(addresses->address_from[0]);

        while (strcmp(temp_block->block->header[num_attr].att_name, "\0") != 0) {
            num_attr++;
        }

    }
    AK_free(addresses);
    AK_EPI;
    return num_attr;
}
Beispiel #9
0
/**
 * @author Markus Schatten, Matija Šestak.
 * @brief  Function that fetches all values in some row and put on the list
 * @param num zero-based row index
 * @param  * tblName table name
 * @return row values list
 */
struct list_node *AK_get_row(int num, char * tblName) {
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    struct list_node *row_root = (struct list_node *)AK_calloc(1, sizeof (struct list_node));
    Ak_Init_L3(&row_root);

    int num_attr = AK_num_attr(tblName);
    int i, j, k, l, counter;
    i = 0;

    char data[MAX_VARCHAR_LENGTH];
    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 == num) {
                    for (l = 0; l < num_attr; l++) {
                        int type = temp->block->tuple_dict[k + l].type;
                        int size = temp->block->tuple_dict[k + l].size;
                        int address = temp->block->tuple_dict[k + l].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 row_root;
                }
            }
        }
        i++;
    }
    AK_free(addresses);
	Ak_DeleteAll_L3(&row_root);
	AK_free(row_root);
    AK_EPI;
    return NULL;
}
Beispiel #10
0
/**
 * @author Dino Laktašić
 * @brief  Function to make union of the two tables. Union is implemented for working with multiple sets of data, i.e. duplicate 
 * 	   tuples can be written in same table (union) 
 * @param srcTable1 name of the first table
 * @param srcTable2 name of the second table
 * @param dstTable name of the new table
 * @return if success returns EXIT_SUCCESS, else returns EXIT_ERROR
 */
int AK_union(char *srcTable1, char *srcTable2, char *dstTable) {
    AK_PRO;
    table_addresses *src_addr1 = (table_addresses*) AK_get_table_addresses(srcTable1);
    table_addresses *src_addr2 = (table_addresses*) AK_get_table_addresses(srcTable2);

    int startAddress1 = src_addr1->address_from[0];
    int startAddress2 = src_addr2->address_from[0];
	
    if ((startAddress1 != 0) && (startAddress2 != 0)) {
        register int i, j, k;
        i = j = k = 0;

        AK_mem_block *tbl1_temp_block = (AK_mem_block *) AK_get_block(startAddress1);
        AK_mem_block *tbl2_temp_block = (AK_mem_block *) AK_get_block(startAddress2);
        
        int num_att = AK_check_tables_scheme(tbl1_temp_block, tbl2_temp_block, "Union");

	int address, type, size;
        char data[MAX_VARCHAR_LENGTH];

		//initialize new segment
        AK_header *header = (AK_header *) AK_malloc(num_att * sizeof (AK_header));
        memcpy(header, tbl1_temp_block->block->header, num_att * sizeof (AK_header));
        AK_initialize_new_segment(dstTable, SEGMENT_TYPE_TABLE, header);
        AK_free(header);

        //AK_list *row_root = (AK_list *) AK_malloc(sizeof (AK_list));
	struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
		
	//writing first block or table to new segment
	for (i = 0; src_addr1->address_from[i] != 0; i++) {
            startAddress1 = src_addr1->address_from[i];

                //BLOCK: for each block in table1 extent
                for (j = startAddress1; j < src_addr1->address_to[i]; j++) {
                    tbl1_temp_block = (AK_mem_block *) AK_get_block(j); //read block from first table

                    //if there is data in the block
                    if (tbl1_temp_block->block->AK_free_space != 0) {

						for (k = 0; k < DATA_BLOCK_SIZE; k++) {
							if (tbl1_temp_block->block->tuple_dict[k].type == FREE_INT)
								break;
								
							address = tbl1_temp_block->block->tuple_dict[k].address;
							size = tbl1_temp_block->block->tuple_dict[k].size;
							type = tbl1_temp_block->block->tuple_dict[k].type;

							memset(data, '\0', MAX_VARCHAR_LENGTH);
							memcpy(data, tbl1_temp_block->block->data + address, size);
						
							Ak_Insert_New_Element_For_Update(type, data, dstTable, tbl1_temp_block->block->header[k % num_att].att_name, row_root, 0);
							
							if ((k + 1) % num_att == 0 && k != 0) {
								Ak_insert_row(row_root);
								
								Ak_DeleteAll_L3(&row_root);
							}
						}
					}
				}
		}
		
	//writing first block or table to new segment
	for (i = 0; src_addr2->address_from[i] != 0; i++) {
            startAddress2 = src_addr2->address_from[i];

                //BLOCK: for each block in table2 extent
                for (j = startAddress2; j < src_addr2->address_to[i]; j++) {
                    tbl2_temp_block = (AK_mem_block *) AK_get_block(j); //read block from second table

                    //if there is data in the block
                    if (tbl2_temp_block->block->AK_free_space != 0) {
				
						for (k = 0; k < DATA_BLOCK_SIZE; k++) {
							if (tbl2_temp_block->block->tuple_dict[k].type == FREE_INT)
								break;
						
							address = tbl2_temp_block->block->tuple_dict[k].address;
							size = tbl2_temp_block->block->tuple_dict[k].size;
							type = tbl2_temp_block->block->tuple_dict[k].type;
							
							memset(data, '\0', MAX_VARCHAR_LENGTH);
							memcpy(data, tbl2_temp_block->block->data + address, size);

							Ak_Insert_New_Element_For_Update(type, data, dstTable, tbl2_temp_block->block->header[k % num_att].att_name, row_root, 0);
							
							if ((k + 1) % num_att == 0) {
								Ak_insert_row(row_root);
								
								Ak_DeleteAll_L3(&row_root);
							}
						}
					}
				}
		}
		
	    AK_free(src_addr1);
	    AK_free(src_addr2);
	    Ak_dbg_messg(LOW, REL_OP, "UNION_TEST_SUCCESS\n\n");
	    AK_EPI;
	    return EXIT_SUCCESS;
	} else {
		Ak_dbg_messg(LOW, REL_OP, "\nAK_union: Table/s doesn't exist!");
		AK_free(src_addr1);
		AK_free(src_addr2);
		AK_EPI;
		return EXIT_ERROR;
	}
	AK_EPI;
}
Beispiel #11
0
search_result AK_search_unsorted(char *szRelation, search_params *aspParams, int iNum_search_params) {
    AK_PRO;
    AK_flush_cache();
    int iBlock;
    AK_mem_block *mem_block = NULL, tmp;
    int i, j, k;
    int iTupleMatches;
    search_result srResult;
    table_addresses *taAddresses;

    srResult.aiTuple_addresses = NULL;
    srResult.iNum_tuple_addresses = 0;
    srResult.aiSearch_attributes = NULL;
    srResult.aiBlocks = NULL;

    if (aspParams == NULL || iNum_search_params == 0){
	AK_EPI;
        return srResult;
    }

    taAddresses = AK_get_table_addresses(szRelation);

    /// iterate through all the blocks
    for (k = 0; k < MAX_EXTENTS_IN_SEGMENT && taAddresses->address_from[k] > 0; k++) { // 200 == Novak's magic number :)
        for (iBlock = taAddresses->address_from[k]; iBlock <= taAddresses->address_to[k]; iBlock++) {
            //mem_block = AK_get_block(iBlock);
            mem_block = &tmp;
            mem_block->block = AK_read_block(iBlock);

            /// count number of attributes in segment/relation
            srResult.iNum_tuple_attributes = 0;
            for (i = 0; i < MAX_ATTRIBUTES; i++) {
                if (mem_block->block->header[i].att_name[0] == FREE_CHAR)
                    break;
                srResult.iNum_tuple_attributes++;
            }

            srResult.aiSearch_attributes = (int *) AK_malloc(iNum_search_params * sizeof (int));
            if (srResult.aiSearch_attributes == NULL) {
                printf("AK_search_unsorted: ERROR. Cannot allocate srResult.aiAttributes_searched.\n");
                AK_EPI;
                exit(EXIT_ERROR);
            }
            srResult.iNum_search_attributes = 0;

            /// determine index of attributes on which search will be performed
            for (j = 0; j < iNum_search_params; j++) {
                for (i = 0; i < MAX_ATTRIBUTES; i++) {
                    if (!strcmp(mem_block->block->header[i].att_name, aspParams[j].szAttribute)) {
                        srResult.aiSearch_attributes[j] = i;
                        srResult.iNum_search_attributes++;
                        break;
                    }
                }
            }

            /// if any of the provided attributes are not found in the relation, return empty result
            if (srResult.iNum_search_attributes != iNum_search_params)
                return srResult;

            /// in every tuple, for all required attributes, compare attribute value with searched-for value and store matched tuple addresses
            for (i = 0; i < DATA_BLOCK_SIZE && mem_block->block->tuple_dict[i].type != FREE_INT; i += srResult.iNum_tuple_attributes) {
                iTupleMatches = 1;

                for (j = 0; j < iNum_search_params && iTupleMatches; j++) {
                    switch (aspParams[j].iSearchType) {
                        case SEARCH_PARTICULAR:
                        {
                            size_t iSearchAttributeValueSize = AK_type_size(mem_block->block->header[srResult.aiSearch_attributes[j]].type, (char *) aspParams[j].pData_lower);

                            if (mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].size != iSearchAttributeValueSize
                                    || memcmp(mem_block->block->data + mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].address, aspParams[j].pData_lower, iSearchAttributeValueSize)) {
                                iTupleMatches = 0;
                            }
                        }
                            break;

                        case SEARCH_RANGE:
                        {

                            switch (mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].type) {
                                case TYPE_INT:
                                case TYPE_DATE:
                                case TYPE_DATETIME:
                                case TYPE_TIME:
                                {
                                    int iAttributeValue = *((int *) (mem_block->block->data + mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].address));
                                    if (iAttributeValue < *((int *) aspParams[j].pData_lower)
                                            || iAttributeValue > *((int *) aspParams[j].pData_upper)) {
                                        iTupleMatches = 0;
                                    }
                                }
                                    break;

                                case TYPE_FLOAT:
                                case TYPE_NUMBER:
                                    if (*((double *) (mem_block->block->data + mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].address)) < *((double *) aspParams[j].pData_lower)
                                            || *((double *) (mem_block->block->data + mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].address)) > *((double *) aspParams[j].pData_upper)) {
                                        iTupleMatches = 0;
                                    }
                                    break;

                                default: // other types unsupported
                                    iTupleMatches = 0;
                            }
                        }
                            break;

                        case SEARCH_ALL: // iTupleMatches is already == 1, no action needed
                            break;

                        case SEARCH_NULL:
                        {
                            size_t iSearchAttributeValueSize = AK_type_size(mem_block->block->header[srResult.aiSearch_attributes[j]].type, (char *) aspParams[j].pData_lower);

                            if (mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].type != TYPE_VARCHAR
                                    || iSearchAttributeValueSize != strlen("NULL")
                                    || memcmp(mem_block->block->data + mem_block->block->tuple_dict[i + srResult.aiSearch_attributes[j]].address, "NULL", strlen("NULL")))
                                iTupleMatches = 0;
                        }
                            break;

                        default:
                            iTupleMatches = 0;
                    }
                }

                if (iTupleMatches) {
                    /*if(DEBUG) {
                        printf("AK_realloc(srResult.aiTuple_addresses = %p, srResult.iNum_tuple_addresses++ * sizeof(int) = %d)\n", srResult.aiTuple_addresses, (srResult.iNum_tuple_addresses + 1) * sizeof(int));
                        if(srResult.iNum_tuple_addresses == 7)
                            puts("8");
                    }*/
                    srResult.iNum_tuple_addresses++;
                    srResult.aiTuple_addresses = (int *) AK_realloc(srResult.aiTuple_addresses, srResult.iNum_tuple_addresses * sizeof (int));

                    if (srResult.aiTuple_addresses == NULL) {
                        printf("AK_search_unsorted: ERROR. Cannot AK_reallocate srResult.aiTuple_addresses, iteration %d.\n", i);
                        AK_EPI;
                        exit(EXIT_ERROR);
                    }

                    /*if(DEBUG)
                        puts("AK_realloc srResult.aiBlocks");*/
                    srResult.aiBlocks = (int *) AK_realloc(srResult.aiBlocks, srResult.iNum_tuple_addresses * sizeof (int));
                    if (srResult.aiBlocks == NULL) {
                        printf("AK_search_unsorted: ERROR. Cannot AK_reallocate srResult.aiBlocks, iteration %d.\n", i);
                        AK_EPI;
                        exit(EXIT_ERROR);
                    }

                    srResult.aiTuple_addresses[srResult.iNum_tuple_addresses - 1] = i;
                    srResult.aiBlocks[srResult.iNum_tuple_addresses - 1] = iBlock;
                }
            }
        }
    }
    AK_EPI;
    return srResult;
}
Beispiel #12
0
/**
 * @author Dino Laktašić and Mislav Čakarić (replaced old print table function by new one)
 * update by Luka Rajcevic
 * @brief  Function that prints a table
 * @param *tblName table name
 * @return No return value
 * update by Anto Tomaš (corrected the Ak_DeleteAll_L3 function)
 */
void AK_print_table_to_file(char *tblName) {

	char* FILEPATH = "table_test.txt";
	FILE *fp;
    
	AK_PRO;
    fp = fopen(FILEPATH, "a");
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    if (addresses->address_from[0] == 0) {
        fprintf(fp, "Table %s does not exist!\n", tblName);

    } else {
        AK_header *head = AK_get_header(tblName);

        int i, j, k, l;
        int num_attr = AK_num_attr(tblName);
        int num_rows = AK_get_num_records(tblName);
        int len[num_attr]; //max length for each attribute in row
        int length = 0; //length of spacer

        //store lengths of header attributes
        for (i = 0; i < num_attr; i++) {
            len[i] = strlen((head + i)->att_name);
        }

        //for each header attribute iterate through all table rows and check if
        //there is longer element than previously longest and store it in array
        for (i = 0; i < num_attr; i++) {
            for (j = 0; j < num_rows; j++) {
                struct list_node *el = AK_get_tuple(j, i, tblName);
                switch (el->type) {
                    case TYPE_INT:
                        length = AK_chars_num_from_number(*((int *) (el)->data), 10);
                        if (len[i] < length) {
                            len[i] = length;
                        }
                        break;
                    case TYPE_FLOAT:
                        length = AK_chars_num_from_number(*((float *) (el)->data), 10);
                        if (len[i] < length) {
                            len[i] = length;
                        }
                        break;
                    case TYPE_VARCHAR:
                    default:
                        if (len[i] < el->size) {
                            len[i] = el->size;
                        }
                        break;
                }
            }
        }
        //num_attr is number of char | + space in printf
        //set offset to change the box size
        length = 0;
        for (i = 0; i < num_attr; length += len[i++]);
        length += num_attr * TBL_BOX_OFFSET + 2 * num_attr + 1;

        fprintf(fp, "Table: %s\n", tblName);

        if (num_attr <= 0 || num_rows <= 0) {
            fprintf(fp, "Table is empty.\n");
        } else {
            //print table header
            fclose(fp);
            AK_print_row_spacer_to_file(len, length);
            fp = fopen(FILEPATH, "a");
            fprintf(fp, "\n|");

            for (i = 0; i < num_attr; i++) {
                //print attributes center aligned inside box
                k = (len[i] - (int) strlen((head + i)->att_name) + TBL_BOX_OFFSET + 1);
                if (k % 2 == 0) {
                    k /= 2;
                    fprintf(fp, "%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name), (head + i)->att_name);
                } else {
                    k /= 2;
                    fprintf(fp, "%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name) + 1, (head + i)->att_name);
                }

                //print attributes left aligned inside box
                //printf(" %-*s|", len[i] + MAX_TABLE_BOX_OFFSET, (head + i)->att_name);
            }
            fprintf(fp, "\n");
            fclose(fp);
            AK_print_row_spacer_to_file(len, length);
            struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
            Ak_Init_L3(&row_root);

            i = 0;
            int type, size, address;

            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) {
                            for (l = 0; l < num_attr; l++) {
                                type = temp->block->tuple_dict[k + l].type;
                                size = temp->block->tuple_dict[k + l].size;
                                address = temp->block->tuple_dict[k + l].address;
                                Ak_InsertAtEnd_L3(type, &(temp->block->data[address]), size, row_root);
                            }
                            AK_print_row_to_file(len, row_root);
                            AK_print_row_spacer_to_file(len, length);
                            Ak_DeleteAll_L3(&row_root);
                        }
                    }
                }
                i++;
            }
            fp = fopen(FILEPATH, "a");
            fprintf(fp, "\n");
        }
    }
    fclose(fp);
    AK_EPI;
}
Beispiel #13
0
/**
 * @author Dino Laktašić and Mislav Čakarić (replaced old print table function by new one)
 * @brief  Function for printing table
 * @param *tblName table name
 * @return No return value
 */
void AK_print_table(char *tblName) {
    AK_PRO;
    table_addresses *addresses = (table_addresses*) AK_get_table_addresses(tblName);
    //  || (AK_table_exist(tblName) == 0)
    if ((addresses->address_from[0] == 0) || (AK_table_exist(tblName) == 0)) {
        printf("Table %s does not exist!\n", tblName);
        AK_free(addresses);
    } else {
        AK_header *head = AK_get_header(tblName);

        int i, j, k, l;
        int num_attr = AK_num_attr(tblName);
        int num_rows = AK_get_num_records(tblName);
        int len[num_attr]; //max length for each attribute in row
        int length = 0; //length of spacer
        clock_t t;

        //store lengths of header attributes
        for (i = 0; i < num_attr; i++) {
            len[i] = strlen((head + i)->att_name);
        }

        //for each header attribute iterate through all table rows and check if
        //there is longer element than previously longest and store it in array
        for (i = 0; i < num_attr; i++) {
            for (j = 0; j < num_rows; j++) 
			{
                struct list_node *el = AK_get_tuple(j, i, tblName);
                switch (el->type) 
				{
                    case TYPE_INT:
                        length = AK_chars_num_from_number(*((int *) (el)->data), 10);
                        if (len[i] < length) 
						{
                            len[i] = length;
                        }
                        break;
                    case TYPE_FLOAT:
                        length = AK_chars_num_from_number(*((float *) (el)->data), 10);
                        if (len[i] < length) 
						{
                            len[i] = length;
                        }
                        break;
                    case TYPE_VARCHAR:
                    default:
                        if (len[i] < el->size) 
						{
                            len[i] = el->size;
                        }
                        break;
                }
				//we don't need this linked list anymore (starting from tupple first to the end
				//see comment above in function AK_get_tuple - Elvis Popovic
				Ak_DeleteAll_L3(&el);
				AK_free(el);
            }
        }
        //num_attr is number of char | + space in printf
        //set offset to change the box size
        length = 0;
        for (i = 0; i < num_attr; length += len[i++]);
        length += num_attr * TBL_BOX_OFFSET + 2 * num_attr + 1;

        //start measuring time
        t = clock();

        printf("Table: %s\n", tblName);

        if (num_attr <= 0 || num_rows <= 0) {
            printf("Table is empty.\n");
        } else {
            //print table header
            AK_print_row_spacer(len, length);
            printf("\n|");

            for (i = 0; i < num_attr; i++) {
                //print attributes center aligned inside box
                k = (len[i] - (int) strlen((head + i)->att_name) + TBL_BOX_OFFSET + 1);
                if (k % 2 == 0) {
                    k /= 2;
                    printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name), (head + i)->att_name);
                } else {
                    k /= 2;
                    printf("%-*s%-*s|", k, " ", k + (int) strlen((head + i)->att_name) + 1, (head + i)->att_name);
                }

                //print attributes left aligned inside box
                //printf(" %-*s|", len[i] + MAX_TABLE_BOX_OFFSET, (head + i)->att_name);
            }
			AK_free(head);
            printf("\n");
            AK_print_row_spacer(len, length);

            struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
            Ak_Init_L3(&row_root);

            i = 0;
            int type, size, address;

            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 /*&& k / num_attr < num_rows*/) {
                            for (l = 0; l < num_attr; l++) {
                                type = temp->block->tuple_dict[k + l].type;
                                size = temp->block->tuple_dict[k + l].size;
                                address = temp->block->tuple_dict[k + l].address;
                                Ak_InsertAtEnd_L3(type, &temp->block->data[address], size, row_root);
                            }
                            AK_print_row(len, row_root);
                            AK_print_row_spacer(len, length);
                            Ak_DeleteAll_L3(&row_root);
                        }
                    }
                }
                i++;
            }

            printf("\n");
            t = clock() - t;

            if ((((double) t) / CLOCKS_PER_SEC) < 0.1) {
                printf("%i rows found, duration: %f μs\n", num_rows, ((double) t) / CLOCKS_PER_SEC * 1000);
            } else {
                printf("%i rows found, duration: %f s\n", num_rows, ((double) t) / CLOCKS_PER_SEC);
            }
        AK_free(row_root);
        }

AK_free(addresses);

    }
    AK_EPI;
}
Beispiel #14
0
/**
 * @author unknown, Jurica Hlevnjak - fix bugs and reorganize code in this function
 * @brief Help function for the drop command. Delete memory blocks and addresses of table 
 * and removes table or index from system table.
 * @param tblName name of table or index
 * @param sys_table name of system catalog table
 */
void AK_drop_help_function(char *tblName, char *sys_table) {

    table_addresses *addresses;
    AK_PRO;
    addresses = (table_addresses*) AK_get_table_addresses(tblName);

    AK_mem_block *mem_block;

    int from = 0, to = 0, i = 0, j = 0, c;

    for (j = 0; j < MAX_EXTENTS_IN_SEGMENT; j++) {
        if (addresses->address_from != 0) {
            from = addresses->address_from[j];
            to = addresses->address_to[j];

            if (from == 0 || to == 0) break;
            for (i = from; i <= to; i++) {
                mem_block = (AK_mem_block *) AK_get_block(i);
                mem_block->block->type = BLOCK_TYPE_FREE;

                for (c = 0; c < DATA_BLOCK_SIZE; c++) {
                    mem_block->block->tuple_dict[c].type = FREE_INT;
                    mem_block->block->data[c] = FREE_CHAR;
                }
            }
        } else break;
    }

    int data_adr = 0;
    int data_size = 0;
    //int data_type = 0;
    int address_sys;
    char name_sys[MAX_ATT_NAME];

    AK_mem_block *mem_block2 = (AK_mem_block *) AK_get_block(0);

    for (i = 0; i < DATA_BLOCK_SIZE; i++) {
        memset(name_sys, 0, MAX_ATT_NAME);

        if (mem_block2->block->tuple_dict[i].address == FREE_INT) {
            break;
        }

        data_adr = mem_block2->block->tuple_dict[i].address;
        data_size = mem_block2->block->tuple_dict[i].size;

        memcpy(name_sys, mem_block2->block->data + data_adr, data_size);

        i++;
        data_adr = mem_block2->block->tuple_dict[i].address;
        data_size = mem_block2->block->tuple_dict[i].size;

        memcpy(&address_sys, mem_block2->block->data + data_adr, data_size);

        if (strcmp(name_sys, sys_table) == 0) {
            break;
        }
    }

    mem_block2 = (AK_mem_block *) AK_get_block(address_sys);
    table_addresses *addresses2;

    addresses2 = (table_addresses*) AK_get_table_addresses(tblName);

    for (i = 0; i < MAX_EXTENTS_IN_SEGMENT; i++) {
        addresses2->address_from[i] = 0;
        addresses2->address_to[i] = 0;
    }

    char name[MAX_VARCHAR_LENGTH];

    for (i = 0; i < DATA_BLOCK_SIZE; i++) {
        if (mem_block2->block->tuple_dict[i].type == FREE_INT)
            break;
        i++;
        memcpy(name, &(mem_block2->block->data[mem_block2->block->tuple_dict[i].address]), mem_block2->block->tuple_dict[i].size);
        name[ mem_block2->block->tuple_dict[i].size] = '\0';
        if (strcmp(name, tblName) == 0) {
            i++;
            mem_block2->block->data[mem_block2->block->tuple_dict[i].address] = 0;
            i++;
            mem_block2->block->data[mem_block2->block->tuple_dict[i].address] = 0;
        }
    }


    struct list_node *row_root = (struct list_node *) AK_malloc(sizeof (struct list_node ));
    Ak_Init_L3(&row_root);
    Ak_DeleteAll_L3(&row_root);
    
    Ak_Update_Existing_Element(TYPE_VARCHAR, tblName, sys_table, "name", row_root);

    Ak_delete_row(row_root);
    AK_free(addresses);
    AK_free(addresses2);

    AK_EPI;
}
Beispiel #15
0
/**
 * @author Dino Laktašić
 * @brief  Function that produces a difference of the two tables. Table addresses are get through names of tables.
 *         Specially start addresses are taken from them. They are used to allocate blocks for them. It is checked whether
           the tables have same table schemas. If not, it returns EXIT_ERROR. New segment for result of difference operation is
           initialized. Function compares every block in extent of the first table with every block in extent of second table. If there 
	   is a difference between their rows, they are put in dstTable.
 * @param srcTable1 name of the first table
 * @param srcTable2 name of the second table
 * @param dstTable name of the new table
 * @return if success returns EXIT_SUCCESS, else returns EXIT_ERROR
 */
int AK_difference(char *srcTable1, char *srcTable2, char *dstTable) {
    AK_PRO;
    table_addresses *src_addr1 = (table_addresses*) AK_get_table_addresses(srcTable1);
    table_addresses *src_addr2 = (table_addresses*) AK_get_table_addresses(srcTable2);

    int startAddress1 = src_addr1->address_from[0];
    int startAddress2 = src_addr2->address_from[0];
	
    if ((startAddress1 != 0) && (startAddress2 != 0)) {
        register int i, j, k, l, m, n, o;
        i = j = k = l = 0;

        AK_mem_block *tbl1_temp_block = (AK_mem_block *) AK_get_block(startAddress1);
        AK_mem_block *tbl2_temp_block = (AK_mem_block *) AK_get_block(startAddress2);
		
		int num_att = AK_check_tables_scheme(tbl1_temp_block, tbl2_temp_block, "Difference");
		 
		if (num_att == EXIT_ERROR) {
			AK_EPI;
			return EXIT_ERROR;
		}

		int address, type, size;
		int different, num_rows, temp_int,summ;
		different = num_rows = temp_int = summ = 0;
		
		float temp_float = 0;
		
        char data1[MAX_VARCHAR_LENGTH];
	char data2[MAX_VARCHAR_LENGTH];
		
	//initialize new segment
        AK_header *header = (AK_header *) AK_malloc(num_att * sizeof (AK_header));
        memcpy(header, tbl1_temp_block->block->header, num_att * sizeof (AK_header));
        AK_initialize_new_segment(dstTable, SEGMENT_TYPE_TABLE, header);
        AK_free(header);

	struct list_node * row_root = (struct list_node *) AK_malloc(sizeof(struct list_node));
	
	for (i = 0; src_addr1->address_from[i] != 0; i++) {
            startAddress1 = src_addr1->address_from[i];

                //BLOCK: for each block in table1 extent
                for (j = startAddress1; j < src_addr1->address_to[i]; j++) {
                    tbl1_temp_block = (AK_mem_block *) AK_get_block(j); //read block from first table

                    //if there is data in the block
                    if (tbl1_temp_block->block->AK_free_space != 0) {
						
			//TABLE2: for each extent in table2
                        for (k = 0; k < (src_addr2->address_from[k] != 0); k++) {
                            startAddress2 = src_addr2->address_from[k];

                            if (startAddress2 != 0) {

                                //BLOCK: for each block in table2 extent
                                for (l = startAddress2; l < src_addr2->address_to[k]; l++) {
                                    tbl2_temp_block = (AK_mem_block *) AK_get_block(l);

                                    //if there is data in the block
                                    if (tbl2_temp_block->block->AK_free_space != 0) {
										
					//TUPLE_DICTS: for each tuple_dict in the block
                                        for (m = 0; m < DATA_BLOCK_SIZE; m += num_att) {
                                            if (tbl1_temp_block->block->tuple_dict[m + 1].type == FREE_INT)
                                                break;

					    //TUPLE_DICTS: for each tuple_dict in the block
                                            for (n = 0; n < DATA_BLOCK_SIZE; n += num_att) {
                                                if (tbl2_temp_block->block->tuple_dict[n + 1].type == FREE_INT)
                                                    break;
												
												//for each element in row
												for (o = 0; o < num_att; o++) {
													address = tbl1_temp_block->block->tuple_dict[m + o].address;
													size = tbl1_temp_block->block->tuple_dict[m + o].size;
													type = tbl1_temp_block->block->tuple_dict[m + o].type;
													
													switch (type) {
														case TYPE_INT: 
															memcpy(&temp_int, &(tbl1_temp_block->block->data[address]), size);
															sprintf(data1, "%d", temp_int);
															break;
														case TYPE_FLOAT:
															memcpy(&temp_float, &(tbl1_temp_block->block->data[address]), size);
															sprintf(data1, "%f", temp_float);
															break;
														case TYPE_VARCHAR:
														default:
															memset(data1, '\0', MAX_VARCHAR_LENGTH);
															memcpy(data1, &(tbl1_temp_block->block->data[address]), size);
													}
													
													address = tbl2_temp_block->block->tuple_dict[n + o].address;
													size = tbl2_temp_block->block->tuple_dict[n + o].size;
													type = tbl2_temp_block->block->tuple_dict[n + o].type;
													
													switch (type) {
														case TYPE_INT: 
															memcpy(&temp_int, &(tbl2_temp_block->block->data[address]), size);
															sprintf(data2, "%d", temp_int);
															break;
														case TYPE_FLOAT:
															memcpy(&temp_float, &(tbl2_temp_block->block->data[address]), size);
															sprintf(data2, "%f", temp_float);
															break;
														case TYPE_VARCHAR:
														default:
															memset(data2, '\0', MAX_VARCHAR_LENGTH);
															memcpy(data2, &(tbl2_temp_block->block->data[address]), size);
													}
													
													//if they are the same
												    if(strcmp(data1,data2)==0){
														different++;
														}
													if(different==(num_att-1)) summ=1;

												}
												//if same rows are found don't keep searching
												if(summ==1)break;
											}
											//if there is a difference between tuple_dicts
											if (summ == 0) {
												
												Ak_DeleteAll_L3(&row_root);	
												for (o = 0; o < num_att; o++) {
													address = tbl1_temp_block->block->tuple_dict[m + o].address;
													size = tbl1_temp_block->block->tuple_dict[m + o].size;
													type = tbl1_temp_block->block->tuple_dict[m + o].type;
													
													memset(data1, '\0', MAX_VARCHAR_LENGTH);
													memcpy(data1, tbl1_temp_block->block->data + address, size);

													Ak_Insert_New_Element(type, data1, dstTable, tbl1_temp_block->block->header[o].att_name, row_root);
												}

												Ak_insert_row(row_root);
											}
											num_rows = different = summ = 0;
										}
									}
								}
							} else break;
						}
					}
				}
		}
		
	AK_free(src_addr1);
        AK_free(src_addr2);
		Ak_DeleteAll_L3(&row_root);	
		AK_free(row_root);
		Ak_dbg_messg(LOW, REL_OP, "DIFFERENCE_TEST_SUCCESS\n\n");
		AK_EPI;
		return EXIT_SUCCESS;
	} else {
		Ak_dbg_messg(LOW, REL_OP, "\nAK_difference: Table/s doesn't exist!");
        AK_free(src_addr1);
        AK_free(src_addr2);
		AK_EPI;
		return EXIT_ERROR;
	}
	AK_EPI;
}
Beispiel #16
0
//int AK_selection(char *srcTable, char *dstTable, AK_list *expr) {
int AK_selection(char *srcTable, char *dstTable, struct list_node *expr) {
        AK_PRO;
	AK_header *t_header = (AK_header *) AK_get_header(srcTable);
	int num_attr = AK_num_attr(srcTable);

		int startAddress = AK_initialize_new_segment(dstTable, SEGMENT_TYPE_TABLE, t_header);
		if (startAddress == EXIT_ERROR) {
			AK_EPI;
			return EXIT_ERROR;
		}
		Ak_dbg_messg(LOW, REL_OP, "\nTABLE %s CREATED from %s!\n", dstTable, srcTable);
		table_addresses *src_addr = (table_addresses*) AK_get_table_addresses(srcTable);
		
		/*
		AK_list_elem row_root = (AK_list_elem) AK_malloc(sizeof (AK_list));
		Ak_Init_L3(&row_root);
		*/
		
		struct list_node * row_root = (struct list_node *) AK_malloc(sizeof(struct list_node));
		Ak_Init_L3(&row_root);
		
		int i, j, k, l, type, size, address;
		char data[MAX_VARCHAR_LENGTH];

		for (i = 0; src_addr->address_from[i] != 0; i++) {

			for (j = src_addr->address_from[i]; j < src_addr->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].type == FREE_INT)
						break;

					for (l = 0; l < num_attr; l++) {
						type = temp->block->tuple_dict[k + l].type;
						size = temp->block->tuple_dict[k + l].size;
						address = temp->block->tuple_dict[k + l].address;
						memcpy(data, &(temp->block->data[address]), size);
						data[size] = '\0';
						Ak_Insert_New_Element(type, data, dstTable, t_header[l].att_name, row_root);
					}

					if (AK_check_if_row_satisfies_expression(row_root, expr))
						Ak_insert_row(row_root);

					
					Ak_DeleteAll_L3(&row_root);
				}
			}
		}

		AK_free(src_addr);
		AK_free(t_header);
		AK_free(row_root);

		AK_print_table(dstTable);
	

	Ak_dbg_messg(LOW, REL_OP, "SELECTION_TEST_SUCCESS\n\n");
	AK_EPI;
	return EXIT_SUCCESS;
}