예제 #1
0
파일: clock.c 프로젝트: lubing521/h264_VAA
int store_clk(struct clk *clk)
{
	int pos, hash;
	int k = 1, n = 1, s = 1;
	int count = 0;

	hash = get_hash_val(clk->name);
	clk_dbg("%s:pos=%d\n", clk->name, hash);
	pos = hash;

	while(1){
		count ++;
		if(hash_tab[pos] < 0)
			break;

		k++;
		n = k>>1;
		s = -s;
		pos = hash + s*n;

		if(pos < 0)
			pos += HASH_TAB_LEN;

		if(pos >= HASH_TAB_LEN)
			pos -= HASH_TAB_LEN;

		if(pos == hash)
			return -1;
	}
	clk_dbg("count = %d\n", count);
	hash_tab[pos] = clk->id;

	return pos;
}
예제 #2
0
void keydb_unlock(int64_t pos) {

  char key[1024] = "";
  int hash_number;

  sprintf(key, "%llu", pos); // turn pos into a string.
  hash_number = get_hash_val(10, key); // 2^10 = 1024. See SHM_KEYDB_BITMAP.

  sem_wait(KEYDB_LOCK);
  bit_array_clear(SHM_KEYDB_BITMAP, hash_number);
  sem_post(KEYDB_LOCK);

}
예제 #3
0
void keydb_lock(int64_t pos) {

  char key[1024] = "";
  int hash_number;

  sprintf(key, "%llu", pos); // turn pos into a string.
  hash_number = get_hash_val(10, key); // 2^10 = 1024. See SHM_KEYDB_BITMAP.

  while (1) {
    sem_wait(KEYDB_LOCK);
    if ((bit_array_test(SHM_KEYDB_BITMAP, hash_number)) == 0) {
      bit_array_set(SHM_KEYDB_BITMAP, hash_number);
      sem_post(KEYDB_LOCK);
      break;
    }
    sem_post(KEYDB_LOCK);
  }

}
예제 #4
0
파일: clock.c 프로젝트: lubing521/h264_VAA
struct clk *search_clk(const char *name)
{
	struct clk *clk;
	int hash, pos;
	int id;
	int k = 1, n = 1, s = 1;

	hash = get_hash_val(name);

	pos = hash;

	while(1){
		id = hash_tab[pos];

		if(id >= 0){
			clk = &sep0611_clk[id];

			if(!strcmp(name, clk->name)){
				return clk;
			}
		}

		k++;
		n = k>>1;
		s = -s;
		pos = hash + s*n;
		
		if(pos < 0)
			pos += HASH_TAB_LEN;

		if(pos >= HASH_TAB_LEN)
			pos -= HASH_TAB_LEN;

		if(pos == hash)
			break;
	}

