コード例 #1
0
ファイル: table.c プロジェクト: mschatten/akdb
/**
 * @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;
}
コード例 #2
0
ファイル: memoman.c プロジェクト: embalint/akdb
/**
  * @author Matija Novak, updated by Matija Šestak( function now uses caching)
  * @brief Function to find AK_free space in some block betwen block addresses. It's made for insert_row()
  * @param address addresses of extents
  * @return address of the block to write in
 */
int AK_find_AK_free_space(table_addresses * addresses)
{
    AK_mem_block *mem_block;
    int from = 0, to = 0, j = 0, i = 0;
    AK_PRO;
    Ak_dbg_messg(HIGH, MEMO_MAN, "find_AK_free_space: Searching for block that has AK_free space < 500 \n");

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

            //searching block
            for (i = from; i <= to; i++)
            {
                mem_block = AK_get_block(i);
                int AK_free_space_on = mem_block->block->AK_free_space;

                Ak_dbg_messg(HIGH, MEMO_MAN, "find_AK_free_space: FREE SPACE %d\n", mem_block->block->AK_free_space);

                if ((AK_free_space_on < MAX_FREE_SPACE_SIZE) &&
                        (mem_block->block->last_tuple_dict_id < MAX_LAST_TUPLE_DICT_SIZE_TO_USE))  //found AK_free block to write
                {
                    AK_EPI;
                    return i;
                }
            }
        }
        else break;
    }

    //I cant call function from memoman must consider another solution to place these functions
    int adr = -1;

    //need to create new extent
    AK_EPI;
    return adr;
}
コード例 #3
0
ファイル: hash.c プロジェクト: mschatten/akdb
/**
  * @author Mislav Čakarić
  * @brief Function that inserts a bucket to block
  * @param indexName name of index
  * @param data content of bucket stored in char array
  * @param type type of bucket (MAIN_BUCKET or HASH_BUCKET)
  * @return address structure with data where the bucket is stored 
 */
struct_add* Ak_insert_bucket_to_block(char *indexName, char *data, int type) {
    int size, id;
    AK_PRO;
    struct_add *add = (struct_add*) AK_malloc(sizeof (struct_add));
    add->addBlock = 0;
    add->indexTd = 0;

    int adr_to_write = (int) AK_find_AK_free_space(AK_get_index_addresses(indexName));
    if (adr_to_write == -1)
        adr_to_write = (int) AK_init_new_extent(indexName, SEGMENT_TYPE_INDEX);
    if (adr_to_write == 0){
	AK_EPI;
        return add;
    }

    AK_block *block = (AK_block*) AK_read_block(adr_to_write);

    Ak_dbg_messg(HIGH, INDICES, "insert_bucket_to_block: Position to write (tuple_dict_index) %d\n", adr_to_write);

    switch (type) {
        case MAIN_BUCKET:
            size = sizeof (main_bucket);
            break;
        case HASH_BUCKET:
            size = sizeof (hash_bucket);
            break;
    }
    id = block->last_tuple_dict_id + 1;
    memcpy(&block->data[block->AK_free_space], data, size);
    block->tuple_dict[id].address = block->AK_free_space;
    block->AK_free_space += size;
    block->tuple_dict[id].type = type;
    block->tuple_dict[id].size = size;
    block->last_tuple_dict_id = id;
    AK_write_block(block);

    add->addBlock = adr_to_write;
    add->indexTd = id;
    AK_EPI;
    return add;
}
コード例 #4
0
ファイル: union.c プロジェクト: embalint/akdb
/**
 * @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;
}
コード例 #5
0
ファイル: filesearch.c プロジェクト: embalint/akdb
/**
  * @author Miroslav Policki
  * @brief Function for testing file search
  * @return No return value
  */
