예제 #1
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #2
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #3
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #4
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @author Matija Šestak.
 * @brief  Function that fetches attribute name for some zero-based index
 * @param *tblName table name
 * @param index zero-based index
 * @return attribute name
 */
char *AK_get_attr_name(char *tblName, int index) {
    AK_PRO;
    int num_attr = AK_num_attr(tblName);
    if (index >= num_attr){
        AK_EPI;
        return NULL;
    }
    else {
        AK_header *header = AK_get_header(tblName);
        AK_EPI;
        return (header + index)->att_name;
    }
    AK_EPI;
}
예제 #5
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #6
0
파일: test.c 프로젝트: mschatten/akdb
char* AK_get_table_atribute_types(char* tblName){
    int len_attr, num_attr, next_attr, attr_type;
    int next_address = 0;
    char attr_buffer[4];
    AK_PRO;
    num_attr = AK_num_attr(tblName);


    if (num_attr == EXIT_WARNING) {
        AK_EPI;
        return NULL;
    }

    char *attr = (char *) AK_calloc(1, sizeof (char));
    AK_header *table_header = (AK_header *) AK_get_header(tblName);

    for (next_attr = 0; next_attr < num_attr; next_attr++) {
        
        attr_type = (table_header + next_attr)->type;
        
        len_attr = sprintf(attr_buffer,"%d",attr_type);

        attr = (char *) AK_realloc(attr, len_attr + next_address + 1);
        memcpy(attr + next_address, attr_buffer, len_attr);
        next_address += len_attr;

        if (next_attr < num_attr - 1) {
            memcpy(attr + next_address, ATTR_DELIMITER, 1);
            next_address++;
        } else {
            memcpy(attr + next_address, "\0", 1);
        }
       
    }

    AK_free(table_header);
    
    if (next_address > 0) {
        AK_EPI;
        return attr;
    } else {
        AK_free(attr);
        AK_EPI;
        return NULL;
    }
    AK_EPI;
}
예제 #7
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #8
0
/**
 * @author Dino Laktašić.
 * @brief Get attributes for a given table and store them to the char array 
 * <ol>
 * <li>Get the number of attributes in a given table</li>
 * <li>If there is no attributes return NULL</li>
 * <li>Get the table header for a given table</li>
 * <li>Initialize struct list_node</li>
 * <li>For each attribute in table header, insert attribute in the array</li>
 * <li>Delimit each new attribute with ";" (ATTR_DELIMITER)</li>
 * <li>return pointer to char array</li>
 * </ol>
 * @param *tblName name of the table
 * @result pointer to char array 
 */
char *AK_rel_eq_get_atrributes_char(char *tblName) {
    int len_attr, num_attr, next_attr;
    int next_address = 0;
    char *attr_name;
    AK_PRO;
    num_attr = AK_num_attr(tblName);

    if (num_attr == -1) {
        AK_EPI;
        return NULL;
    }

    char *attr = (char *) AK_calloc(1, sizeof (char));
    AK_header *table_header = (AK_header *) AK_get_header(tblName);

    for (next_attr = 0; next_attr < num_attr; next_attr++) {
        attr_name = (table_header + next_attr)->att_name;
        len_attr = strlen(attr_name);

        attr = (char *) AK_realloc(attr, len_attr + next_address + 1);
        memcpy(attr + next_address, attr_name, len_attr);
        next_address += len_attr;

        if (next_attr < num_attr - 1) {
            memcpy(attr + next_address, ATTR_DELIMITER, 1);
            next_address++;
        } else {
            memcpy(attr + next_address, "\0", 1);
        }
    }

    AK_free(table_header);

    if (next_address > 0) {
        AK_EPI;
        return attr;
    } else {
        AK_free(attr);
        AK_EPI;
        return NULL;
    }
}
예제 #9
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @author Matija Šestak.
 * @brief  Function that fetches zero-based index for atrribute
 * @param  *tblName table name
 * @param *attrName attribute name
 * @return zero-based index
 */
