Exemple #1
0
/*
 * NAME:	hfs->rmdir()
 * DESCRIPTION:	delete an empty directory
 */
int hfs_rmdir(hfsvol *vol, char *path)
{
  CatKeyRec key;
  CatDataRec data;
  long parid;
  char name[HFS_MAX_FLEN + 1];
  unsigned char pkey[HFS_CATKEYLEN];

  if (v_getvol(&vol) < 0 ||
      v_resolve(&vol, path, &data, &parid, name, 0) <= 0)
    return -1;

  if (data.cdrType != cdrDirRec)
    {
      ERROR(ENOTDIR, 0);
      return -1;
    }

  if (data.u.dir.dirVal != 0)
    {
      ERROR(ENOTEMPTY, 0);
      return -1;
    }

  if (parid == HFS_CNID_ROOTPAR)
    {
      ERROR(EINVAL, 0);
      return -1;
    }

  if (vol->flags & HFS_READONLY)
    {
      ERROR(EROFS, 0);
      return -1;
    }

  /* delete directory record */

  r_makecatkey(&key, parid, name);
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) < 0)
    return -1;

  /* delete thread record */

  r_makecatkey(&key, data.u.dir.dirDirID, (char *)"");
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) < 0 ||
      v_adjvalence(vol, parid, 1, -1) < 0)
    return -1;

  return 0;
}
void bt_delete(TreeNode * root) {
    if (NULL == root) {
        // Nothing to delete.
        return;
    }

    // Delete the left subtree.
    bt_delete(root->left);

    // Delete the right subtree.
    bt_delete(root->right);

    // Delete the root node.
    delete root;
}
/*
 * A sample driver
 */
int DoData(Btree *bt, char *buffer, int mode) {
    UR ur;
    char *s;
    s = strchr(buffer, ';');
    if (!s) {
        if (mode == 0)
            s = ""; /* don't need address for deletes */
        else
            return TREE_FAIL; /* trying to add partial data */
    }
    else
        *s++ = '\0';

    strncpy(ur.key, buffer, 10); /* key is first 10 characters */
    ur.key[10] = '\0';
    strncpy(ur.name, buffer, 24);
    ur.name[24] = '\0';
    strncpy(ur.addr, s, 24);
    ur.addr[24] = '\0';

    if (mode == 0)
        return bt_delete(bt, ur.key);
    else
        return bt_add(bt, &ur, ur.key);
}
Exemple #4
0
/*
 * NAME:	hfs->rmdir()
 * DESCRIPTION:	delete an empty directory
 */
int hfs_rmdir(hfsvol *vol, const char *path)
{
  CatKeyRec key;
  CatDataRec data;
  unsigned long parid;
  char name[HFS_MAX_FLEN + 1];
  byte pkey[HFS_CATKEYLEN];

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &data, &parid, name, 0) <= 0)
    goto fail;

  if (data.cdrType != cdrDirRec)
    ERROR(ENOTDIR, 0);

  if (data.u.dir.dirVal != 0)
    ERROR(ENOTEMPTY, 0);

  if (parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* delete directory record */

  r_makecatkey(&key, parid, name);
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) == -1)
    goto fail;

  /* delete thread record */

  r_makecatkey(&key, data.u.dir.dirDirID, "");
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) == -1 ||
      v_adjvalence(vol, parid, 1, -1) == -1)
    goto fail;

  return 0;

fail:
  return -1;
}
// -----------------------------------------------------------------------------
//virtual
bool Solution::Test()
{
    bool pass = true;

    {
        int nodes[] = { };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        root = invertTree(root);
        std::vector<int> v;
        bt_traverse(root, BT_TRAV_IN, v);
        pass = pass && v.empty();
        bt_delete(root);
    }

    {
        int nodes[] = { '1' };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        root = invertTree(root);
        std::vector<int> v;
        bt_traverse(root, BT_TRAV_IN, v);
        pass = pass && (v.size() == 1) && (v[0] == '1');
        bt_delete(root);
    }

    {
        int nodes[] = { '1', '2' };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        root = invertTree(root);
        std::vector<int> v;
        bt_traverse(root, BT_TRAV_IN, v);
        pass = pass && (v.size() == 2) && (v[0] == '1') && (v[1] == '2');
        bt_delete(root);
    }

    {
        int nodes[] = { '1', '2', '3' };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        root = invertTree(root);
        std::vector<int> v;
        bt_traverse(root, BT_TRAV_IN, v);
        pass = pass && (v.size() == 3) && (v[0] == '3') && (v[1] == '1') && (v[2] == '2');
        bt_delete(root);
    }

    return pass;
}
Exemple #6
0
/* Moves P around in BT to compensate for its key having
   changed.  Returns a null pointer if successful.  If P's new
   value is equal to that of some other node in BT, returns the
   other node after removing P from BT.

   This function is an optimization only if it is likely that P
   can actually retain its relative position in BT, e.g. its key
   has only been adjusted slightly.  Otherwise, it is more
   efficient to simply remove P from BT, change its key, and
   re-insert P.

   It is not safe to update more than one node's key, then to
   call this function for each node.  Instead, update a single
   node's key, call this function, update another node's key, and
   so on.  Alternatively, remove all affected nodes from the
   tree, update their keys, then re-insert all of them. */
