/* * Merge block with adjacent free blocks * Return: the pointer to the new free block */ static void *coalesce(void *block) { REQUIRES(block != NULL); REQUIRES(in_heap(block)); uint32_t *prev_block = block_prev(block); uint32_t *next_block = block_next(block); int prev_free = block_free(prev_block); int next_free = block_free(next_block); unsigned int words = block_size(block); if (prev_free && next_free) { // Case 4, both free block_delete(prev_block); block_delete(next_block); words += block_size(prev_block) + block_size(next_block) + 4; set_size(prev_block, words); block_mark(prev_block, FREE); block = (void *)prev_block; block_insert(block); ENSURES(in_list(block)); } else if (!prev_free && next_free) { // Case 2, next if free block_delete(next_block); words += block_size(next_block) + 2; set_size(block, words); block_mark(block, FREE); block_insert(block); ENSURES(in_list(block)); } else if (prev_free && !next_free) { // Case 3, prev is free block_delete(prev_block); words += block_size(prev_block) + 2; set_size(prev_block, words); block_mark(prev_block, FREE); block = (void *)prev_block; block_insert(block); ENSURES(in_list(block)); } else { // Case 1, both unfree block_insert(block); ENSURES(in_list(block)); return block; } return block; }
void blocking_generate_keys(project_t *project, uint32_t id) { size_t i, j; conjunction_t *conjunction; part_t *part; record_t *record; char buffer[5], key[1024]; record = array_get(project->d0->records, id); for(i = 0; i < array_size(project->conjunctions); i++) { conjunction = array_get(project->conjunctions, i); key[0] = '\0'; for(j = 0; j < array_size(conjunction->parts); j++) { part = array_get(conjunction->parts, j); if(!part->transform) { strcat(key, record_get_field(record, part->field)); } else if(!strcmp(part->transform, "brsoundex")) { brsoundex(record_get_field(record, part->field), buffer, 5); strcat(key, buffer); } else { handle_error("Unknown transformation"); } } if(strlen(key)) { block_insert(project->block, key, id); } } }
void * blocking_read_blocks(void *proj) { char *k, *p, *key; FILE *fh; int i, id, total; project_t *project; char line[200000]; project = (project_t *) proj; fh = fopen(project->args->blocking_file, "r"); while (fgets(line, sizeof(line), fh)) { p = strtok(line, ":"); key = p; p = strtok(NULL, ":"); total = atoi(p); p = strtok(NULL, ":"); for (i = 0; i < total; i++) { k = strtok(p, " "); while(k) { id = atoi(k + 1); block_insert(project->block, key, id); k = strtok(NULL, " "); } } } return NULL; }
/* * Place the block and potentially split the block * Return: Nothing */ static void place(void *block, unsigned int awords) { REQUIRES(awords >= 2 && awords % 2 == 0); REQUIRES(block != NULL); REQUIRES(in_heap(block)); REQUIRES(in_list(block)); unsigned int cwords = block_size(block); //the size of the given freeblock block_delete(block); // delete block from the seg list ENSURES(!in_list(block)); if ((cwords - awords) >= 4) { set_size(block, awords); block_mark(block, ALLOCATED); block = block_next(block); set_size(block, cwords - awords - 2); block_mark(block, FREE); block_insert(block); ENSURES(in_list(block)); } else { set_size(block, cwords); block_mark(block, ALLOCATED); } }
/* relase po with size N to AVAIL list */ void dkbtfree(void * x){ assert(x!=NULL); node_t * po=x; node_t * block; block=block_merge_left(get_block_pprv(po), po); block=block_merge_right(block, get_block_pnxt(block));/* return new block */ set_block_free(block); set_prev_free(get_block_pnxt(block)); set_prev_used(block); block_insert(block); /*insert into dll */ }
void ally_set(allies **p_al, struct faction *f, int status) { while (*p_al) { allies *al = *p_al; int i = block_search(al, f); if (i != BLOCKSIZE) { if (status == 0) { if (--al->num != i) { al->factions[i] = al->factions[al->num]; al->status[i] = al->status[al->num]; /* TODO: repair heap up or down */ } else if (al->num == 0) { *p_al = al->next; free(al); return; } } else { al->status[i] = status; } return; } if (al->num < BLOCKSIZE) { if (status > 0) { block_insert(al, f, status); } return; } p_al = &al->next; } if (status > 0) { *p_al = calloc(1, sizeof(allies)); block_insert(*p_al, f, status); } }
void test_block() { int i; block_t *block; block = block_new(); for(i = 0; i < VAL; i++) block_insert(block, KEY, i); assert_int_equal(block_size(block), 1); block_foreach(block, test_block_foreach, NULL); block_foreach_remove(block, test_block_foreach_rm, NULL); assert_int_equal(block_size(block), 0); block_free(block); }
/* * realloc - you may want to look at mm-naive.c */ void *realloc(void *oldptr, size_t size) { if (oldptr == NULL) // if oldptr is NULL, this works as malloc(size) return malloc(size); if (size == 0) { // if size is 0, this works as free(oldptr) free(oldptr); return NULL; } uint32_t *block = block_block(oldptr); REQUIRES(in_heap(block)); REQUIRES(!block_free(block)); unsigned int words = block_size(block); // old size in words unsigned int nwords; // new size in words uint32_t * ptr; // temp ptr /* Adjust size to include alignment and convert to multipes of 4 bytes */ if (size <= DSIZE) nwords = 2; else nwords = (((size) + (DSIZE-1)) & ~0x7) / WSIZE; /* if new size is the same as old size or the old size is larger but no larger * than 4 words, return oldptr without spliting */ //printf("RE, words = %d, nwords = %d\n", words, nwords); if (nwords == words || (words > nwords && words - nwords < 4)) return oldptr; else if (nwords < words) { /* if old size is at least 4 words larger than new size * return oldptr with spliting */ set_size(block, nwords); block_mark(block, ALLOCATED); ptr = block_next(block); ENSURES(words - nwords - 2 < words); set_size(ptr, words - nwords - 2); block_mark(ptr, FREE); block_insert(ptr); return oldptr; } else { /* if old size is smaller than new size, look for more space */ ptr = block_next(block); if (block_free(ptr)) { ENSURES(in_list(ptr)); // if next block is free unsigned int owords = block_size(ptr); //size of next blockdd int remain = owords + 2 - (nwords - words); if (remain >= 4) { // the next free block is enough large to split block_delete(ptr); set_size(block, nwords); block_mark(block, ALLOCATED); ptr = block_next(block); set_size(ptr, owords - (nwords - words)); block_mark(ptr, FREE); block_insert(ptr); return oldptr; } else if (remain >= 0) { // the next free block can not split block_delete(ptr); set_size(block, words + owords + 2); block_mark(block, ALLOCATED); return oldptr; } } /* the next free block is too small, or * next block is not free, malloc whole new one. */ ptr = malloc(size); /* Copy the old data. */ memcpy(ptr, oldptr, block_size(block) * WSIZE); /* Free the old block. */ free(oldptr); return ptr; } }