int AK_get_attr_index(char *tblName, char *attrName) {
    AK_PRO;
    if (tblName == NULL || attrName == NULL){
        AK_EPI;
        return EXIT_WARNING;
    }
    int num_attr = AK_num_attr(tblName);
    AK_header *header = AK_get_header(tblName);
    int index = 0;
    while (index < num_attr) 
	{
        if (strcmp(attrName, (header + index)->att_name) == 0)
		{
			AK_free(header);
            AK_EPI;
            return index;
        }
        index++;
    }
	AK_free(header);
    AK_EPI;
    return EXIT_WARNING;
}
예제 #10
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #11
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @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;
}
예제 #12
0
파일: table.c 프로젝트: mschatten/akdb
/**
 * @author Unknown
 * @brief Function for testing table abstraction
 * @return No return value

    @update by Ana-Marija Balen - added getRow function to the test
 */
TestResult AK_table_test() {
    AK_PRO;
    printf("table.c: Present!\n");

    printf("\n********** TABLE ABSTRACTION TEST by Matija Šestak **********\n\n");

    printf("Table \"student\":AK_print_table\n");
    AK_print_table("student");
    printf("\n");

    printf("Table \"student\": AK_table_empty: ");
    if (AK_table_empty("student"))
        printf("true\n");
    else
        printf("false\n");
    printf("\n");

    printf("Table \"student\": AK_num_attr: ");
    printf("%d\n", AK_num_attr("student"));
    printf("\n");
	
    int get_num_records;
    printf("Table \"student\": AK_get_num_records: ");
    printf("%d\n", get_num_records = AK_get_num_records("student"));
    printf("\n");

    printf("Table \"student\": AK_get_row: ");
    
    int i;

    AK_header *head = AK_get_header("student");
    int num_attr = AK_num_attr("student");
    int len[num_attr];
    for (i = 0; i < num_attr; i++) {
            len[i] = strlen((head + i)->att_name);
    }

    AK_print_row(len, AK_get_row(0,"student"));
    printf("\n");

    printf("Table \"student\": AK_get_attr_name for index 3: ");
    int get_attr_name;
    printf("%s\n", get_attr_name = AK_get_attr_name("student", 3));
    printf("\n");

    int get_attr_index;
    printf("Table \"student\": AK_get_attr_index of \"year\": ");
    printf("%d\n", get_attr_index = AK_get_attr_index("student", "year"));
    printf("\n");
	
    int tuple_to_string;
    printf("Table \"student\": AK_get_tuple for row=0, column=1:");
    printf("%s\n", tuple_to_string = AK_tuple_to_string(AK_get_tuple(0, 1, "student")));
	
	if (get_num_records != EXIT_WARNING & get_attr_name != NULL & get_attr_index != EXIT_WARNING & tuple_to_string != NULL) {
	  printf("\nTest succeeded!\n");
    }
    else{
	  printf("\nTest failed!\n");
    }
	
    AK_EPI;
    return TEST_result(0,0);
}
예제 #13
0
/**
 * @author Dino Laktašić.
 * @brief Function for testing rel_eq_selection
 * @return No return value
 */
