Esempio n. 1
0
int insert(int offset, long long key) {

	long long key_promoted = -1;
	int return_value = -1;
	int new_offset = -1;
	int offset_child_right = -1;
	int offset_child_left = -1;
	page_tree *page;

	// verifica se eh necessario criar um novo no raiz
	if ((return_value = insertKey(offset, key, &offset_child_left, &offset_child_right, &key_promoted)) == PROMOTED) {
		// aloca nova pagina na ram
		allocPage(&page);
		// insere chave na nova pagina criada (ainda na RAM)
		pageInsert(page, key_promoted, offset_child_left, offset_child_right);
		//emanuel
		page->child[0] = offset_left;
		page->child[0] = offset_child_left;

		// move o ponteiro para o final do arquivo para pegar a posicao da nova pagina
		fseek(bTreeFile, 0L, SEEK_END);
		new_offset = ftell(bTreeFile);
		// salva a pagina no disco
		savePage(new_offset, page);
		update_root_offset(new_offset);
		free(page);
	}

	return return_value;
}
void runSimulation(int argc, char **argv) {
    FILE *traceFile;
    
    /*create the page table and initialize it*/
    PAGETABLE *pageTable = calloc(1, sizeof(PAGETABLE));
    pageTable->levelCount = levelCount;
    int offsetBits = ADDRESS_LENGTH - initializePageTable(pageTable, argv, (argc - levelCount));
    
    p2AddrTr trace;     //this struct contains address when fetched from trace file
    if ((traceFile = fopen(argv[argc-levelCount-1],"rb")) == NULL) {
        fprintf(stderr,"cannot open %s for reading\n",argv[argc-levelCount-1]);
        exit(1);
    }
    
    unsigned long addressCount = 0;
    while (!feof(traceFile)) {
        if (nFlag)
            if (addressCount >= limit)      //break out of loop if limit is reached
                break;
        if (NextAddress(traceFile, &trace)) {
            unsigned int address = (unsigned int)trace.addr;
            if (pageLookup(pageTable, address) == NULL) {   //Page has not been seen yet
                pageTable->misses++;
                pageInsert(pageTable, address, pageTable->frameCount);  //insert the new page
                if (pFlag) {
                    unsigned int page = address;
                    page >>= offsetBits;
                    MAP *map = pageLookup(pageTable, address);
                    fprintf(printFile, "%08X -> %08X\n", page, map->frame);
                }
            }
            else
Esempio n. 3
0
int insertKey(int offset, long long key, int* child_left_promoted, int* child_right_promoted, long long* key_promoted)
{
	page_tree *curr_page; // pagina atual para busca
	page_tree *new_page; // pagina para split
	int pos = -1; // posicao em que a chave deveria ser inserida

	// trata o caso de arvore vazia
	if (offset == NIL) {
		*key_promoted = key;
		*child_right_promoted = NIL;
		*child_left_promoted = NIL;
		return PROMOTED;
	}

	curr_page = loadPage(offset); // carrega a pagina para inspecao
	if (pageSearch(curr_page, key, &pos) == SUCCESS) {
		fprintf(stderr, "Chave ja existe na arvore\n\n");
		return ERROR;
	}

	int return_value = -1;
	int right_offset_child_promoted = -1;
	int left_offset_child_promoted = -1;
	long long key_promotion = -1;
	return_value = insertKey(curr_page->child[pos], key, &left_offset_child_promoted, &right_offset_child_promoted, &key_promotion);

	// verifica se nao eh necessaria mais nenhuma operacao na arvore
	// ou seja, a chave foi inserida mas nao ha promocao
	// ou entao a chave ja existia e foi retornado um erro
	if (return_value == NOT_PROMOTED || return_value == ERROR) {
		return return_value;
	}

	// verifica se a chave cabe na pagina atual
	if (curr_page->nKeys < ORDER-1) {
		pageInsert(curr_page, key_promotion, left_offset_child_promoted, right_offset_child_promoted);
		savePage(offset, curr_page);
		return NOT_PROMOTED;
	}

	// se a chave nao couber na pagina, realiza split
	//fprintf(stderr, "chamando split... offset vale %d e chave vale %lld\n", offset, key_promotion);

	split(key_promotion, right_offset_child_promoted, curr_page, key_promoted, child_left_promoted, child_right_promoted, &new_page);
	*child_left_promoted = offset;
	savePage(offset, curr_page); // salva a pagina atual
	savePage(*child_right_promoted, new_page); // salva a nova pagina apos split

	free(curr_page);
	free(new_page);

	return PROMOTED;
}
Esempio n. 4
0
//split(key_promotion, offset_child_promoted, curr_page, key_promoted, child_right_promoted, &new_page);
void split(const long long key_input, const int child_right_input, page_tree* page, long long* key_promoted, int* child_left_promoted, int* child_right_promoted, page_tree** new_page)
{
	int i;
	int size_split;
	int key_idx, child_idx;
	//printf("inserindo chave %lld\n", key_input);

	/*aloca nova pagina
	 *note que new_page
	 *é ponteiro **
	 */

	/*size_split terá o numero de chaves
	 * que iremos colocar na pagina nova
	 */

	allocPage(new_page);

	size_split = (ORDER -1)/2;


	/*copia as chaves do split para
	 * a nova pagina
	 */
	for(i = 0, key_idx = ORDER - 2, child_idx = ORDER -1; i < size_split; i++, key_idx--, child_idx --)
	{
		pageInsert(*new_page, page->keys[key_idx], page->child[child_idx-1], page->child[child_idx]);
		page->child[child_idx] = NIL;
		//page->child[child_idx-1] = NIL;
		page->nKeys--;

	}

	/*verifica se a chave atual é maior que a chave da direita
	 * da página antiga. CAso seja maior, será inserido
	 * na nova página, caso contrário, será inserido nova página
	 */


//	printf("comparando %d com %d\n", key_input, page->keys[ORDER-2 - size_split]);
	if(key_input > page->keys[ORDER-2 - size_split])
	{
		/*insere a chave atual*/
		pageInsert(*new_page, key_input, NIL, child_right_input);


	} else{
		/*antes o ultimo nó da pagina antiga é transferido
		 * pra pagina nova. E depois inseriamos a chave atual na pagina antiga
		 */
		pageInsert(*new_page, page->keys[ORDER -2 -size_split], page->child[ORDER-1-size_split-1], page->child[ORDER-1-size_split]);
		page->child[ORDER-1-size_split] = NIL;
		page->nKeys--;
		//page->nKeys--;
		pageInsert(page, key_input, NIL, child_right_input);

	}



	/*promovemos a chave da esquerda da nova pagina
	 * pois será a menor
	 */

	*key_promoted = (*new_page)->keys[0];
	*child_left_promoted = (*new_page)->child[0];

	//printf("==>child left promoted vale %d e key promovida vale %d\n", *child_left_promoted, *key_promoted);



	/*deslocamos as chaves de nova
	 * pagina para esquerda
	 */

	for(i = 0; i < (*new_page)->nKeys-1; i++)
	{
		(*new_page)->keys[i] = (*new_page)->keys[i+1];
		(*new_page)->child[i] = (*new_page)->child[i+1];


	}

	(*new_page)->child[i] = (*new_page)->child[i+1];
	(*new_page)->child[i+1] = NIL;

	/*remove de fato a chave na nova pagina*/
	(*new_page)->nKeys--;


	/*obtem o offset_left: Este offset é o offset
	 * da pagina antiga (que foi particionada)
	 *
	 */

	offset_left = searchKeyOnBTree(offset_root, page->keys[0]);
	*child_left_promoted = offset_left;

	//printf("||SPLIT e child left vale %d, procurei pela chave %d\n", offset_left, page->keys[0]);

	/*obtem o offset da nova pagina:
	 * basta posicionar no fim do arquivo e retornar o valor
	 * do offset em bytes
	 */


	fseek(bTreeFile, 0L, SEEK_END);
	*child_right_promoted = ftell(bTreeFile);


	//printf("conteudo da pagina atual:\n");
	//printf("%d\n", (*new_page)->keys[0]);






}