struct bt_node *
bt_changed (struct bt *bt, struct bt_node *p)
{
  struct bt_node *prev = bt_prev (bt, p);
  struct bt_node *next = bt_next (bt, p);

  if ((prev != NULL && bt->compare (prev, p, bt->aux) >= 0)
      || (next != NULL && bt->compare (p, next, bt->aux) >= 0))
    {
      bt_delete (bt, p);
      return bt_insert (bt, p);
    }
  return NULL;
 }
// -----------------------------------------------------------------------------
//virtual
bool Solution::Test()
{
    bool pass = true;

    {
        int nodes[] = { };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        std::vector< std::vector<int> > result = levelOrderBottom(root);
        pass = pass && result.empty();
        bt_delete(root);
    }

    {
        int nodes[] = { 1 };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        std::vector< std::vector<int> > result = levelOrderBottom(root);
        pass = pass && (result.size() == 1) &&
            (result[0].size() == 1) && (result[0][0] == 1)
            ;
        bt_delete(root);
    }

    {
        int nodes[] = { 3, 9, 20, '#', '#', 15, 7 };
        BTNode<int> * root = bt_create(nodes, sizeof(nodes) / sizeof(int));
        std::vector< std::vector<int> > v = levelOrderBottom(root);
        pass = pass && (v.size() == 3) &&
            (v[0].size() == 2) && (v[0][0] == 15) && (v[0][1] == 7) &&
            (v[1].size() == 2) && (v[1][0] == 9) && (v[1][1] == 20) &&
            (v[2].size() == 1) && (v[2][0] == 3)
            ;
        bt_delete(root);
    }

    return pass;
}
int main(int argc, char * argv[]) {
    bool pass = true;

    {
        const int N = 15;
        int nodes[] = { 15, 6, 18, 3, 7, 17, 20, 2, 4, '#', 13, '#', '#', '#', '#' };
        TreeNode * root = bt_create(nodes, N, 0, '#');
        TreeNode * node15 = root;
        pass = pass && (bst_find_successor(node15)->value == 17);
        TreeNode * node13 = root->left->right->right;
        pass = pass && (bst_find_successor(node13)->value == 15);
        TreeNode * node20 = root->right->right;
        pass = pass && (bst_find_successor(node20) == NULL);
        bt_delete(root);
    }

    return (pass ? 0 : -1);
}
Exemple #9
0
int main(int argc, char** argv) {
    if (argc < (INPUT_ARG + 1)) {
        printf("***Missing input argument\n");
        return EXIT_FAILURE; 
    }

    FILE* file = fopen(argv[INPUT_ARG], FILE_READ_ONLY);
    if (!file) {
        printf("***File \"%s\" could not be found\n", argv[INPUT_ARG]);
        fclose(file);
        return EXIT_FAILURE;
    }

    linked_list* in_order_list = build_list_from_file(file, false);
    linked_list* post_order_list = build_list_from_file(file, true);
    if (in_order_list->size != post_order_list->size ||
        in_order_list->size == 0 || post_order_list->size == 0) {
        ll_delete(in_order_list);
        ll_delete(post_order_list);
        fclose(file);
        printf("***the length of the inorder and post order traversal"
               " in the input must be nonzero and equal.");
        return EXIT_FAILURE;
    }

    printf("inorder: ");
    ll_print(in_order_list);
    printf("postorder: ");
    ll_print(post_order_list);

    binary_tree* btree = new_binary_tree(in_order_list, post_order_list);
    bt_print(btree);
    
    fclose(file);
    ll_delete(in_order_list);
    free(in_order_list);
    ll_delete(post_order_list);
    free(post_order_list);
    bt_delete(btree);
    free(btree);
    return EXIT_SUCCESS;
}
Exemple #10
0
/*
 * NAME:	file->trunc()
 * DESCRIPTION:	release allocation blocks unneeded by a file
 */