void Ak_filesearch_test() {
    int i;
    double f;
    AK_mem_block *mem_block, tmp;
    AK_header hBroj_int[4], *hTmp;
    struct list_node *row_root;
    AK_PRO;
    // create table and fill it for testing purposes
    hTmp = (AK_header *) AK_create_header("Number int", TYPE_INT, FREE_INT, FREE_CHAR, FREE_CHAR);
    hBroj_int[0] = *hTmp;
    hTmp = (AK_header *) AK_create_header("Number float", TYPE_FLOAT, FREE_INT, FREE_CHAR, FREE_CHAR);
    hBroj_int[1] = *hTmp;
    hTmp = (AK_header *) AK_create_header("Varchar column", TYPE_VARCHAR, FREE_INT, FREE_CHAR, FREE_CHAR);
    hBroj_int[2] = *hTmp;
    memset(&hBroj_int[3], 0, sizeof (AK_header));

    if (EXIT_ERROR == AK_initialize_new_segment("filesearch test table", SEGMENT_TYPE_TABLE, hBroj_int)) {
        printf("filesearch_test: ERROR. Unable to create \"filesearch test table \"\n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    row_root = AK_malloc(sizeof (struct list_node));
    if (row_root == NULL) {
        printf("filesearch_test: ERROR. Cannot allocate row_root.\n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    for (i = -10, f = -i; i < 10; i++, f = -i) {
        Ak_Init_L3(&row_root);
        Ak_Insert_New_Element(TYPE_INT, &i, "filesearch test table", "Number int", row_root);
        Ak_Insert_New_Element(TYPE_FLOAT, &f, "filesearch test table", "Number float", row_root);
        Ak_Insert_New_Element(TYPE_VARCHAR, "test text", "filesearch test table", "Varchar column", row_root);
        Ak_insert_row(row_root);
        Ak_DeleteAll_L3(&row_root);
    }

    AK_free(row_root);

    // filesearch usage example starts here
    {
        char *szTmp;
        search_params sp[3];
        search_result sr;
        int iLower, iUpper;
        double dTmp;

        sp[0].szAttribute = "Varchar column";
        sp[0].iSearchType = SEARCH_ALL;

        sp[1].szAttribute = "Number int";
        sp[1].iSearchType = SEARCH_RANGE;
        iLower = -5;
        iUpper = 5;
        sp[1].pData_lower = &iLower;
        sp[1].pData_upper = &iUpper;

        sp[2].szAttribute = "Number float";
        sp[2].iSearchType = SEARCH_PARTICULAR;
        dTmp = 2;
        sp[2].pData_lower = &dTmp;

        Ak_dbg_messg(LOW, FILE_MAN, "Calling AK_search_unsorted");
        sr = AK_search_unsorted("filesearch test table", sp, 3);

        for (i = 0; i < sr.iNum_tuple_addresses; i++) {
            //mem_block = AK_get_block (sr.aiBlocks[i]); // caching should be used when available
            mem_block = &tmp;
            mem_block->block = (AK_block *) AK_read_block(sr.aiBlocks[i]);

            printf("Found:%d\n", *((int *) (mem_block->block->data + mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 0].address)));
            printf("Found:%f\n", *((double *) (mem_block->block->data + mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 1].address)));

            szTmp = AK_malloc(mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 2].size + 1);
            memcpy(szTmp, mem_block->block->data + mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 2].address, mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 2].size);
            szTmp[mem_block->block->tuple_dict[sr.aiTuple_addresses[i] + 2].size] = '\0';
            printf("Found:%s\n", szTmp);
            AK_free(szTmp);
        }

        AK_deallocate_search_result(sr);
    }
    AK_EPI;
}
コード例 #6
0
ファイル: difference.c プロジェクト: mschatten/akdb
/**
 * @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;
}
コード例 #7
0
ファイル: rel_eq_selection.c プロジェクト: embalint/akdb
/**
 * @author Dino Laktašić.
 * @brief Main function for generating RA expresion according to selection equivalence rules 
 * @param *list_rel_eq RA expresion as the struct list_node
 * @return optimised RA expresion as the struct list_node
 */
struct list_node *AK_rel_eq_selection(struct list_node *list_rel_eq) {
    int step; //, exit_cond[5] = {0};
    AK_PRO;
    //Initialize temporary linked list
    struct list_node *temp = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&temp);