	return NULL;
}
예제 #5
0
파일: roxanne_db.c 프로젝트: rtyler/Roxanne
int write_record(char* key, char* value) {

  int       len = strlen(value);
  div_t     qnr = div(len, BLOCK_SIZE);
  int       blocks = qnr.quot;
  void*     buffer;
  int       byte_count = 0;
  int       block_offset;
  int64_t   byte_offset;
  int       index_result;
  int       hash_id = get_hash_val(HASH_BITS, key); 
  int       find_result;
  
  // lock this part of the key-space to make the write atomic.
  hash_write_lock(hash_id);

  if (find(key) > 0)  { // Bail if we've got a same-key collision.
    hash_write_unlock(hash_id);
    return -2;
  }

  // Figure out how many blocks we need and then requisition
  // them from the block bitmap table.
  if (qnr.rem > 0) blocks++; // round up to the next whole block.  
  if ((block_offset = create_block_reservation(blocks)) == -1) {
    fprintf(stderr, "Failed to reserve space in the block bitmap.\n");
    hash_write_unlock(hash_id);
    return(-1);
  }

  byte_count = blocks * BLOCK_SIZE;
  byte_offset = block_offset * BLOCK_SIZE;

  // Make a temporary buffer that is at least as big as the
  // data payload that we need to write. The buffer will be
  // zero-padded on the end.
  if ((buffer = malloc(byte_count)) == NULL) {
    perror("malloc failed in write_record()");
    release_block_reservation(block_offset, blocks);
    hash_write_unlock(hash_id);
    return(-1);
  }

  bzero(buffer, byte_count);
  memcpy(buffer, value, len);
  
  // write to the appropriate location in our file
  if ((pwrite(DB_FD, buffer, byte_count, byte_offset)) == -1) {
    perror("pwrite failed in write_record");
    release_block_reservation(block_offset, blocks);
    hash_write_unlock(hash_id);
    free(buffer);
    return(-1);
  }
  free(buffer);

  // Pass the key and the block offset to the index.
  index_result = write_index(key, block_offset, blocks);
  hash_write_unlock(hash_id);
  if (index_result < 0) {
    fprintf(stderr, "write_index failed in write_record with %d.\n", index_result);
    release_block_reservation(block_offset, blocks);
    return(-1);
  }

  return 0;
}
예제 #6
0
파일: roxanne_db.c 프로젝트: rtyler/Roxanne
int delete_record(char* key) {
  void*       buffer;
  int         byte_count = 0;
  int         block_offset;
  int64_t     byte_offset;
  int64_t     pos = 0;
  int         result;
  struct idx  index_rec;
  int         hash_id = get_hash_val(HASH_BITS, key);
  
  // lock this part of the key-space to make the delete atomic.
  // No one can be creating this key while we are deleting it.
  hash_write_lock(hash_id);

  pos = find(key);

  if (pos == -1) {
    fprintf(stderr, "Call to find() failed with %lld.\n", pos);
    hash_write_unlock(hash_id);
    return(-1);
  }

  if (pos == -2) {
    hash_write_unlock(hash_id);
    return(-2); // Not in the index
  }

  // Fetch the index record so we can find the blocks to delete
  result = pread(IDX_FD, (void*)&index_rec, IDX_ENTRY_SIZE, pos);
  if (result == 0) {
    fprintf(stderr, "EOF encoutered unexpectedly.\n");
    hash_write_unlock(hash_id);
    return(-1);
  }
  if (result < IDX_ENTRY_SIZE) { // Somehow the read failed.
    perror("index read failed in function delete_record");
    hash_write_unlock(hash_id);
    return(-1);
  }

  index_rec.key[0] = '\0'; // NULL at the beginning of the key means it is free.
  result = pwrite(IDX_FD, (void*)&index_rec, IDX_ENTRY_SIZE, pos); // zap the key.
  hash_write_unlock(hash_id); // key is now deleted.

  byte_count = index_rec.length * BLOCK_SIZE;
  byte_offset = index_rec.block_offset * BLOCK_SIZE;

  // Make a temporary, zero-padded buffer that is at least as big as the
  // data payload that we need to erase. 
  if ((buffer = malloc(byte_count)) == NULL) {
    perror("malloc failed in delete_record()");
    return(-1);
  }

  bzero(buffer, byte_count);
  
  // write the zeros to the appropriate location in our file.
  if ((pwrite(DB_FD, buffer, byte_count, byte_offset)) == -1) {
    perror("pwrite failed in delete_record");
    free(buffer);
    return(-1);
  }
  free(buffer);

  // Mark these blocks as usable again.
  release_block_reservation(index_rec.block_offset, index_rec.length);

  return(0);
}
예제 #7
0
파일: roxanne_db.c 프로젝트: rtyler/Roxanne
int write_index(char* key, int block_offset, int length) {

  int         hash_id = get_hash_val(HASH_BITS, key);
  struct      idx index_rec = {};
  struct      idx* index_rec_ptr;
  int         result;
  int64_t     pos  = hash_id * IDX_ENTRY_SIZE;
  int         find_results = find(key);

  index_rec_ptr = &index_rec;

  if (find_results == -1) {
    fprintf(stderr, "find() failed when called from write_index. Don't know why.\n");
    return -1;
  }

  if (find_results > 0) {
    return -2; // record with this key already exists.
  }

  while (1) {
    result = pread(IDX_FD, (void*)index_rec_ptr, IDX_ENTRY_SIZE, pos);
    
    if (result == 0) {
      fprintf(stderr, "EOF encoutered unexpectedly.\n");
      return -1;
    }

    if (result < IDX_ENTRY_SIZE) { // Somehow the read failed.
      perror("index read failed in function write_index");
      return -1;
    } 

    // Determine if we can write on this index record, or do we need
    // to start looking down the chain.

    if (index_rec.key[0] == '\0') { // There is space here.
      // Don't change the 'next' field as it may point to addnl records in the chain.
      index_rec.block_offset = block_offset;
      index_rec.length = length;
      strncpy(index_rec_ptr->key, key, KEY_LEN - 1);
      pwrite(IDX_FD, (void*)index_rec_ptr, IDX_ENTRY_SIZE, pos); // write our key here.
      return 0;
    }
      
    // Since we are here, the test above failed. The current index record is in use.
    // If the 'next' pointer is 0, we can just create a new index record for ourself.
    if (index_rec.next == 0) { // no next index record in the chain. create one.

      // Lock the index file.
      // we don't want to compete with someone else for appending to the index file.
      if (sem_wait(IDX_APPEND_LOCK) == -1) {
        perror("call to sem_wait in write_index failed.\n");
        return(-1);
      }

      index_rec.next = lseek(IDX_FD, 0, SEEK_END);
      pwrite(IDX_FD, (void*)index_rec_ptr, IDX_ENTRY_SIZE, pos); // update current rec with pointer to next.
      pos = index_rec.next;
      index_rec.next = 0;
      index_rec.block_offset = block_offset;
      index_rec.length = length;
      strncpy(index_rec_ptr->key, key, KEY_LEN - 1);
      pwrite(IDX_FD, (void*)index_rec_ptr, IDX_ENTRY_SIZE, pos); // add a new index entry.
      sem_post(IDX_APPEND_LOCK);
      return 0;
    }

    // Since we are here, we need to keep moving down the chain til we find a blank spot or the end.
    pos = index_rec.next; // move on to next record.

  }

}
예제 #8
0
파일: roxanne_db.c 프로젝트: rtyler/Roxanne
struct db_ptr find_db_ptr(char* key) {
  // Attempts to find the key in the hash table and return a structure
  // that points to the record in the db file.
  int       hash_id = get_hash_val(HASH_BITS, key);
  struct    idx index_rec = {};
  struct    db_ptr db_rec = {.block_offset = -1, .blocks = -1};
  int       result;
  int64_t   pos  = hash_id * IDX_ENTRY_SIZE;