int f_trunc(hfsfile *file)
{
  hfsvol *vol = file->vol;
  ExtDataRec *extrec;
  ULongInt *lglen, *pylen, alblksz, newpylen;
  unsigned int dlen, start, end;
  node n;
  int i;

  if (vol->flags & HFS_VOL_READONLY)
    goto done;

  f_getptrs(file, &extrec, &lglen, &pylen);

  alblksz  = vol->mdb.drAlBlkSiz;
  newpylen = (*lglen / alblksz + (*lglen % alblksz != 0)) * alblksz;

  if (newpylen > *pylen)
    ERROR(EIO, "file size exceeds physical length");
  else if (newpylen == *pylen)
    goto done;

  dlen  = (*pylen - newpylen) / alblksz;

  start = file->fabn;
  end   = newpylen / alblksz;

  if (start >= end)
    {
      start = file->fabn = 0;
      memcpy(&file->ext, extrec, sizeof(ExtDataRec));
    }

  n.nnum = 0;
  i      = -1;

  while (start < end)
    {
      for (i = 0; i < 3; ++i)
	{
	  unsigned int num;

	  num    = file->ext[i].xdrNumABlks;
	  start += num;

	  if (start >= end)
	    break;
	  else if (num == 0)
	    ERROR(EIO, "empty file extent");
	}

      if (start >= end)
	break;

      if (v_extsearch(file, start, &file->ext, &n) <= 0)
	goto fail;

      file->fabn = start;
    }

  if (start > end)
    {
      ExtDescriptor blocks;

      file->ext[i].xdrNumABlks -= start - end;
      dlen -= start - end;

      blocks.xdrStABN    = file->ext[i].xdrStABN + file->ext[i].xdrNumABlks;
      blocks.xdrNumABlks = start - end;

      if (v_freeblocks(vol, &blocks) == -1)
	goto fail;
    }

  *pylen = newpylen;

  file->flags |= HFS_FILE_UPDATE_CATREC;

  do
    {
      while (dlen && ++i < 3)
	{
	  unsigned int num;

	  num    = file->ext[i].xdrNumABlks;
	  start += num;

	  if (num == 0)
	    ERROR(EIO, "empty file extent");
	  else if (num > dlen)
	    ERROR(EIO, "file extents exceed physical size");

	  dlen -= num;

	  if (v_freeblocks(vol, &file->ext[i]) == -1)
	    goto fail;

	  file->ext[i].xdrStABN    = 0;
	  file->ext[i].xdrNumABlks = 0;
	}

      if (file->fabn)
	{
	  if (n.nnum == 0 &&
	      v_extsearch(file, file->fabn, 0, &n) <= 0)
	    goto fail;

	  if (file->ext[0].xdrNumABlks)
	    {
	      if (v_putextrec(&file->ext, &n) == -1)
		goto fail;
	    }
	  else
	    {
	      if (bt_delete(&vol->ext, HFS_NODEREC(n, n.rnum)) == -1)
		goto fail;

	      n.nnum = 0;
	    }
	}
      else
	memcpy(extrec, &file->ext, sizeof(ExtDataRec));

      if (dlen)
	{
	  if (v_extsearch(file, start, &file->ext, &n) <= 0)
	    goto fail;

	  file->fabn = start;
	  i = -1;
	}
    }
  while (dlen);

done:
  return 0;

fail:
  return -1;
}
Exemple #11
0
int ark_create_verbose(char *path, ARK **arkret,
                       uint64_t size, uint64_t bsize, uint64_t hcount,
                       int nthrds, int nqueue, int basyncs, uint64_t flags)
{
  int          rc = 0;
  int        p_rc = 0;
  uint64_t bcount = 0;
  uint64_t      x = 0;
  int           i = 0;
  int        tnum = 0;
  int        rnum = 0;
  scb_t     *scbp = NULL;

  KV_TRC_OPEN(pAT, "arkdb");

  if (NULL == arkret)
  {
    KV_TRC_FFDC(pAT, "Incorrect value for ARK control block: rc=EINVAL");
    rc = EINVAL;
    goto ark_create_ark_err;
  }

  if ( (flags & (ARK_KV_PERSIST_LOAD|ARK_KV_PERSIST_STORE)) && 
         (flags & ARK_KV_VIRTUAL_LUN) )
  {
    KV_TRC_FFDC(pAT, "Invalid persistence combination with ARK flags: %016lx",
                flags);
    rc = EINVAL;
    goto ark_create_ark_err;
  }

  if (nthrds <= 0)
  {
      KV_TRC_FFDC(pAT, "invalid nthrds:%d", nthrds);
      rc = EINVAL;
      goto ark_create_ark_err;
  }

  _ARK *ark = am_malloc(sizeof(_ARK));
  if (ark == NULL) {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocating ARK control structure for %ld",
                sizeof(_ARK));
    goto ark_create_ark_err;
  }

  KV_TRC(pAT, "%p path(%s) size %ld bsize %ld hcount %ld "
              "nthrds %d nqueue %d basyncs %d flags:%08lx",
              ark, path, size, bsize, hcount, 
              nthrds, nqueue, basyncs, flags);

  ark->bsize    = bsize;
  ark->rthread  = 0;
  ark->persload = 0;
  ark->nasyncs  = ((nqueue <= 0) ? ARK_MAX_ASYNC_OPS : nqueue);
  ark->basyncs  = basyncs;
  ark->ntasks   = ARK_MAX_TASK_OPS;
  ark->nthrds   = ARK_VERBOSE_NTHRDS_DEF; // hardcode, perf requirement

  // Create the KV storage, whether that will be memory based
  // or flash
  ark->ea = ea_new(path, ark->bsize, basyncs, &size, &bcount,
                    (flags & ARK_KV_VIRTUAL_LUN));
  if (ark->ea == NULL)
  {
    if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
    rc = errno;
    KV_TRC_FFDC(pAT, "KV storage initialization failed: rc/errno:%d", rc);
    goto ark_create_ea_err;
  }

  // Now that the "connection" to the store has been established
  // we need to check to see if data was persisted from a previous
  // instantiation of the KV store.
  p_rc = ark_check_persistence(ark, flags);
  if (p_rc > 0)
  {
    // We ran into an error while trying to read from
    // the store.
    rc = p_rc;
    KV_TRC_FFDC(pAT, "Persistence check failed: %d", rc);
    goto ark_create_persist_err;
  }
  else if (p_rc == -1)
  {
    KV_TRC(pAT, "NO PERSIST LOAD FLAG");
    // There was no persistence data, so we just build off
    // of what was passed into the API.

    ark->size = size;
    ark->bcount = bcount;
    ark->hcount = hcount;
    ark->vlimit = ARK_VERBOSE_VLIMIT_DEF;
    ark->blkbits = ARK_VERBOSE_BLKBITS_DEF;
    ark->grow = ARK_VERBOSE_GROW_DEF;
    ark->rthread = 0;
    ark->flags = flags;
    ark->astart = 0;
    ark->blkused = 1;
    ark->ark_exit = 0;
    ark->nactive = 0;
    ark->pers_stats.kv_cnt = 0;
    ark->pers_stats.blk_cnt = 0;
    ark->pers_stats.byte_cnt = 0;
    ark->pcmd = PT_IDLE;

    // Create the requests and tag control blocks and queues.
    x = ark->hcount / ark->nthrds;
    ark->npart  = x + (ark->hcount % ark->nthrds ? 1 : 0);

    // Create the hash table
    ark->ht = hash_new(ark->hcount);
    if (ark->ht == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Hash initialization failed: %d", rc);
      goto ark_create_ht_err;
    }

    // Create the block list
    ark->bl = bl_new(ark->bcount, ark->blkbits);
    if (ark->bl == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Block list initialization failed: %d", rc);
      goto ark_create_bl_err;
    }
    if (flags & ARK_KV_PERSIST_STORE)
    {
      ark_persistence_calc(ark);
      if (bl_reserve(ark->bl, ark->pers_max_blocks))
          {goto ark_create_bl_err;}
    }
  }
  else
  {
      KV_TRC(pAT, "PERSIST: %p path(%s) size %ld bsize %ld hcount %ld "
                  "nthrds %d nqueue %ld basyncs %d bcount %ld blkbits %ld",
                  ark, path, ark->size, ark->bsize, ark->hcount,
                  ark->nthrds, ark->nasyncs, ark->basyncs,
                  ark->bcount, ark->blkbits);
  }

  rc = pthread_mutex_init(&ark->mainmutex,NULL);
  if (rc != 0)
  {
    KV_TRC_FFDC(pAT, "pthread_mutex_init for main mutex failed: %d", rc);
    goto ark_create_pth_mutex_err;
  }

  ark->rtags = tag_new(ark->nasyncs);
  if ( NULL == ark->rtags )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Tag initialization for requests failed: %d", rc);
    goto ark_create_rtag_err;
  }

  ark->ttags = tag_new(ark->ntasks);
  if ( NULL == ark->ttags )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Tag initialization for tasks failed: %d", rc);
    goto ark_create_ttag_err;
  }

  ark->rcbs = am_malloc(ark->nasyncs * sizeof(rcb_t));
  if ( NULL == ark->rcbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for request control blocks", (ark->nasyncs * sizeof(rcb_t)));
    goto ark_create_rcbs_err;
  }

  ark->tcbs = am_malloc(ark->ntasks * sizeof(tcb_t));
  if ( NULL == ark->tcbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for task control blocks", (ark->ntasks * sizeof(rcb_t)));
    goto ark_create_tcbs_err;
  }

  ark->iocbs = am_malloc(ark->ntasks * sizeof(iocb_t));
  if ( NULL == ark->iocbs )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for io control blocks", (ark->ntasks * sizeof(iocb_t)));
    goto ark_create_iocbs_err;
  }

  ark->poolthreads = am_malloc(ark->nthrds * sizeof(scb_t));
  if ( NULL == ark->poolthreads )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation of %"PRIu64" bytes for server thread control blocks", (ark->nthrds * sizeof(scb_t)));
    goto ark_create_poolthreads_err;
  }

  for ( rnum = 0; rnum < ark->nasyncs ; rnum++ )
  {
    ark->rcbs[rnum].stat = A_NULL;
    pthread_cond_init(&(ark->rcbs[rnum].acond), NULL);
    pthread_mutex_init(&(ark->rcbs[rnum].alock), NULL);
  }

  for ( tnum = 0; tnum < ark->ntasks; tnum++ )
  {
    ark->tcbs[tnum].inb = bt_new(0, ark->vlimit, sizeof(uint64_t), 
                                       &(ark->tcbs[tnum].inblen),
                                       &(ark->tcbs[tnum].inb_orig));
    if (ark->tcbs[tnum].inb == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Bucket allocation for inbuffer failed: %d", rc);
      goto ark_create_taskloop_err;
    }

    ark->tcbs[tnum].oub = bt_new(0, ark->vlimit, sizeof(uint64_t), 
                                       &(ark->tcbs[tnum].oublen),
                                       &(ark->tcbs[tnum].oub_orig));
    if (ark->tcbs[tnum].oub == NULL)
    {
      if (!errno) {KV_TRC_FFDC(pAT, "UNSET_ERRNO"); errno=ENOMEM;}
      rc = errno;
      KV_TRC_FFDC(pAT, "Bucket allocation for outbuffer failed: %d", rc);
      goto ark_create_taskloop_err;
    }

    //ark->tcbs[tnum].vbsize = bsize * 1024;
    ark->tcbs[tnum].vbsize = bsize * 256;
    ark->tcbs[tnum].vb_orig = am_malloc(ark->tcbs[tnum].vbsize);
    if (ark->tcbs[tnum].vb_orig == NULL)
    {
      rc = ENOMEM;
      KV_TRC_FFDC(pAT, "Out of memory allocation for %"PRIu64" bytes for variable size buffer", (bsize * 1024));
      goto ark_create_taskloop_err;
    }
    ark->tcbs[tnum].vb = ptr_align(ark->tcbs[tnum].vb_orig);
  }

  *arkret = (void *)ark;

  ark->pts = (PT *)am_malloc(sizeof(PT) * ark->nthrds);
  if ( ark->pts == NULL )
  {
    rc = ENOMEM;
    KV_TRC_FFDC(pAT, "Out of memory allocation for %"PRIu64" bytes for server thread data", (sizeof(PT) * ark->nthrds));
    goto ark_create_taskloop_err;
  }

  for (i = 0; i < ark->nthrds; i++) {
    PT *pt = &(ark->pts[i]);
    scbp = &(ark->poolthreads[i]);

    memset(scbp, 0, sizeof(scb_t));

    // Start off the random start point for this thread
    // at -1, to show that it has not been part of a
    // ark_random call.
    scbp->rlast = -1;
    scbp->holds = 0;
    scbp->poolstate = PT_RUN;

    scbp->poolstats.io_cnt = 0;
    scbp->poolstats.ops_cnt = 0;
    scbp->poolstats.kv_cnt = 0;
    scbp->poolstats.blk_cnt = 0;
    scbp->poolstats.byte_cnt = 0;

    pthread_mutex_init(&(scbp->poolmutex), NULL);
    pthread_cond_init(&(scbp->poolcond), NULL);

    scbp->rqueue = queue_new(ark->nasyncs);
    scbp->tqueue = queue_new(ark->ntasks);
    scbp->ioqueue = queue_new(ark->ntasks);

    pt->id = i;
    pt->ark = ark;
    rc = pthread_create(&(scbp->pooltid), NULL, pool_function, pt);
    if (rc != 0)
    {
      KV_TRC_FFDC(pAT, "pthread_create of server thread failed: %d", rc);
      goto ark_create_poolloop_err;
    }
  }