//    struct list_node *list_split_sel;
    struct list_node *tmp, *temp_elem, *temp_elem_prev, *temp_elem_next;
    struct list_node *list_elem_next, *list_elem = (struct list_node *) Ak_First_L2(list_rel_eq);

    //Iterate through all the elements of RA linked list
    while (list_elem != NULL) {

        switch (list_elem->type) {

            case TYPE_OPERATOR:
                Ak_dbg_messg(LOW, REL_EQ, "\nOPERATOR '%c' SELECTED\n", list_elem->data[0]);
                Ak_dbg_messg(LOW, REL_EQ, "----------------------\n");
                temp_elem = (struct list_node *) Ak_End_L2(temp);
                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                list_elem_next = (struct list_node *) Ak_Next_L2(list_elem);

                switch (list_elem->data[0]) {
                        //Commutativity of Selection and Projection.
                    case RO_PROJECTION:
                        step = -1;

                        if (temp_elem != NULL) {
                            while (temp_elem != NULL) {
                                if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                    if (temp_elem->type == TYPE_CONDITION) {
                                        temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                        if ((AK_rel_eq_can_commute(list_elem_next, temp_elem) == EXIT_FAILURE) &&
                                                (temp_elem_prev->data[0] == RO_SELECTION) && (temp_elem_prev->type == TYPE_OPERATOR)) {
                                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                                            step++;
                                            break;
                                        } else if ((AK_rel_eq_can_commute(list_elem_next, temp_elem) == EXIT_SUCCESS) &&
                                                (temp_elem_prev->data[0] == RO_SELECTION) && (temp_elem_prev->type == TYPE_OPERATOR)) {
                                        	Ak_InsertBefore_L2(list_elem->type, list_elem->data, list_elem->size, &temp_elem_prev, &temp);
                                        	Ak_InsertBefore_L2(list_elem_next->type, list_elem_next->data, list_elem_next->size, &temp_elem_prev, &temp);
                                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                                            step++;
                                            break;
                                        }
                                    }
                                }
                                temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                            }
                        }

                        if (temp_elem == NULL || step != 0) {
                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        }

                        list_elem = list_elem->next;
                        break;

                        //Cascade of Selection and Commutativity of Selection
                    case RO_SELECTION:

                        //Join cascade selection conditions to one
                        if (temp_elem != NULL && temp_elem_prev != NULL && temp_elem->type == TYPE_CONDITION &&
                                temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                            temp_elem->size = temp_elem->size + list_elem_next->size + strlen(" AND") + 1; //edit to (" AND ")
                            //strcat(temp_elem->data, " AND "); //uncomment for infix use
                            strcat(temp_elem->data, " "); //remove for infix
                            strcat(temp_elem->data, list_elem_next->data);
                            strcat(temp_elem->data, " AND"); //comment if using infix format
                            memcpy(temp_elem->data, temp_elem->data, temp_elem->size);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::selection cascade - condition changed to (%s) in temp list\n", temp_elem->data);
                        } else {
                        	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                            Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                            Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        }

                        /*//Divide selection condition (slower than upper solution but can be useful in certain cases)
                        list_split_sel = AK_rel_eq_split_condition(list_elem_next->data);
                        struct list_node *list_elem_split = (struct list_node *)FirstL(list_split_sel);
						
                        if (temp_elem != NULL) {
                                tmp = temp_elem;
						
                                while (list_elem_split != NULL) {
                                        step = 0;
								
                                        while (temp_elem != NULL) {
                                                if (temp_elem->type == TYPE_CONDITION || (temp_elem->data[0] == RO_SELECTION && temp_elem->type == TYPE_OPERATOR)) {
                                                        if (temp_elem->type == TYPE_CONDITION && strcmp(list_elem_next->data, temp_elem->data) == 0) {
                                                                step = 1;
                                                        }
                                                } else if (!step){
                                                        InsertAtEndL(list_elem->type , list_elem->data, list_elem->size, temp);
                                                        InsertAtEndL(list_elem_next->type, list_elem_split->data, list_elem_split->size, temp);
                                                        break;
                                                }
                                                temp_elem = (struct list_node *)PreviousL(temp_elem, temp);
                                        }
								
                                        list_elem_split = list_elem_split->next;
                                        temp_elem = tmp;
                                }
                        } else {
                                while (list_elem_split != NULL) {
                                        InsertAtEndL(list_elem->type , list_elem->data, list_elem->size, temp);
                                        InsertAtEndL(list_elem_next->type, list_elem_split->data, list_elem_split->size, temp);
                                        list_elem_split = list_elem_split->next;
                                }
                        }
                        DeleteAllL(list_split_sel);*/
                        list_elem = list_elem->next;
                        break;

                        //Commutativity of Selection and set operations (Union, Intersection, and Set difference)
                    case RO_UNION:
                    case RO_INTERSECT:
                    case RO_EXCEPT:
                        step = -1;

                        while (temp_elem != NULL) {
                            if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                step++;
                                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                if (temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                                    if (step > 1) {
                                        tmp = temp_elem;
                                        while (tmp->type != TYPE_OPERAND) {
                                            tmp = tmp->next;
                                        }
                                        Ak_InsertAfter_L2(temp_elem->type, temp_elem->data, temp_elem->size, &tmp, &temp);
                                        Ak_InsertAfter_L2(temp_elem_prev->type, temp_elem_prev->data, temp_elem_prev->size, &tmp, &temp);
                                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", temp_elem_prev->data, temp_elem->data);
                                    }
                                    break;
                                }
                            } else {
                                break;
                            }
                            temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                        }
                        Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        break;

                    case RO_NAT_JOIN:
                    	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        list_elem = list_elem->next;
                        break;

                        //Commutativity of Selection and Theta join (or Cartesian product)
                    case RO_THETA_JOIN:
                        step = -1;

                        while (temp_elem != NULL) {
                            if (temp_elem->type == TYPE_OPERAND || temp_elem->type == TYPE_CONDITION) {
                                step++;
                                temp_elem_prev = (struct list_node *) Ak_Previous_L2(temp_elem, temp);

                                if (temp_elem_prev->data[0] == RO_SELECTION && temp_elem_prev->type == TYPE_OPERATOR) {
                                    if (step > 1) {
                                        tmp = temp_elem;
                                        temp_elem_next = temp_elem->next;

                                        char *data1, *data2;
                                        char *cond_attr1, *cond_attr2;
                                        char op_selected[2];
                                        memcpy(op_selected, temp_elem_prev->data, 2);

                                        data1 = AK_rel_eq_commute_with_theta_join(temp_elem->data, temp_elem_next->data);
                                        cond_attr1 = AK_rel_eq_cond_attributes(data1);

                                        data2 = AK_rel_eq_commute_with_theta_join(temp_elem->data, (temp_elem_next->next)->data);
                                        cond_attr2 = AK_rel_eq_cond_attributes(data2);

                                        //Debug lines - can be removed later
                                        //printf("CONDITION DATA : data: (%s),(%s), cond: (%s),(%s)\n", data1, data2, cond_attr1, cond_attr2);
                                        //printf("SHARE ATTRIBUTE: (%i)\n", AK_rel_eq_share_attributes(cond_attr1, cond_attr2));

                                        if (AK_rel_eq_share_attributes(cond_attr1, cond_attr2)) {
                                            if (cond_attr1 != NULL) {
                                                //memset(temp_elem->data, '\0', MAX_VARCHAR_LENGHT);
                                                temp_elem->size = strlen(data1) + 1;
                                                memcpy(temp_elem->data, data1, temp_elem->size);
                                                memset(temp_elem->data + temp_elem->size, '\0', MAX_VARCHAR_LENGTH - temp_elem->size);
                                                Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", temp_elem_prev->data, temp_elem->data);
                                            } else {
                                                struct list_node *temp_elem_prevprev = (struct list_node *) Ak_Previous_L2(temp_elem_prev, temp);
                                                temp_elem_prevprev->next = temp_elem;
                                                AK_free(temp_elem_prev);
                                                struct list_node *temp_elem_prev = temp_elem_prevprev;

                                                temp_elem_prev->next = temp_elem_next;
                                                AK_free(temp_elem);
                                                struct list_node *temp_elem = temp_elem_next;
                                                temp_elem_next = temp_elem->next;
                                                tmp = temp_elem;
                                            }

                                            while (tmp->type != TYPE_OPERAND) {
                                                tmp = tmp->next;
                                            }

                                            if (cond_attr2 != NULL) {
                                                memset(data2 + strlen(data2), '\0', 1);
                                                Ak_InsertAfter_L2(temp_elem->type, data2, strlen(data2) + 1, &tmp, &temp);
                                                Ak_InsertAfter_L2(TYPE_OPERATOR, op_selected, 2, &tmp, &temp);
                                                Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with attributes (%s) in temp list\n", op_selected, data2);
                                            }
                                        }

                                        AK_free(data1);
                                        AK_free(data2);
                                        AK_free(cond_attr1);
                                        AK_free(cond_attr2);
                                        break;
                                    }
                                }
                            } else {
                                break;
                            }
                            temp_elem = (struct list_node *) Ak_Previous_L2(temp_elem, temp);
                        }

                        Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_InsertAtEnd_L3(list_elem_next->type, list_elem_next->data, list_elem_next->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted with condition (%s) in temp list\n", list_elem->data, list_elem_next->data);
                        list_elem = list_elem->next;
                        break;

                    case RO_RENAME:
                    	Ak_InsertAtEnd_L3(list_elem->type, list_elem->data, list_elem->size, temp);
                        Ak_dbg_messg(MIDDLE, REL_EQ, "::operator %s inserted in temp list\n", list_elem->data);
                        break;

                    default:
                        Ak_dbg_messg(LOW, REL_EQ, "Invalid operator: %s", list_elem->data);
                        break;
                }
                break;

                //additional type definition included to distinguish beetween table name and attribute/s
            case TYPE_ATTRIBS:
                //printf("::attribute '%s' inserted in the temp list\n", list_elem->data);
                break;

                //additional type definition included to distinguish beetween attribute/s and condition
            case TYPE_CONDITION:
                //printf("::condition '%s' inserted in the temp list\n", list_elem->data);
                break;

            case TYPE_OPERAND:
                Ak_dbg_messg(MIDDLE, REL_EQ, "::table_name (%s) inserted in the temp list\n", list_elem->data);
                Ak_InsertAtEnd_L3(TYPE_OPERAND, list_elem->data, list_elem->size, temp);
                break;

            default:
                Ak_dbg_messg(LOW, REL_EQ, "Invalid type: %s", list_elem->data);
                break;
        }

        list_elem = list_elem->next;
    }

    //====================================> IMPROVMENTS <=======================================
    //Recursive RA optimization (need to implement exit condition in place of each operator, ...)
    //If there is no new changes on the list return generated struct list_nodes
    //int iter_cond;
    //for (iter_cond = 0; iter_cond < sizeof(exit_cond); iter_cond++) {
    //	if (exit_cond[iter_cond] == 0) {
    ////	Edit function to return collection of the struct list_nodes
    ////	Generate next RA expr. (new plan)
    ////	temp += remain from the list_rel_eq
    //		AK_rel_eq_selection(temp);
    //	}
    //}

    Ak_DeleteAll_L3(&list_rel_eq);
    AK_EPI;
    return temp;
}
コード例 #8
0
ファイル: rel_eq_selection.c プロジェクト: embalint/akdb
/**
 * @author Dino Laktašić.
 * @brief Check if some set of attributes is subset of larger set
 * <ol>
 * <li>Tokenize set and subset of projection attributes and store each of them to it's own array</li>
 * <li>Check if the size of subset array is larger than the size of set array</li>
 * <li>if the subset array is larger return 0</li>
 * <li>else sort both arrays ascending</li>
 * <li>Compare the subset and set items at the same positions, starting from 0</li>
 * <li>if there is an item in the subset array that doesn't match attribute at the same position in the set array return 0</li>
 * <li>else continue comparing until final item in the subset array is ritched</li>
 * <li>on loop exit return EXIT_SUCCESS</li>
 * </ol> 
 * @param *set set array 
 * @param *subset subset array 
 * @return EXIT_SUCCESS if some set of attributes is subset of larger set, else returns EXIT_FAILURE
 */
