示例#1
0
void* keydb_tree(int fd, int64_t pos, struct keydb_column **list) {
  // Return a linked list of keys (stored as struct keydb_column)
  // found in the tree pointed at by pos. The caller must free the list.

  struct keydb_node* parent;
  struct keydb_node* buffer;
  struct keydb_column *mid = NULL;
  int64_t next_pos;
  int64_t n;

  buffer = key_buf_read(fd, pos);

  if (buffer == NULL) return NULL;

  if ((mid = malloc(sizeof(struct keydb_column))) == NULL) {
    perror(NULL);
    cleanup_and_exit;
  }
  mid->next = NULL;

  if (buffer->refcount <= 0) { //this record is tombstoned.
    mid->column[0] = '\0'; // Put a terminator at the start of the string.
  } else {
    memcpy(mid->column, buffer->column, KEY_LEN); // otherwise load it up.
    mid->refcount = buffer->refcount;
  }

  // Right
  if (buffer->right != 0) keydb_tree(fd, buffer->right, list);

  // Middle
  mid->next = *list;
  *list = mid;

  // Left
  if (buffer->left  != 0) keydb_tree(fd, buffer->left, list);

  free(buffer);

  return NULL;
}
示例#2
0
struct response_struct keys_command(char* token_vector[], int token_count) {

  char* part = NULL;
  char key[KEY_LEN] = "";
  int length = 0;
  int i = 0;
  int retval;
  int64_t pos = 0;
  struct keydb_node *node;
  struct keydb_column *list, *tmp, *cursor;
  bool some_content = false; // Does our key list have any keys in it?
  list = NULL; 
  char* tmp_response;
  int response_free_bytes = MSG_SIZE;
  int responselen = 0;
  int column_size;
  struct response_struct response;

  response.status = 0;
  if ((response.msg = malloc(sizeof(char) * MSG_SIZE)) == NULL) {
    perror(NULL);
    cleanup_and_exit();
  }
  bzero(response.msg, MSG_SIZE);

  for (i = 1; (part = token_vector[i]) && (i < MAX_ARGS); i++) {
    length += strlen(part);
    if (length > KEY_LEN - 1) {
      response.status = 1;
      sprintf(response.msg, "Key too large.");
      return response;
    }

    node = keydb_find(KEYDB_FD, part, pos);
    
    if (!(node = keydb_find(KEYDB_FD, part, pos))) {
      response.status = 1;
      sprintf(response.msg, "Not found.");
      return response;
    } 

    if (node->refcount <= 0) {
      response.status = 1;
      sprintf(response.msg, "Not found.");
      return response;
    } 
  
    pos = node->next;
    free(node);
    if (pos == 0) { // There is no next subtree.
      response.status = 1;
      sprintf(response.msg, "No subkeys.");
      return response;
    }

  }

  keydb_tree(KEYDB_FD, pos, &list);
  while (list) {
    if (list->column[0] != '\0') {
      column_size = strlen(list->column) + 2;
      response_free_bytes -= column_size;
      if (response_free_bytes < 1) { // need to expand response.
        responselen = strlen(response.msg);
        responselen += column_size;
        tmp_response = malloc(sizeof(char) * responselen);
        strcpy(tmp_response, response.msg);
        free(response.msg);
        response.msg = tmp_response;
        response_free_bytes = 0;
      }
      strcat(response.msg, list->column);
      strcat(response.msg, " ");
      some_content = true;
    }
    tmp = list->next;
    free(list);
    list = tmp;
  }
  
  if (!some_content) {
    sprintf(response.msg, "No subkeys.");
    response.status = 1;
  }
  response.msg[strlen(response.msg) - 1] = '\0'; // Knock out that last extra space.
  return response;
}