#if 0
  while (ark->nactive < ark->nthrds) {
    usleep(1);
    //printf("Create waiting %d/%d\n", ark->nactive, ark->nthrds);
  }
#endif

  ark->pcmd = PT_RUN;

  goto ark_create_return;

ark_create_poolloop_err:

  for (; i >= 0; i--)
  {
    scbp = &(ark->poolthreads[i]);

    if (scbp->pooltid != 0)
    {
      queue_lock(scbp->rqueue);
      queue_wakeup(scbp->rqueue);
      queue_unlock(scbp->rqueue);
      pthread_join(scbp->pooltid, NULL);

      pthread_mutex_destroy(&(scbp->poolmutex));
      pthread_cond_destroy(&(scbp->poolcond));

      if ( scbp->rqueue != NULL )
      {
        queue_free(scbp->rqueue);
      }

      if ( scbp->tqueue != NULL )
      {
        queue_free(scbp->tqueue);
      }
    
      if ( scbp->ioqueue != NULL )
      {
        queue_free(scbp->ioqueue);
      }
    }
  }

  if ( ark->pts != NULL )
  {
    am_free(ark->pts);
  }

ark_create_taskloop_err:
  for ( tnum = 0; tnum < ark->ntasks; tnum++ )
  {
    if (ark->tcbs[tnum].inb)
    {
      bt_delete(ark->tcbs[tnum].inb);
    }

    if (ark->tcbs[tnum].oub)
    {
      bt_delete(ark->tcbs[tnum].oub);
    }

    if (ark->tcbs[tnum].vb_orig)
    {
      am_free(ark->tcbs[tnum].vb_orig);
    }
  }

  for (rnum = 0; rnum < ark->nasyncs; rnum++)
  {
    pthread_cond_destroy(&(ark->rcbs[rnum].acond));
    pthread_mutex_destroy(&(ark->rcbs[rnum].alock));
  }

  if ( ark->poolthreads != NULL )
  {
    am_free(ark->poolthreads);
  }