int AK_rel_eq_is_attr_subset(char *set, char *subset) {
    int len_set, len_subset;
    int set_id = 0;
    int subset_id = 0;
    char *temp_set, *temp_subset;
    char *token_set, *token_subset;
    char *save_token_set, *save_token_subset;
    char *tokens_set[MAX_TOKENS] = {NULL};
    char *tokens_subset[MAX_TOKENS] = {NULL};
    AK_PRO;
    if (set == NULL || subset == NULL) {
        AK_EPI;
        return EXIT_FAILURE;
    }

    len_set = len_subset = 0;

    temp_set = (char *) AK_calloc(strlen(set), sizeof (char));
    temp_subset = (char *) AK_calloc(strlen(subset), sizeof (char));

    memcpy(temp_set, set, strlen(set));
    memcpy(temp_subset, subset, strlen(subset));

    Ak_dbg_messg(HIGH, REL_EQ, "RULE - is (%s) subset of set (%s) in rel_eq_selection\n", subset, set);

    for ((token_set = strtok_r(temp_set, ATTR_DELIMITER, &save_token_set)); token_set;
            (token_set = strtok_r(NULL, ATTR_DELIMITER, &save_token_set)), set_id++) {
        if (set_id < MAX_TOKENS - 1) {
            tokens_set[set_id] = token_set;
            len_set++;
        }
    }

    for ((token_subset = strtok_r(temp_subset, ATTR_DELIMITER, &save_token_subset)); token_subset;
            (token_subset = strtok_r(NULL, ATTR_DELIMITER, &save_token_subset)), subset_id++) {
        if (subset_id < MAX_TOKENS - 1) {
            tokens_subset[subset_id] = token_subset;
            len_subset++;
        }
    }

    if (len_set < len_subset) {
        Ak_dbg_messg(HIGH, REL_EQ, "RULE - failed (%s) isn't subset of set (%s)!\n", subset, set);
        AK_EPI;
        return EXIT_FAILURE;
    }

    qsort(tokens_set, len_set, sizeof (char *), AK_strcmp);
    qsort(tokens_subset, len_subset, sizeof (char *), AK_strcmp);

    len_set = 0;

    for (subset_id = 0; tokens_subset[subset_id] != NULL; subset_id++) {
        for (set_id = 0; tokens_set[set_id] != NULL; set_id++) {
            if (strcmp(tokens_set[set_id], tokens_subset[subset_id]) == 0) {
                len_set++;
            }
        }
    }

    if (len_set != len_subset) {
        Ak_dbg_messg(HIGH, REL_EQ, "RULE - failed (%s) isn't subset of set (%s)!\n", subset, set);
        AK_EPI;
        return EXIT_FAILURE;
    }

    AK_free(temp_set);
    AK_free(temp_subset);

    Ak_dbg_messg(HIGH, REL_EQ, "RULE - succeed (%s) is subset of set (%s).\n", subset, set);
    AK_EPI;
    return EXIT_SUCCESS;
}
コード例 #9
0
ファイル: memoman.c プロジェクト: embalint/akdb
/**
 * @author Nikola Bakoš, updated by Matija Šestak (function now uses caching), updated by Mislav Čakarić, updated by Dino Laktašić
 * @brief Function that extends the segment
 * @param table_name name of segment to extent
 * @param extent_type type of extent (can be one of:
        SEGMENT_TYPE_SYSTEM_TABLE,
        SEGMENT_TYPE_TABLE,
        SEGMENT_TYPE_INDEX,
        SEGMENT_TYPE_TRANSACTION,
        SEGMENT_TYPE_TEMP
  * @return address of new extent, otherwise EXIT_ERROR

 */
