示例#1
0
/*
 * 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;
 } 
示例#2
0
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);
    }
  }
}
示例#3
0
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;
}
示例#4
0
/*
 * 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);
    }    
 }
示例#5
0
文件: DKbt_p.c 项目: fangbin/mem
/* 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 */
}
示例#6
0
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);
    }
}
示例#7
0
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);
}
示例#8
0
/*
 * 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;
    }
}