void AK_rel_eq_selection_test() {
    AK_PRO;
    printf("rel_eq_selection.c: Present!\n");
    printf("\n********** REL_EQ_SELECTION TEST by Dino Laktašić **********\n");

    //create header
    AK_header t_header[MAX_ATTRIBUTES];
    AK_header *temp;

    temp = (AK_header*) AK_create_header("id", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("firstname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 1, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("job", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 2, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("year", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 3, temp, sizeof (AK_header));
    temp = (AK_header*) AK_create_header("tezina", TYPE_FLOAT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header + 4, temp, sizeof (AK_header));
    memset(t_header + 5, '\0', MAX_ATTRIBUTES - 5);

    //create table
    char *tblName = "profesor";

    int startAddress = AK_initialize_new_segment(tblName, SEGMENT_TYPE_TABLE, t_header);

    if (startAddress != EXIT_ERROR)
        printf("\nTABLE %s CREATED!\n", tblName);

    printf("rel_eq_selection_test: After segment initialization: %d\n", AK_num_attr(tblName));

    //create header
    AK_header t_header2[MAX_ATTRIBUTES];
    AK_header *temp2;

    temp2 = (AK_header*) AK_create_header("mbr", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("firstname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 1, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("lastname", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 2, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("year", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 3, temp2, sizeof (AK_header));
    temp2 = (AK_header*) AK_create_header("weight", TYPE_FLOAT, FREE_INT, FREE_CHAR, FREE_CHAR);
    memcpy(t_header2 + 4, temp2, sizeof (AK_header));
    memset(t_header2 + 5, '\0', MAX_ATTRIBUTES - 5);

    //create table
    char *tblName2 = "student";

    int startAddress2 = AK_initialize_new_segment(tblName2, SEGMENT_TYPE_TABLE, t_header2);

    if (startAddress2 != EXIT_ERROR)
        printf("\nTABLE %s CREATED!\n", tblName2);

    printf("rel_eq_selection_test: After segment initialization: %d\n", AK_num_attr(tblName2));
    //-----------------------------------------------------------------------------------------

    //Init list and insert elements (Query parser output)
    struct list_node *expr = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&expr);

    //Commutativity of Selection and Projection
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L1` 100 >", sizeof ("`L1` 100 >"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "p", sizeof ("p"), expr);
    Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "L1;L2;L3;L4", sizeof ("L1;L2;L3;L4"), expr); //projection attribute
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "p", sizeof ("p"), expr);
    Ak_InsertAtEnd_L3(TYPE_ATTRIBS, "L1;L4;L3;L2;L5", sizeof ("L1;L4;L3;L2;L5"), expr);

    //Cascade of Selection and Commutativity of Selection
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L1` 100 >", sizeof ("`L1` 100 >"), expr);
    //
    //Commutativity of Selection and set operations (Union, Intersection, and Set difference)
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`L2` 100 > `L3` 50 < OR", sizeof ("`L2` 100 > `L3` 50 < OR"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "R", sizeof ("R"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "S", sizeof ("S"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "u", sizeof ("u"), expr); //u, i, e

    //Commutativity of Selection and Theta join (or Cartesian product)
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "s", sizeof ("s"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`job` 'teacher' = `mbr` 50 < AND", sizeof ("`job` 'teacher' = `mbr` 50 < AND"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "student", sizeof ("student"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERAND, "profesor", sizeof ("profesor"), expr);
    Ak_InsertAtEnd_L3(TYPE_OPERATOR, "t", sizeof ("t"), expr);
    Ak_InsertAtEnd_L3(TYPE_CONDITION, "`mbr` 50 = `job` 'teacher' = AND", sizeof ("`mbr` 50 = `job` 'teacher' = AND"), expr); //theta join attribute

    //printf("\nRA expr. before rel_eq optimization:\n");
    //AK_print_rel_eq_projection(expr);
    AK_print_rel_eq_selection(AK_rel_eq_selection(expr));

    if (DEBUG_ALL) {
        printf("\n------------------> TEST_SELECTION_FUNCTIONS <------------------\n\n");

        char *test_cond1, *test_cond2;
        char *test_table;
        char *cond_attr1, *cond_attr2;

        test_table = "profesor";
        test_cond1 = "`mbr` 100 > `firstname` 50 < AND `id` 'A' > OR";
        test_cond2 = "`id` 100 > `firstname` 50 < AND `job` 'teacher' = AND";

        cond_attr1 = AK_rel_eq_cond_attributes(test_cond1);
        cond_attr2 = AK_rel_eq_cond_attributes(test_cond2);

        printf("IS_SET_SUBSET_OF_LARGER_SET_TEST: (%i)\n\n", AK_rel_eq_is_attr_subset(cond_attr1, cond_attr2));
        printf("GET_ALL_TABLE_ATTRIBUTES_TEST   : (%s)\n\n", AK_rel_eq_get_atrributes_char(test_table));
        printf("GET_CONDITION_ATTRIBUTES_TEST   : (%s)\n\n", AK_rel_eq_cond_attributes(test_cond1));
        printf("COMMUTE_WITH_THETA_JOIN_TEST    : (%s)\n\n", AK_rel_eq_commute_with_theta_join(test_cond1, test_table));
        printf("CONDITION_SHARE_ATTRIBUTES_TEST : (%i)\n", AK_rel_eq_share_attributes(cond_attr1, cond_attr2));
        /**/
    } else {
        printf("...\n");
    }

    Ak_DeleteAll_L3(&expr);
    //dealocate variables ;)
    AK_EPI;
}
예제 #14
0
파일: selection.c 프로젝트: embalint/akdb
//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;
}