int AK_init_new_extent(char *table_name, int extent_type)
{
    char *sys_table;

    int old_size = 0;
    int new_size = 0;
    table_addresses *addresses = (table_addresses *) AK_get_segment_addresses(table_name);
    int block_address = addresses->address_from[0]; //before 1
    int block_written;

    AK_mem_block *mem_block = AK_get_block(block_address);
    int start_address = 0;
    float RESIZE_FACTOR = 0;
    int end_address;
    struct list_node *row_root;
    int obj_id = 0;
    //!!! to correct header BUG iterate through header from 0 to N-th block while there is
    //header attributes. Than create header and pass it to function for extent creation below.
    //Current implementation works only with tables with max MAX_ATTRIBUTES.
    int i = 0;
    AK_PRO;

    for (i = 0; i < MAX_EXTENTS_IN_SEGMENT; i++)
    {
        if (addresses->address_from[i] == 0)
            break;
        new_size = addresses->address_to[i] - addresses->address_from[i];
        if (new_size > old_size) //find largest extent
            old_size = new_size;
    }

    old_size++;

    if ((start_address = AK_new_extent(1, old_size, extent_type, mem_block->block->header)) == EXIT_ERROR)
    {
        printf("AK_init_new_extent: Could not allocate the new extent\n");
        AK_EPI;
        return EXIT_ERROR;
    }
    Ak_dbg_messg(HIGH, MEMO_MAN, "AK_init_new_extent: start_address=%i, old_size=%i, extent_type=%i\n", start_address, old_size, extent_type);

    switch (extent_type)
    {
    case SEGMENT_TYPE_TABLE:
        RESIZE_FACTOR = EXTENT_GROWTH_TABLE;
        sys_table = "AK_relation";
        break;
    case SEGMENT_TYPE_INDEX:
        RESIZE_FACTOR = EXTENT_GROWTH_INDEX;
        sys_table = "AK_index";
        break;
    case SEGMENT_TYPE_TRANSACTION:
        RESIZE_FACTOR = EXTENT_GROWTH_TRANSACTION;
        printf("Not implemented yet!\n");
        break;
    case SEGMENT_TYPE_TEMP:
        RESIZE_FACTOR = EXTENT_GROWTH_TEMP;
        printf("Not implemented yet!\n");
        break;
    }

    end_address = start_address + (old_size + old_size * RESIZE_FACTOR);
    //mem_block = (AK_mem_block *) AK_get_block(0);

    row_root = (struct list_node *) AK_malloc(sizeof (struct list_node));
    Ak_Init_L3(&row_root);
    //DeleteAllElements(row_root);
    Ak_Insert_New_Element(TYPE_INT, &obj_id, sys_table, "obj_id", row_root);
    Ak_Insert_New_Element(TYPE_VARCHAR, table_name, sys_table, "name", row_root);
    Ak_Insert_New_Element(TYPE_INT, &start_address, sys_table, "start_address", row_root);
    Ak_Insert_New_Element(TYPE_INT, &end_address, sys_table, "end_address", row_root);
    Ak_insert_row(row_root);
    AK_EPI;
    return start_address;
}
コード例 #10
0
ファイル: memoman.c プロジェクト: embalint/akdb
/**
* @author Matija Novak, updated by Matija Šestak(function now uses caching), modified and renamed by Mislav Čakarić
* @brief Function for geting addresses of some table
* @param table table name that you search for
* @return structure table_addresses witch contains start and end adresses of table extents, when form and to are 0 you are on the end of addresses
*/
table_addresses *AK_get_segment_addresses(char * segmentName)
{
    int i = 0;
    int AK_freeVar = 0;
    int data_adr = 0;
    int data_size = 0;
    int data_type = 0;
    int address_sys;
    char name_sys[MAX_ATT_NAME];
    char *sys_table;
    sys_table = "AK_relation";

    AK_PRO;

    Ak_dbg_messg(HIGH, MEMO_MAN,"get_segment_addresses: Serching for %s table \n", sys_table);
    AK_mem_block *mem_block = AK_get_block(0);
    for (i = 0; i < DATA_BLOCK_SIZE; i++)
    {
        memset(name_sys, 0, MAX_ATT_NAME);
        if (mem_block->block->tuple_dict[i].address == FREE_INT)
        {
            break;
        }
        data_adr = mem_block->block->tuple_dict[i].address;
        data_size = mem_block->block->tuple_dict[i].size;
        data_type = mem_block->block->tuple_dict[i].type;
        memcpy(name_sys, mem_block->block->data + data_adr, data_size);
        i++;
        data_adr = mem_block->block->tuple_dict[i].address;
        data_size = mem_block->block->tuple_dict[i].size;
        data_type = mem_block->block->tuple_dict[i].type;
        memcpy(&address_sys, mem_block->block->data + data_adr, sizeof(int));
        if (strcmp(name_sys, sys_table) == 0)
        {
            Ak_dbg_messg(HIGH, MEMO_MAN, "get_segment_addresses: Found the address of the %s table: %d \n", sys_table, address_sys);
            break;
        }
    }
    mem_block = AK_get_block(address_sys);
    table_addresses * addresses = (table_addresses *) AK_malloc(sizeof (table_addresses));
//memset(addresses->address_from, 0, MAX_EXTENTS_IN_SEGMENT);
//memset(addresses->address_to, 0, MAX_EXTENTS_IN_SEGMENT);
    for (AK_freeVar = 0; AK_freeVar < MAX_EXTENTS_IN_SEGMENT; AK_freeVar++)
    {
        addresses->address_from[AK_freeVar] = 0;
        addresses->address_to[AK_freeVar] = 0;
    }
    char name[MAX_VARCHAR_LENGTH];
    int address_from;
    int address_to;
    int j = 0;
    for (i = 0; i < DATA_BLOCK_SIZE; i++)
    {
        if (mem_block->block->tuple_dict[i].type == FREE_INT)
            break;
        if ( (mem_block->block->last_tuple_dict_id) <= i )
            break;
        i++;
        memcpy(name, &(mem_block->block->data[mem_block->block->tuple_dict[i].address]), mem_block->block->tuple_dict[i].size);
        name[ mem_block->block->tuple_dict[i].size] = '\0';
        i++;
        memcpy(&address_from, &(mem_block->block->data[mem_block->block->tuple_dict[i].address]), mem_block->block->tuple_dict[i].size);
        i++;
        memcpy(&address_to, &(mem_block->block->data[mem_block->block->tuple_dict[i].address]), mem_block->block->tuple_dict[i].size);
//if found the table that addresses we need
        if (strcmp(name, segmentName) == 0)
        {
            addresses->address_from[j] = address_from;
            addresses->address_to[j] = address_to;
            j++;
            Ak_dbg_messg(HIGH, MEMO_MAN, "get_segment_addresses(%s): Found addresses of searching segment: %d , %d \n", name, address_from, address_to);
        }
        /*if (segmentType == SEGMENT_TYPE_INDEX)
        {
            i += 2;
        }*/
    }
    AK_EPI;
    return addresses;
}
コード例 #11
0
ファイル: memoman.c プロジェクト: embalint/akdb
/**
  *  @author Matija Novak
  *  @brief Function initializes the global query memory (variable query_mem)
  *  @return EXIT_SUCCESS if the query memory has been initialized, EXIT_ERROR otherwise
 */
