Beispiel #1
0
/// Clear out the raw set and cooked sets. Destroy the entire
/// cooked data structure but leave the raw one present though
/// empty. This is the same as the initial (post-creation) state.
/// @param[in] ca       the object pointer
void
ca_clear_pa(ca_o ca)
{
    dict_t *dict;
    dnode_t *dnp, *next;
    pa_o pa;

    if ((dict = ca->ca_raw_pa_dict)) {
        for (dnp = dict_first(dict); dnp;) {
            next = dict_next(dict, dnp);

            pa = (pa_o)dnode_getkey(dnp);
            dict_delete(dict, dnp);
            dnode_destroy(dnp);
            pa_destroy(pa);
            dnp = next;
        }
    }

    if ((dict = ca->ca_cooked_pa_dict)) {
        for (dnp = dict_first(dict); dnp;) {
            next = dict_next(dict, dnp);

            pa = (pa_o)dnode_getkey(dnp);
            dict_delete(dict, dnp);
            dnode_destroy(dnp);
            pa_destroy(pa);
            dnp = next;
        }
        dict_destroy(ca->ca_cooked_pa_dict);
        ca->ca_cooked_pa_dict = NULL;
    }
}
Beispiel #2
0
/*
void cxml_node_free(CLOG_INFO* info, void * data) {
  CXMLNODE *node = (CXMLNODE*) data;
*/
void cxml_node_free(CLOG_INFO* info, CXMLNODE **node) {
  dnode_t *dn = NULL;

  if(NULL==node || NULL==*node) {
    return;
  }

  clog( info, CTRACE, "XML: xml_node_free(), free the attributes");
  // free the attributes
  if(NULL!=(*node)->att) {
    if(!dict_isempty((*node)->att)) {
      for (dn = dict_first((*node)->att); dn; dn = dict_next((*node)->att, dn)) {
        char *key=(char*)dnode_getkey(dn);
        char *data=(char*)dnode_get(dn);
        if(NULL!=key) free(key); key=NULL;
        if(NULL!=data) free(data); data=NULL;
      }
    }
    dict_free_nodes((*node)->att);
    dict_destroy((*node)->att);
    (*node)->att=NULL;
  }

  clog( info, CTRACE, "XML: xml_node_free(), free the name");
  // free the name
  if(NULL!=(*node)->name) cstring_free(&((*node)->name));

  clog( info, CTRACE, "XML: xml_node_free(), free the data");
  // free the data
  if(NULL!=(*node)->data) cstring_free(&((*node)->data));

  clog( info, CTRACE, "XML: xml_node_free(), free the subs");
  // free the children
  if(NULL!=(*node)->sub) {
    if(!dict_isempty((*node)->sub)) {
      for (dn = dict_first((*node)->sub); dn; dn = dict_next((*node)->sub, dn)) {
        char *key=(char*)dnode_getkey(dn);
        CXMLNODE *data=(CXMLNODE*)dnode_get(dn);
        if(NULL!=key) free(key); key=NULL;
        cxml_node_free(info, &data);
      }
    }
    dict_free_nodes((*node)->sub);
    dict_destroy((*node)->sub);
    (*node)->sub=NULL;
  }

  free((*node));
  (*node)=NULL;
  node=NULL;
}
Beispiel #3
0
static void free_imp(dnode_t *node, void *)
{
  char *key = (char *)dnode_getkey(node);
  if ( key )
   qfree(key);
  free(node);
}
Beispiel #4
0
/// Any PTXes which survived shopping are eligible to be winners,
/// as long as they've been seen and evaluated at all. This test is
/// necessary because not all commands are run in all PTXes, so the
/// fact that a PTX has not been invalidated could mean it was not
/// even evaluated.
/// This function returns the first eligible surviving PTX. It does not
/// establish a policy per se; since PTXes are stored in an order set by
/// the server, the policy of which matching PTX is 'best' can be
/// dictated by the server.
/// @return the chosen PTX id
static CCS
_shop_ptx_winner(shopping_state_s *ssp)
{
    dnode_t *dnp, *next;

    ssp->wix[0] = ssp->winner[0] = '\0';

    if (ssp->ptx_dict) {
	for (dnp = dict_first(ssp->ptx_dict); dnp;) {
	    CCS key, id;

	    next = dict_next(ssp->ptx_dict, dnp);

	    key = (CCS)dnode_getkey(dnp);
	    id = (CCS)dnode_get(dnp);

	    // Remember, only an evaluated PTX can be a winner.
	    // These are marked with a lower-case index, but
	    // convert it back to upper case before returning.
	    if (islower((int)key[0])) {
		snprintf(ssp->wix, charlen(ssp->wix), "%c%s",
		    toupper((int)key[0]), key + 1);
		snprintf(ssp->winner, charlen(ssp->winner), "%s", id);
		return ssp->winner;
	    }

	    dnp = next;
	}
    }

    return NULL;
}
Beispiel #5
0
TA_RetCode TA_DictDeletePair_S( TA_Dict *dict, const char *key )
{
   TA_PrivDictInfo *theDict;
   TA_String *stringToDelete;
   void      *valueToDelete;
   dnode_t   *node;
   TA_Libc   *libHandle;
   dict_t    *kazlibDict;

   theDict = (TA_PrivDictInfo *)dict;

   if( (theDict == NULL) || (key == NULL) )
      return TA_BAD_PARAM;
   kazlibDict = &theDict->d;
   libHandle  = theDict->libHandle;

   /* Find the key-value pair. */
   node = dict_lookup( libHandle, kazlibDict, key );

   if( node )
   {
      /* Free the 'node', the 'key' string and the 'value'. */
      stringToDelete = TA_StringFromChar( dnode_getkey(node) );
      valueToDelete  = dnode_get(node);
      dict_delete_free( libHandle, kazlibDict, node );
      TA_StringFree( TA_GetGlobalStringCache( libHandle ), stringToDelete );
      if( theDict->freeValueFunc )
         theDict->freeValueFunc( libHandle, valueToDelete );
   }
   else
      return TA_KEY_NOT_FOUND;

   return TA_SUCCESS;
}
Beispiel #6
0
/// Remove the specified PTX from the DB via its index.
/// @param[in] key      the key associated with a given PTX
/// return zero iff the node was found and successfully removed
static int
_shop_ptx_invalidate(shopping_state_s *ssp, CCS key, CCS msg, int ignored)
{
    dnode_t *dnp;
    CCS id;

    dnp = dict_lookup(ssp->ptx_dict, key);

    if (ignored && dnp) {
	id = (CCS)dnode_get(dnp);
	vb_printf(VB_WHY, "WOULD INVALIDATE %s (%s) due to '%s'", id, key, msg);
	return 0;
    }

    if (dnp) {
	id = (CCS)dnode_get(dnp);
	key = (CCS)dnode_getkey(dnp);
	vb_printf(VB_WHY, "PTX %s invalidated due to '%s'", id, msg);
	dict_delete_free(ssp->ptx_dict, dnp);
	putil_free(id);
	putil_free(key);
	return 0;
    } else {
	putil_warn("invalidated PTX %s twice", key);
	return 1;
    }
}
Beispiel #7
0
static void free_dict(dnode_t *node, void *notused) {
    m2_ws_session_id *keyptr = (m2_ws_session_id*)dnode_getkey(node);
    m2_ws_session_data *valptr = (m2_ws_session_data*)dnode_get(node);
    printf("Freeing conn_id = %d, seen %d times\n",keyptr->req->conn_id,valptr->times_seen);
    free(keyptr);
    free(valptr);
    free(node);
}
Beispiel #8
0
TA_RetCode TA_DictFree( TA_Dict *dict )
{
   TA_PrivDictInfo *theDict;

   dnode_t   *node;
   dnode_t   *next;
   TA_String *stringToDelete;
   void      *valueToDelete;
   dict_t    *kazlibDict;
   TA_Libc   *libHandle;
   int        flags;

   theDict = (TA_PrivDictInfo *)dict;

   if( theDict == NULL )
      return TA_BAD_PARAM;

   kazlibDict = &theDict->d;
   libHandle  = theDict->libHandle;

   /* Delete all the key-value pair sequentially. */
   node = dict_first( libHandle, kazlibDict );

   while (node != NULL)
   {
      /* Get the next node. */
      next = dict_next( libHandle, kazlibDict, node );

      /* Free the 'node, the 'key' string and the 'value'. */
      flags = theDict->flags;
      valueToDelete  = dnode_get(node);
      if( flags & (TA_DICT_KEY_TWO_STRING|TA_DICT_KEY_ONE_STRING) )
      {
         stringToDelete = TA_StringFromChar(dnode_getkey(node));
         dict_delete_free( libHandle, kazlibDict, node );
         TA_StringFree( TA_GetGlobalStringCache( libHandle ), stringToDelete );
      }
      else
         dict_delete_free( libHandle, kazlibDict, node );

      if( flags & TA_DICT_KEY_TWO_STRING )
      {
         /* The value is a dictionary. Delete it. */
         TA_DictFree( (TA_Dict *)valueToDelete );
      }
      else if( theDict->freeValueFunc )
         theDict->freeValueFunc( libHandle, valueToDelete );

      node = next;
   }

   /* Free the TA_PrivDictInfo */
   TA_Free( libHandle, theDict );

   return TA_SUCCESS;
}
Beispiel #9
0
TA_String *TA_DictAccessKey( TA_Dict *dict )
{
   TA_PrivDictInfo *theDict;

   theDict = (TA_PrivDictInfo *)dict;

   if( (theDict == NULL) || (theDict->accessNode == NULL) )
      return NULL;

   return TA_StringFromChar( dnode_getkey( theDict->accessNode ) );
}
Beispiel #10
0
// Mark a PTX as having been evaluated by converting its index
// to lower case (lookups are case-insensitive so this is a no-op
// from the POV of the table).
static void
_shop_ptx_mark_as_seen(shopping_state_s *ssp, CCS key) {
    dnode_t *dnp;
    CS realkey;

    if ((dnp = dict_lookup(ssp->ptx_dict, key))) {
	realkey = (CS)dnode_getkey(dnp);
	if (isupper((int)realkey[0])) {
	    realkey[0] = tolower((int)realkey[0]);
	}
    }
}
Beispiel #11
0
static int check_pdb_pool()
{
  if ( p_pool != NULL )
   return 1; // already readed
  p_pool = new PDB_pool;
  int res = p_pool->read_pdbs();
  // print all import modules
  dnode_t *node = NULL;
  for ( node = p_pool->get(node); node != NULL; node = p_pool->get(node) )
  {
    msg("Import %s\n", (char *)dnode_getkey(node));
  }
  return p_pool->pdb_count();
}
Beispiel #12
0
/// Traverses the CA, calling the specified function on each 'cooked' PA.
/// In order to enforce the conventional ordering of read-before-write
/// we go around twice, handling reads on the first pass and everything
/// else on the second.
/// @param[in] ca       the object pointer
/// @param[in] process  pointer to the callback function
/// @param[in] data     pointer which is passed to the callback
/// @return -1 on error, sum of process() return codes on success
int
ca_foreach_cooked_pa(ca_o ca, int (*process) (pa_o, void *), void *data)
{
    dict_t *dict;
    dnode_t *dnp;
    pa_o pa;
    int rc = 0, pret;

    if ((dict = ca->ca_cooked_pa_dict)) {
        for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) {
            pa = (pa_o)dnode_getkey(dnp);
            if (pa_is_read(pa)) {
                pret = process(pa, data);
                if (pret < 0) {
                    putil_int("ca_foreach_cooked_pa(%s)", pa_get_abs(pa));
                    return -1;
                } else {
                    rc += pret;
                }
            }
        }
        for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) {
            pa = (pa_o)dnode_getkey(dnp);
            if (!pa_is_read(pa)) {
                pret = process(pa, data);
                if (pret < 0) {
                    putil_int("ca_foreach_cooked_pa(%s)", pa_get_abs(pa));
                    return -1;
                } else {
                    rc += pret;
                }
            }
        }
    }

    return rc;
}
Beispiel #13
0
/// Serializes the CmdAction and writes it to the specified file descriptor.
/// On Windows this must send to a socket. On Unix it can use any
/// kind of file descriptor.
/// @param[in] ca       the object pointer
/// @param[in] fd       file descriptor to which the serialized form is sent
void
ca_write(ca_o ca, int fd)
{
    dict_t *dict;
    dnode_t *dnp, *next;
    pa_o pa;
    CCS pabuf;

    dict = ca->ca_raw_pa_dict;

    if (dict_count(dict) <= 0) {
        return;
    }

    // In case buffered files were left open by sloppy audited programs.
    fflush(NULL);

    for (dnp = dict_first(dict); dnp;) {
        pa = (pa_o)dnode_getkey(dnp);

        // Unfortunately it's too early to dcode any written files
        // since they may still be open. But we should get stats of
        // non-member read ops since they may differ in the event
        // of a distributed build. We must assume logical coherence
        // for all write ops, member and non-member.
        // In other words, read ops are allowed to be on physically
        // separate files with the same path (e.g. /usr/include/stdio.h)
        // but write ops to the same path are assumed to be to a shared file.
        // This matters in the case of a distributed build.
        if (pa_is_read(pa) && !pa_is_member(pa)) {
            (void)pa_stat(pa, 0);
        }

        if ((pabuf = pa_toCSVString(pa))) {
            if (write(fd, pabuf, strlen(pabuf)) == -1) {
                putil_syserr(0, "write()");
            }
            putil_free(pabuf);
        }

        // Dictionary bookkeeping.
        next = dict_next(dict, dnp);

        dict_delete(dict, dnp);
        dnp = next;

        pa_destroy(pa);
    }
}
Beispiel #14
0
/// Checks the list of PAs and tells us whether any of them references
/// a file which needs to be uploaded.
/// @param[in] ca       the object pointer
/// @return true if the object refers to an uploadable file
int
ca_is_uploadable(ca_o ca)
{
    dict_t *dict;
    dnode_t *dnp;
    pa_o pa;
    int rc = 0;

    if ((dict = ca->ca_cooked_pa_dict)) {
        for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) {
            pa = (pa_o)dnode_getkey(dnp);
            if (pa_get_uploadable(pa)) {
                rc++;
            }
        }
    }

    return rc;
}
Beispiel #15
0
/// Merge two CmdActions, a 'leader' and a 'donor', together. The donor
/// is then redundant.
/// @param[in] leader   the leader object pointer
/// @param[in] donor    the donor object pointer
void
ca_merge(ca_o leader, ca_o donor)
{
    CCS sub;
    dict_t *dict;
    dnode_t *dnp, *next;
    pa_o pa;

    // ASSUMPTION: aggregated CAs are composed from
    // commands run serially - i.e. any parallelism
    // is above the build-script level.

    // Stringify the donor and leave that string representation in
    // the leader for the record.
    sub = ca_format_header(donor);
    if (leader->ca_subs) {
        leader->ca_subs = (CCS)putil_realloc((void *)leader->ca_subs,
                                             (strlen(leader->ca_subs) +
                                              strlen(sub) +
                                              1) * CHARSIZE);
        strcat((CS)leader->ca_subs, sub);
    } else {
        leader->ca_subs = (CCS)putil_malloc((strlen(sub) + 1) * CHARSIZE);
        strcpy((CS)leader->ca_subs, sub);
    }
    putil_free(sub);

    // Traverse the donor's raw list of PA's and move them into the leader's.
    if ((dict = donor->ca_raw_pa_dict)) {
        for (dnp = dict_first(dict); dnp;) {
            next = dict_next(dict, dnp);

            pa = (pa_o)dnode_getkey(dnp);
            ca_record_pa(leader, pa);
            dict_delete(dict, dnp);
            dnode_destroy(dnp);
            dnp = next;
        }
        dict_destroy(donor->ca_raw_pa_dict);
        donor->ca_raw_pa_dict = NULL;
    }
}
Beispiel #16
0
/// Free all data structures allocated by _shop_ptx_init().
static void
_shop_ptx_destroy(dict_t *dict)
{
    dnode_t *dnp, *next;

    if (dict) {
	for (dnp = dict_first(dict); dnp;) {
	    CCS key, id;

	    next = dict_next(dict, dnp);

	    key = (CCS)dnode_getkey(dnp);
	    id = (CCS)dnode_get(dnp);
	    dict_delete_free(dict, dnp);
	    putil_free(key);
	    putil_free(id);
	    dnp = next;
	}
	dict_destroy(dict);
    }
}
Beispiel #17
0
void
process_from_founded_sig(dict_t *dict)
{
  if ( !dict || !dict_count(dict) )
   return;
  if ( !check_rpd_count(true) )
   return;
  dnode_t *node;
  pdb_class *pc;
  char *c_name;
  ea_t ea;
  for ( node = dict_first(dict); node; node = dict_next(dict, node) )
  {
    c_name = (char *)dnode_get(node);
    ea = (ea_t)dnode_getkey(node);
    pc = p_pool->find_class(c_name);
    if ( !pc )
     continue;
    fill_vtbl(c_name, ea, pc);
  }
}
Beispiel #18
0
TA_RetCode TA_DictDeletePair_S2( TA_Dict *dict, const char *key1, const char *key2 )
{
   TA_PrivDictInfo *theDict;
   TA_String *stringToDelete;
   dnode_t   *node;
   TA_Dict   *subDict;
   TA_RetCode retCode;
   TA_Libc   *libHandle;
   dict_t    *kazlibDict;

   theDict = (TA_PrivDictInfo *)dict;

   if( (theDict == NULL)    ||
       (key1 == NULL)       || 
       (key2 == NULL))
      return TA_BAD_PARAM;
   kazlibDict = &theDict->d;
   libHandle  = theDict->libHandle;

   /* Find the dictionary for this 'key1'. */
   node = dict_lookup( libHandle, kazlibDict, key1 );

   if( !node )
      return TA_KEY_NOT_FOUND;

   subDict = (TA_Dict *)dnode_get(node);

   retCode = TA_DictDeletePair_S( subDict, key2 );

   /* Delete the dictionary if it is empty. */
   if( (retCode == TA_SUCCESS) && (TA_DictSize(subDict) == 0) )
   {
      TA_DictFree( subDict );
      /* Free the 'node' and the 'key1' string. */
      stringToDelete = TA_StringFromChar( dnode_getkey(node) );
      dict_delete_free( theDict->libHandle, kazlibDict, node );
      TA_StringFree( TA_GetGlobalStringCache( libHandle ), stringToDelete );
   }
   return TA_SUCCESS;
}
Beispiel #19
0
int mongrel2_ws_broadcast(mongrel2_socket *pub_socket, m2_ws_sessions_state *ses, bstring data){
    mongrel2_ws_sessions_state_lock(ses);

    dnode_t *iter = dict_first(ses->dict);

    const m2_ws_session_id *idptr = NULL;

    while(iter != NULL){
        printf(".");
        idptr = dnode_getkey(iter);
        assert(idptr != NULL);
        assert(idptr->req != NULL);
        mongrel2_ws_reply(pub_socket,idptr->req,data);

        iter = dict_next(ses->dict,iter);
    }

    printf(" done sending\n");

    mongrel2_ws_sessions_state_unlock(ses);
    return 0;
}
Beispiel #20
0
/// Traverses the CA, calling the specified function on each 'raw' PA.
/// @param[in] ca       the object pointer
/// @param[in] process  pointer to the callback function
/// @param[in] data     pointer which is passed to the callback
/// @return -1 on error, sum of process() return codes on success
int
ca_foreach_raw_pa(ca_o ca, int (*process) (pa_o, void *), void *data)
{
    dict_t *dict;
    dnode_t *dnp;
    pa_o pa;
    int rc = 0, pret;

    dict = ca->ca_raw_pa_dict;
    for (dnp = dict_first(dict); dnp; dnp = dict_next(dict, dnp)) {
        pa = (pa_o)dnode_getkey(dnp);
        pret = process(pa, data);
        if (pret < 0) {
            putil_int("error from ca_foreach_raw_pa()");
            return -1;
        } else {
            rc += pret;
        }
    }

    return rc;
}
Beispiel #21
0
/// Convert all raw PAs in the group into a single set of "cooked" PAs
/// under the leader.
/// @param[in] ca       the object pointer
void
ca_coalesce(ca_o ca)
{
    dict_t *dict_raw, *dict_cooked;
    dnode_t *dnpr, *dnpc, *next;

    dict_raw = ca->ca_raw_pa_dict;

    assert(!ca->ca_cooked_pa_dict);
    if ((dict_cooked = dict_create(DICTCOUNT_T_MAX, pa_cmp_by_pathname))) {
        ca->ca_cooked_pa_dict = dict_cooked;
    } else {
        putil_syserr(2, "dict_create()");
    }

    for (dnpr = dict_first(dict_raw); dnpr;) {
        pa_o raw_pa, ckd_pa;

        next = dict_next(dict_raw, dnpr);

        raw_pa = (pa_o)dnode_getkey(dnpr);

        _ca_verbosity_pa(raw_pa, ca, "COALESCING");

        // All data is in the key - that's why the value can be null.
        if ((dnpc = dict_lookup(dict_cooked, raw_pa))) {
            int keep_cooked = 0;

            ckd_pa = (pa_o)dnode_getkey(dnpc);

            if (!pa_is_read(raw_pa) && !pa_is_read(ckd_pa)) {
                moment_s raw_timestamp, ckd_timestamp;

                // If they're both destructive ops (non-read) then we
                // need to consider timestamps and use the later one.

                if (pa_has_timestamp(raw_pa) && pa_has_timestamp(ckd_pa)) {
                    // If the PA's have their own timestamps, use them.
                    raw_timestamp = pa_get_timestamp(raw_pa);
                    ckd_timestamp = pa_get_timestamp(ckd_pa);
                } else {
                    // Otherwise key off the file times. This is for
                    // support of "dummy" PAs as used in shopping.
                    raw_timestamp = pa_get_moment(raw_pa);
                    ckd_timestamp = pa_get_moment(ckd_pa);
                }

                if (moment_cmp(raw_timestamp, ckd_timestamp, NULL) <= 0) {
                    // Cooked write op is newer and can stay.
                    keep_cooked = 1;
                }
            } else if (pa_is_read(raw_pa)) {
                // There's no point replacing a read with another read,
                // so regardless of whether the current cooked PA is a
                // read or write, it can stay.
                keep_cooked = 1;
            } else {
                // A write always beats a read.
            }

            if (!keep_cooked) {
                dict_delete(dict_cooked, dnpc);
                dnode_destroy(dnpc);
                _ca_verbosity_pa(ckd_pa, ca, "REMOVING");
                pa_destroy(ckd_pa);
                if (!(dnpc = dnode_create(NULL))) {
                    putil_syserr(2, "dnode_create()");
                }
                ckd_pa = pa_copy(raw_pa);
                dict_insert(dict_cooked, dnpc, ckd_pa);
            }
        } else {
            if (!(dnpc = dnode_create(NULL))) {
                putil_syserr(2, "dnode_create()");
            }
            ckd_pa = pa_copy(raw_pa);
            dict_insert(dict_cooked, dnpc, ckd_pa);
        }

        // Clean up the raw set as we move PAs to the cooked one.
        dict_delete(dict_raw, dnpr);
        dnode_destroy(dnpr);
        dnpr = next;
    }

    return;
}
Beispiel #22
0
int
main(int argc, char **argv) {

  char   *merylCount = 0L;
  char   *fastaName = 0L;

  int arg=1;
  while (arg < argc) {

    if        (strcmp(argv[arg], "-m") == 0) {
      merylCount = argv[++arg];
    } else if (strcmp(argv[arg], "-f") == 0) {
      fastaName = argv[++arg];
    } else {
      fprintf(stderr, "unknown option '%s'\n", argv[arg]);
    }
    arg++;
  }

  if ((merylCount == 0L) || (fastaName == 0L)) {
    fprintf(stderr, "usage: %s -m <meryl-name-prefix> -f <fasta-file>\n", argv[0]);
    exit(1);
  }


  //  Open the count files
  //
  merylStreamReader  *MSR = new merylStreamReader(merylCount);

  fprintf(stderr, "Mers are "uint32FMT" bases.\n", MSR->merSize());
  fprintf(stderr, "There are "uint64FMT" unique (copy = 1) mers.\n", MSR->numberOfUniqueMers());
  fprintf(stderr, "There are "uint64FMT" distinct mers.\n", MSR->numberOfDistinctMers());
  fprintf(stderr, "There are "uint64FMT" mers total.\n", MSR->numberOfTotalMers());

  //  Guess how many mers we can fit into 512MB, then report how many chunks we need to do.

  uint32  merSize      = MSR->merSize();
  uint64  memoryLimit  = 700 * 1024 * 1024;
  uint64  perMer       = sizeof(kMerLite) + sizeof(dnode_t);
  uint64  mersPerBatch = memoryLimit / perMer;
  uint32  numBatches   = MSR->numberOfDistinctMers() / mersPerBatch;
  uint32  batch        = 0;

  dnode_t   *nodes     = new dnode_t  [mersPerBatch];
  kMerLite  *mers      = new kMerLite [mersPerBatch];

  if (MSR->numberOfDistinctMers() % mersPerBatch)
    numBatches++;

  fprintf(stderr, "perMer:  "uint64FMT" bytes ("uint64FMT" for kMerLite, "uint64FMT" for dnode_t.\n",
          perMer, (uint64)sizeof(kMerLite), (uint64)sizeof(dnode_t));
  fprintf(stderr, "We can fit "uint64FMT" mers into "uint64FMT"MB.\n", mersPerBatch, memoryLimit >> 20);
  fprintf(stderr, "So we need "uint32FMT" batches to verify the count.\n", numBatches);

  while (MSR->validMer()) {
    uint64          mersRemain = mersPerBatch;
    dict_t         *merDict    = dict_create(mersPerBatch, kMerLiteSort);

    batch++;

    //  STEP 1:  Insert mersPerBatch into the merDict
    //
    fprintf(stderr, "STEP 1 BATCH "uint32FMTW(2)":  Insert into merDict\n", batch);
    while (MSR->nextMer() && mersRemain) {
      mersRemain--;

      mers[mersRemain] = MSR->theFMer();

      //  initialize the node with the value, then insert the node
      //  into the tree using the key

      int32 val = (int32)MSR->theCount();
      dnode_init(&nodes[mersRemain], (void *)val);
      dict_insert(merDict, &nodes[mersRemain], &mers[mersRemain]);
    }

    //  STEP 2:  Stream the original file, decrementing the count
    //
    fprintf(stderr, "STEP 2 BATCH "uint32FMTW(2)":  Stream fasta\n", batch);
    seqStream    *CS = new seqStream(fastaName, true);
    merStream    *MS = new merStream(new kMerBuilder(merSize), CS);

    kMerLite       mer;
    dnode_t       *nod;

    while (MS->nextMer()) {
      mer = MS->theFMer();

      nod = dict_lookup(merDict, &mer);

      if (nod != 0L) {
        int32 val = (int32)dnode_get(nod);
        val--;
        dnode_put(nod, (void *)val);
      } else {
        //  Unless the whole meryl file fit into our merDict, we cannot warn if
        //  we don't find mers.
        //
        if (numBatches == 1) {
          char str[1024];
          fprintf(stderr, "Didn't find node for mer '%s'\n", mer.merToString(merSize, str));
        }
      }
    }

    delete MS;
    delete CS;

    //  STEP 3:  Check every node in the tree to make sure that the counts
    //  are exactly zero.
    //
    fprintf(stderr, "STEP 3 BATCH "uint32FMTW(2)":  Check\n", batch);
    nod = dict_first(merDict);
    while (nod) {
      int32           val = (int32)dnode_get(nod); 
      kMerLite const  *nodmer = (kMerLite const *)dnode_getkey(nod);

      if (val != 0) {
        char str[1024];
        fprintf(stderr, "Got count "int32FMT" for mer '%s'\n",
                val,
                nodmer->merToString(merSize, str));
      }

      nod = dict_next(merDict, nod);
    }


    //  STEP 4:  Destroy the dictionary.
    //
    fprintf(stderr, "STEP 4 BATCH "uint32FMTW(2)":  Destroy\n", batch);
    while ((nod = dict_first(merDict)))
      dict_delete(merDict, nod);
    dict_destroy(merDict);
  }
}
Beispiel #23
0
int main(void)
{
    input_t in;
    dict_t darray[10];
    dict_t *d = &darray[0];
    dnode_t *dn;
    size_t i;
    char *tok1, *tok2, *val;
    const char *key;

    char *help =
        "a <key> <val>          add value to dictionary\n"
        "d <key>                delete value from dictionary\n"
        "l <key>                lookup value in dictionary\n"
        "( <key>                lookup lower bound\n"
        ") <key>                lookup upper bound\n"
        "< <key>                lookup strict lower bound\n"
        "> <key>                lookup strict upper bound\n"
        "# <num>                switch to alternate dictionary (0-9)\n"
        "j <num> <num>          merge two dictionaries\n"
        "f                      free the whole dictionary\n"
        "k                      allow duplicate keys\n"
        "c                      show number of entries\n"
        "t                      dump whole dictionary in sort order\n"
        "m                      make dictionary out of sorted items\n"
        "p                      turn prompt on\n"
        "s                      switch to non-functioning allocator\n"
        "q                      quit";

    for (i = 0; i < sizeof darray / sizeof *darray; i++)
        dict_init(&darray[i], DICTCOUNT_T_MAX, comparef);

    for (;;) {
        if (prompt)
            putchar('>');
        fflush(stdout);

        if (!fgets(in, sizeof(input_t), stdin))
            break;

        switch(in[0]) {
            case '?':
                puts(help);
                break;
            case 'a':
                if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
                    puts("what?");
                    break;
                }
                key = dupstring(tok1);
                val = dupstring(tok2);

                if (!key || !val) {
                    puts("out of memory");
                    free((void *) key);
                    free(val);
                }

                if (!dict_alloc_insert(d, key, val)) {
                    puts("dict_alloc_insert failed");
                    free((void *) key);
                    free(val);
                    break;
                }
                break;
            case 'd':
                if (tokenize(in+1, &tok1, (char **) 0) != 1) {
                    puts("what?");
                    break;
                }
                dn = dict_lookup(d, tok1);
                if (!dn) {
                    puts("dict_lookup failed");
                    break;
                }
                val = (char *) dnode_get(dn);
                key = (char *) dnode_getkey(dn);
                dict_delete_free(d, dn);

                free(val);
                free((void *) key);
                break;
            case 'f':
                dict_free_nodes(d);
                break;
            case 'l':
            case '(':
            case ')':
            case '<':
            case '>':
                if (tokenize(in+1, &tok1, (char **) 0) != 1) {
                    puts("what?");
                    break;
                }
                dn = 0;
                switch (in[0]) {
                case 'l':
                    dn = dict_lookup(d, tok1);
                    break;
                case '(':
                    dn = dict_lower_bound(d, tok1);
                    break;
                case ')':
                    dn = dict_upper_bound(d, tok1);
                    break;
                case '<':
                    dn = dict_strict_lower_bound(d, tok1);
                    break;
                case '>':
                    dn = dict_strict_upper_bound(d, tok1);
                    break;
                }
                if (!dn) {
                    puts("lookup failed");
                    break;
                }
                val = (char *) dnode_get(dn);
                puts(val);
                break;
            case 'm':
                construct(d);
                break;
            case 'k':
                dict_allow_dupes(d);
                break;
            case 'c':
                printf("%lu\n", (unsigned long) dict_count(d));
                break;
            case 't':
                for (dn = dict_first(d); dn; dn = dict_next(d, dn)) {
                    printf("%s\t%s\n", (char *) dnode_getkey(dn),
                            (char *) dnode_get(dn));
                }
                break;
            case 'q':
                exit(0);
                break;
            case '\0':
                break;
            case 'p':
                prompt = 1;
                break;
            case 's':
                dict_set_allocator(d, new_node, del_node, NULL);
                break;
            case '#':
                if (tokenize(in+1, &tok1, (char **) 0) != 1) {
                    puts("what?");
                    break;
                } else {
                    int dictnum = atoi(tok1);
                    if (dictnum < 0 || dictnum > 9) {
                        puts("invalid number");
                        break;
                    }
                    d = &darray[dictnum];
                }
                break;
            case 'j':
                if (tokenize(in+1, &tok1, &tok2, (char **) 0) != 2) {
                    puts("what?");
                    break;
                } else {
                    int dict1 = atoi(tok1), dict2 = atoi(tok2);
                    if (dict1 < 0 || dict1 > 9 || dict2 < 0 || dict2 > 9) {
                        puts("invalid number");
                        break;
                    }
                    dict_merge(&darray[dict1], &darray[dict2]);
                }
                break;
            default:
                putchar('?');
                putchar('\n');
                break;
        }
    }

    return 0;
}