  while (1) {

    result = pread(IDX_FD, (void*)&index_rec, IDX_ENTRY_SIZE, pos);

    if (result == 0) {
      fprintf(stderr, "EOF encoutered unexpectedly.\n");
      return db_rec;
    }

    if (result < IDX_ENTRY_SIZE) { // Somehow the read failed.
      perror("index read failed in function find_db_ptr");
      return db_rec;
    } 

    if ((memcmp(key, index_rec.key, KEY_LEN)) == 0)  {// found a match
      db_rec.block_offset = index_rec.block_offset;
      db_rec.blocks = index_rec.length;
      return db_rec;
    }

    if ((pos = index_rec.next) == 0) return db_rec; // return if no next record. Otherwise, keep looping.
    
  }

}

int find(char* key) {
  // returns an offset in the index for the given key.
  int       hash_id = get_hash_val(HASH_BITS, key);
  struct    idx index_rec = {};
  int       result;
   int64_t  pos  = hash_id * IDX_ENTRY_SIZE;

  while (1) {

    result = pread(IDX_FD, (void*)&index_rec, IDX_ENTRY_SIZE, pos);

    if (result == 0) {
      fprintf(stderr, "EOF encoutered unexpectedly.\n");
      return -1;
    }

    if (result < IDX_ENTRY_SIZE) { // Somehow the read failed.
      perror("index read failed in function find");
      return -1;
    } 

    if ((memcmp(key, index_rec.key, KEY_LEN)) == 0)  return pos; // found

    if ((pos = index_rec.next) == 0) return -2; // no next record.

  }

}