コード例 #1
0
ファイル: trie-c.c プロジェクト: dkurochkin/squid
int
main (int argc, char **argv)
{
    void *aTrie = TrieCreate();
    if (!TrieAdd (aTrie, "User-Agent", 10, (void *)1)) {
        fprintf(stderr,"Could not add User-Agent\n");
        return 1;
    }
    if (TrieAdd (aTrie, "User-Agent", 10, (void *)2)) {
        fprintf(stderr, "Could add duplicate User-Agent\n");
        return 1;
    }
    if (TrieFind (aTrie, "User-Agent", 10) != (void *)1) {
        fprintf(stderr, "Could not find User-Agent\n");
        return 1;
    }
    TrieDestroy (aTrie);
    return 0;
}
コード例 #2
0
rc_t KMain ( int argc, char *argv [] )
{
  rc_t rc;
  MyKVPair *pair;
  char buf[1024];
  int counter = 0;
  String key;
  int len;

  if (argc > 1 && !strcmp(argv[1], "-read")) {
    TrieRead(false);
    return 0;
  }

  if (argc > 1 && !strcmp(argv[1], "-swapread")) {
    TrieRead(true);
    return 0;
  }

  /* the documentation claims to return Unix status codes
     EINVAL or ENOMEM. however, it's more likely we just
     ran out of energy to update the comments...

     this creates a Trie with an initial character set of
     0-9, but which expands to accept new characters as seen
     thanks to the "true" value for "cs_expand"

     a standard Trie would encode the entire string into
     the prefix-tree, while this version only encodes as much
     of the strings initial characters as necessary before
     depositing the nodes into a BSTree at the leaves. you have
     told the code that it can accept up to 512 nodes in the
     BSTree until it has to split them up. to get more standard
     Trie behavior, choose a lower number, e.g. 1 */
  rc = TrieInit(&t, "a-z", 1, true);
  if (rc != 0) 
    LOGERR ( klogInt, rc, "triecreate" );

  /* you might want to get out after such an error... */

  /* another comment for you - using "buf, sizeof buf, stdin"
     will be safer ( I know this is just for experimentation,
     but since I'm reviewing it, I want you to get your money's worth */
  while (NULL != fgets(buf, 1024, stdin)) {
    len = strlen(buf);
    buf[--len] = '\0';
    /* printf("%d\n", len); */
    if (len <= 0)
      break;

    /* in C++, the cast to MyKVPair* is required, whereas
       in C it's not - which is part of its beauty. I prefer
       to avoid the cast unless we're planning on porting to C++,
       because the cast prevents you from changing the type of "pair"
       up above. same goes for "sizeof" - I prefer to let the compiler
       choose the right size for the allocation as "sizeof *pair"
       which will always be correct, even if I were to retype "pair" */
    pair = (MyKVPair *)malloc(sizeof(MyKVPair) + len + 1);
    if (pair == NULL) {
      fprintf(stderr, "Error in malloc\n");
      return -1;
    }
    strcpy(pair->key, buf);
    StringInitCString( &pair->tnode.key, (const char *)&pair->key );
    pair->value = counter++;
    /* fprintf(stderr, "At trieinsert\n"); */

    /* here I'd prefer "&pair->tnode" rather than the typecast
       ( do you get the idea I worry about typecasts? ) */
    rc = TrieInsert( &t, (TNode *)pair );
    if (rc != 0) 
      LOGERR ( klogInt, rc, "triecreate" );    
  }
  while (NULL != fgets(buf, 1024, stdin)) {
    len = strlen(buf);
    buf[--len] = '\0';
    StringInitCString( &key, buf );

    /* the first cast is required, although would normally
       want to be a "const MyKVPair*" so that you are sure
       not to modify it. the second cast is unnecessary */
    pair = (MyKVPair *)TrieFind(&t, (const String *)&key);
    if (pair != NULL) {
      printf("%s %d\n", buf, pair->value);
    }
  }
  Persist("/tmp/foo");
  return 0;
}