ark_create_poolthreads_err:
  if (ark->iocbs)
  {
    am_free(ark->iocbs);
  }

ark_create_iocbs_err:
  if (ark->tcbs)
  {
    am_free(ark->tcbs);
  }

ark_create_tcbs_err:
  if (ark->rcbs)
  {
    am_free(ark->rcbs);
  }

ark_create_rcbs_err:
  if (ark->ttags)
  {
    tag_free(ark->ttags);
  }

ark_create_ttag_err:
  if (ark->rtags)
  {
    tag_free(ark->rtags);
  }

ark_create_rtag_err:
  pthread_mutex_destroy(&ark->mainmutex);

ark_create_pth_mutex_err:
  bl_delete(ark->bl);

ark_create_bl_err:
  hash_free(ark->ht);

ark_create_ht_err:
ark_create_persist_err:
  ea_delete(ark->ea);

ark_create_ea_err:
  am_free(ark);
  *arkret = NULL;

ark_create_ark_err:
  KV_TRC_CLOSE(pAT);

ark_create_return:
  return rc;
}
// -----------------------------------------------------------------------------
//virtual
bool Solution::Test()
{
    bool pass = true;

    {
        int nodes[] = {};
        BTNode<int> * p = bt_create(nodes, sizeof(nodes) / sizeof(int));
        BTNode<int> * q = bt_create(nodes, sizeof(nodes) / sizeof(int));
        pass = pass && isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    {
        int nodes[] = {1};
        BTNode<int> * p = bt_create(nodes, sizeof(nodes) / sizeof(int));
        BTNode<int> * q = bt_create(nodes, sizeof(nodes) / sizeof(int));
        pass = pass && isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    {
        int nodes[] = {1, 2, 3};
        BTNode<int> * p = bt_create(nodes, sizeof(nodes) / sizeof(int));
        BTNode<int> * q = bt_create(nodes, sizeof(nodes) / sizeof(int));
        pass = pass && isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    {
        int nodes[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '#', '5' };
        BTNode<int> * p = bt_create(nodes, sizeof(nodes) / sizeof(int));
        BTNode<int> * q = bt_create(nodes, sizeof(nodes) / sizeof(int));
        pass = pass && isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    {
        int nodes[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '#', '5' };
        BTNode<int> * p = bt_create(nodes, sizeof(nodes) / sizeof(int));
        BTNode<int> * q = p;
        pass = pass && isSameTree(p, q);
        bt_delete(p);
    }

    {
        int nodes1[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '#', '5' };
        int nodes2[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '5', '#' };
        BTNode<int> * p = bt_create(nodes1, sizeof(nodes1) / sizeof(int));
        BTNode<int> * q = bt_create(nodes2, sizeof(nodes2) / sizeof(int));
        pass = pass && !isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    {
        int nodes1[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '#', '5' };
        int nodes2[] = { '1', '2', '3', '#', '#', '4', '#', '#', '#', '#', '#', '#', '6' };
        BTNode<int> * p = bt_create(nodes1, sizeof(nodes1) / sizeof(int));
        BTNode<int> * q = bt_create(nodes2, sizeof(nodes2) / sizeof(int));
        pass = pass && !isSameTree(p, q);
        bt_delete(p);
        bt_delete(q);
    }

    return pass;
}
Exemple #13
0
void catalog_before_commit(bool is_commit)
{
/*
 * Final journal commit. Done by single transaction at a time
 */
    if (!is_commit) { return; }

    try {
        catalog_journal_record *r;
        xptr *tree;
        bt_key name;
        char * htname;

        catalog_validate_objects();

        catalog_lock_metadata();

        cs_initp();
        r = local_catalog->catalog_journal;
        while (r != NULL) {
            switch (r->type) {
              case catalog_journal_record::add_name:
                tree = &(CATALOG_NAME_TREE(r->nor.object_type));
                name.setnew(r->nor.name_to_save->name);
                if (*tree == XNULL) { *tree = bt_create(xs_string); }
                bt_insert(*tree, name, r->nor.name_to_save->obj->p);
                break;

              case catalog_journal_record::del_name:
                tree = &(CATALOG_NAME_TREE(r->nor.object_type));
                name.setnew(r->nor.name_to_save->name);
                bt_delete(*tree, name, r->nor.name_to_save->obj->p);
                htname = catalog_ht_fullname_string(r->nor.object_type, r->nor.name_to_save->name, NULL);
                local_catalog->masterdata.htable = sbtrie_delete_str(local_catalog->masterdata.htable, htname);
                free(htname);
                break;

              case catalog_journal_record::add_htable_record:
                local_catalog->masterdata.htable = sbtrie_insert_str(local_catalog->masterdata.htable, r->htr.name, r->htr.data, strlen(r->htr.data) + 2, true);
                break;
            }

            r = r->next;
            local_catalog->masterdata_updated = true;
        }

        local_catalog->catalog_journal = NULL;

        if (local_catalog->masterdata_updated) {
            WRITEP(catalog_masterblock);

            memcpy(
                &(((catalog_master_record *) XADDR(catalog_masterblock))->masterdata),
                &(local_catalog->masterdata),
                sizeof(catalog_name_trees));

            local_catalog->masterdata_updated = false;
        }

        if (!tr_globals::is_ro_mode) {
            WRITEP(catalog_masterblock);

            memcpy(
                &(((catalog_master_record *) XADDR(catalog_masterblock))->last_nid_size),
                &last_nid_size,
                sizeof(int));

            memcpy(
                ((catalog_master_record *) XADDR(catalog_masterblock))->last_nid,
                last_nid,
                last_nid_size);
        }
    } catch (ANY_SE_EXCEPTION) {
        catalog_unlock_metadata();
        throw;
    }
}
Exemple #14
0
/*
 * NAME:	hfs->delete()
 * DESCRIPTION:	remove both forks of a file
 */
int hfs_delete(hfsvol *vol, char *path)
{
  hfsfile file;
  CatKeyRec key;
  unsigned char pkey[HFS_CATKEYLEN];
  int found;

  if (v_getvol(&vol) < 0 ||
      v_resolve(&vol, path, &file.cat, &file.parid, file.name, 0) <= 0)
    return -1;

  if (file.cat.cdrType != cdrFilRec)
    {
      ERROR(EISDIR, 0);
      return -1;
    }

  if (file.parid == HFS_CNID_ROOTPAR)
    {
      ERROR(EINVAL, 0);
      return -1;
    }

  if (vol->flags & HFS_READONLY)
    {
      ERROR(EROFS, 0);
      return -1;
    }

  /* free disk blocks */

  file.vol   = vol;
  file.flags = 0;

  file.cat.u.fil.filLgLen  = 0;
  file.cat.u.fil.filRLgLen = 0;

  f_selectfork(&file, 0);
  if (f_trunc(&file) < 0)
    return -1;

  f_selectfork(&file, 1);
  if (f_trunc(&file) < 0)
    return -1;

  /* delete file record */

  r_makecatkey(&key, file.parid, file.name);
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) < 0 ||
      v_adjvalence(vol, file.parid, 0, -1) < 0)
    return -1;

  /* delete file thread, if any */

  found = v_getfthread(vol, file.cat.u.fil.filFlNum, 0, 0);
  if (found < 0)
    return -1;

  if (found)
    {
      r_makecatkey(&key, file.cat.u.fil.filFlNum, (char *)"");
      r_packcatkey(&key, pkey, 0);

      if (bt_delete(&vol->cat, pkey) < 0)
	return -1;
    }

  return 0;
}
Exemple #15
0
int ark_delete(ARK *ark) {
  int rc = 0;
  int i = 0;
  _ARK *_arkp = (_ARK *)ark;
  scb_t *scbp = NULL;

  if (NULL == ark)
  {
    rc = EINVAL;
    KV_TRC_FFDC(pAT, "Invalid ARK control block parameter: %d", rc);
    goto ark_delete_ark_err;
  }

  // Wait for all active threads to exit
  for (i = 0; i < _arkp->nthrds; i++)
  {
      scbp = &(_arkp->poolthreads[i]);
      scbp->poolstate = PT_EXIT;

      queue_lock(scbp->rqueue);
      queue_wakeup(scbp->rqueue);
      queue_unlock(scbp->rqueue);

      pthread_join(scbp->pooltid, NULL);

      queue_free(scbp->rqueue);
      queue_free(scbp->tqueue);
      queue_free(scbp->ioqueue);

      pthread_mutex_destroy(&(scbp->poolmutex));
      pthread_cond_destroy(&(scbp->poolcond));
      KV_TRC(pAT, "thread %d joined", i);
  }

  if (_arkp->poolthreads) am_free(_arkp->poolthreads);

  if (_arkp->pts) am_free(_arkp->pts);

  for ( i = 0; i < _arkp->nasyncs ; i++ )
  {
    pthread_cond_destroy(&(_arkp->rcbs[i].acond));
    pthread_mutex_destroy(&(_arkp->rcbs[i].alock));
  }

  for ( i = 0; i < _arkp->ntasks; i++ )
  {

    bt_delete(_arkp->tcbs[i].inb);
    bt_delete(_arkp->tcbs[i].oub);
    am_free(_arkp->tcbs[i].vb_orig);
  }

  if (_arkp->iocbs)
  {
    am_free(_arkp->iocbs);
  }

  if (_arkp->tcbs)
  {
    am_free(_arkp->tcbs);
  }

  if (_arkp->rcbs)
  {
    am_free(_arkp->rcbs);
  }

  if (_arkp->ttags)
  {
    tag_free(_arkp->ttags);
  }

  if (_arkp->rtags)
  {
    tag_free(_arkp->rtags);
  }

  if (!(_arkp->flags & ARK_KV_VIRTUAL_LUN))
  {
    rc = ark_persist(_arkp);
    if ( rc != 0 )
    {
      KV_TRC_FFDC(pAT, "FFDC: ark_persist failed: %d", rc);
    }
  }

  pthread_mutex_destroy(&_arkp->mainmutex);

  (void)ea_delete(_arkp->ea);
  hash_free(_arkp->ht);
  bl_delete(_arkp->bl);
  KV_TRC(pAT, "ark_delete done %p", _arkp);
  am_free(_arkp);

ark_delete_ark_err:
  KV_TRC_CLOSE(pAT);
  return rc;
}
Exemple #16
0
/*
 * NAME:	hfs->rename()
 * DESCRIPTION:	change the name of and/or move a file or directory
 */
int hfs_rename(hfsvol *vol, const char *srcpath, const char *dstpath)
{
  hfsvol *srcvol;
  CatDataRec src, dst;
  unsigned long srcid, dstid;
  CatKeyRec key;
  char srcname[HFS_MAX_FLEN + 1], dstname[HFS_MAX_FLEN + 1];
  byte record[HFS_MAX_CATRECLEN];
  unsigned int reclen;
  int found, isdir, moving;
  node n;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, srcpath, &src, &srcid, srcname, 0) <= 0)
    goto fail;

  isdir  = (src.cdrType == cdrDirRec);
  srcvol = vol;

  found = v_resolve(&vol, dstpath, &dst, &dstid, dstname, 0);
  if (found == -1)
    goto fail;

  if (vol != srcvol)
    ERROR(EINVAL, "can't move across volumes");

  if (dstid == 0)
    ERROR(ENOENT, "bad destination path");

  if (found &&
      dst.cdrType == cdrDirRec &&
      dst.u.dir.dirDirID != src.u.dir.dirDirID)
    {
      dstid = dst.u.dir.dirDirID;
      strcpy(dstname, srcname);

      found = v_catsearch(vol, dstid, dstname, 0, 0, 0);
      if (found == -1)
	goto fail;
    }

  moving = (srcid != dstid);

  if (found)
    {
      const char *ptr;

      ptr = strrchr(dstpath, ':');
      if (ptr == 0)
	ptr = dstpath;
      else
	++ptr;

      if (*ptr)
	strcpy(dstname, ptr);

      if (! moving && strcmp(srcname, dstname) == 0)
	goto done;  /* source and destination are identical */

      if (moving || d_relstring(srcname, dstname))
	ERROR(EEXIST, "can't use destination name");
    }

  /* can't move anything into the root directory's parent */

  if (moving && dstid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, "can't move above root directory");

  if (moving && isdir)
    {
      unsigned long id;

      /* can't move root directory anywhere */

      if (src.u.dir.dirDirID == HFS_CNID_ROOTDIR)
	ERROR(EINVAL, "can't move root directory");

      /* make sure we aren't trying to move a directory inside itself */

      for (id = dstid; id != HFS_CNID_ROOTDIR; id = dst.u.dthd.thdParID)
	{
	  if (id == src.u.dir.dirDirID)
	    ERROR(EINVAL, "can't move directory inside itself");

	  if (v_getdthread(vol, id, &dst, 0) <= 0)
	    goto fail;
	}
    }

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* change volume name */

  if (dstid == HFS_CNID_ROOTPAR)
    {
      if (! validvname(dstname))
	goto fail;

      strcpy(vol->mdb.drVN, dstname);
      vol->flags |= HFS_VOL_UPDATE_MDB;
    }

  /* remove source record */

  r_makecatkey(&key, srcid, srcname);
  r_packcatkey(&key, record, 0);

  if (bt_delete(&vol->cat, record) == -1)
    goto fail;

  /* insert destination record */

  r_makecatkey(&key, dstid, dstname);
  r_packcatrec(&key, &src, record, &reclen);

  if (bt_insert(&vol->cat, record, reclen) == -1)
    goto fail;

  /* update thread record */

  if (isdir)
    {
      if (v_getdthread(vol, src.u.dir.dirDirID, &dst, &n) <= 0)
	goto fail;

      dst.u.dthd.thdParID = dstid;
      strcpy(dst.u.dthd.thdCName, dstname);

      if (v_putcatrec(&dst, &n) == -1)
	goto fail;
    }
  else
    {
      found = v_getfthread(vol, src.u.fil.filFlNum, &dst, &n);
      if (found == -1)
	goto fail;

      if (found)
	{
	  dst.u.fthd.fthdParID = dstid;
	  strcpy(dst.u.fthd.fthdCName, dstname);

	  if (v_putcatrec(&dst, &n) == -1)
	    goto fail;
	}
    }

  /* update directory valences */

  if (moving)
    {
      if (v_adjvalence(vol, srcid, isdir, -1) == -1 ||
	  v_adjvalence(vol, dstid, isdir,  1) == -1)
	goto fail;
    }

done:
  return 0;

fail:
  return -1;
}
Exemple #17
0
/*
 * NAME:	hfs->delete()
 * DESCRIPTION:	remove both forks of a file
 */
int hfs_delete(hfsvol *vol, const char *path)
{
  hfsfile file;
  CatKeyRec key;
  byte pkey[HFS_CATKEYLEN];
  int found;

  if (getvol(&vol) == -1 ||
      v_resolve(&vol, path, &file.cat, &file.parid, file.name, 0) <= 0)
    goto fail;

  if (file.cat.cdrType != cdrFilRec)
    ERROR(EISDIR, 0);

  if (file.parid == HFS_CNID_ROOTPAR)
    ERROR(EINVAL, 0);

  if (vol->flags & HFS_VOL_READONLY)
    ERROR(EROFS, 0);

  /* free allocation blocks */

  file.vol   = vol;
  file.flags = 0;

  file.cat.u.fil.filLgLen  = 0;
  file.cat.u.fil.filRLgLen = 0;

  f_selectfork(&file, fkData);
  if (f_trunc(&file) == -1)
    goto fail;

  f_selectfork(&file, fkRsrc);
  if (f_trunc(&file) == -1)
    goto fail;

  /* delete file record */

  r_makecatkey(&key, file.parid, file.name);
  r_packcatkey(&key, pkey, 0);

  if (bt_delete(&vol->cat, pkey) == -1 ||
      v_adjvalence(vol, file.parid, 0, -1) == -1)
    goto fail;

  /* delete file thread, if any */

  found = v_getfthread(vol, file.cat.u.fil.filFlNum, 0, 0);
  if (found == -1)
    goto fail;

  if (found)
    {
      r_makecatkey(&key, file.cat.u.fil.filFlNum, "");
      r_packcatkey(&key, pkey, 0);

      if (bt_delete(&vol->cat, pkey) == -1)
	goto fail;
    }

  return 0;

fail:
  return -1;
}