int AK_query_mem_AK_malloc()
{
    AK_PRO;
    Ak_dbg_messg(HIGH, MEMO_MAN, "AK_query_mem_AK_malloc: Start query_mem_AK_malloc\n");

    /// allocate memory for global variable query_mem
    if ((query_mem = (AK_query_mem *) AK_malloc(sizeof ( AK_query_mem))) == NULL)
    {
        printf("AK_query_mem_AK_malloc: ERROR. Cannot allocate query memory \n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    /// allocate memory for variable query_mem_lib which is used in query_mem->parsed
    AK_query_mem_lib * query_mem_lib;
    if ((query_mem_lib = (AK_query_mem_lib *) AK_malloc(sizeof (AK_query_mem_lib))) == NULL)
    {
        printf("AK_query_mem_AK_malloc: ERROR. Cannot allocate query library memory \n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    /// allocate memory for variable query_mem_dict which is used in query_mem->dictionary
    AK_query_mem_dict * query_mem_dict;
    if ((query_mem_dict = (AK_query_mem_dict *) AK_malloc(sizeof (AK_query_mem_dict))) == NULL)
    {
        printf("AK_query_mem_AK_malloc: ERROR. Cannot allocate query dictionary memory \n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    /// allocate memory for variable query_mem_result which is used in query_mem->result
    AK_query_mem_result * query_mem_result;
    if ((query_mem_result = (AK_query_mem_result *) AK_malloc(sizeof (AK_query_mem_result))) == NULL)
    {
        printf("  AK_query_mem_AK_malloc: ERROR. Cannot allocate query result memory \n");
        AK_EPI;
        exit(EXIT_ERROR);
    }
	query_mem_result->results=AK_malloc(MAX_QUERY_RESULT_MEMORY*sizeof(*query_mem_result->results));
	
    /// allocate memory for variable tuple_dict which is used in query_mem->dictionary->dictionary[]
    AK_tuple_dict * tuple_dict = (AK_tuple_dict *) AK_malloc(sizeof (AK_tuple_dict));
    if ((tuple_dict = (AK_tuple_dict *) AK_malloc(sizeof (AK_tuple_dict))) == NULL)
    {
        printf("  AK_query_mem_AK_malloc: ERROR. Cannot allocate tuple dictionary memory \n");
        AK_EPI;
        exit(EXIT_ERROR);
    }

    memcpy(query_mem_dict->dictionary, tuple_dict, sizeof (* tuple_dict));

    query_mem->parsed = query_mem_lib;
    query_mem->dictionary = query_mem_dict;
    query_mem->result = query_mem_result;
	//initializing values for result block status
	//by default all blocks are free
	int i=0;
	for(i=0; i<MAX_QUERY_RESULT_MEMORY; i++){
		query_mem->result->results[i].free=1;
	}
    /*	wrong way because we don't have data only adress which must be written in query_mem variables
            memcpy(query_mem->parsed, query_mem_lib, sizeof(* query_mem_lib));
            memcpy(query_mem->dictionary,query_mem_dict,sizeof(* query_mem_dict));
            memcpy(query_mem->result,query_mem_result,sizeof(* query_mem_result));*/

    Ak_dbg_messg(HIGH, MEMO_MAN, "AK_query_mem_AK_malloc: Success!\n");
    AK_EPI;
    return EXIT_SUCCESS;
}
コード例 #12
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;
}