void TestHashmaplinked_IterateHandlesCollisions(
    CuTest * tc
)
{
    hashmap_t *hm, *hm2;

    hashmap_iterator_t iter;

    void *key;

    hm = hashmap_new(__uint_hash, __uint_compare, 4);
    hm2 = hashmap_new(__uint_hash, __uint_compare, 4);

    hashmap_put(hm, (void *) 1, (void *) 92);
    hashmap_put(hm, (void *) 5, (void *) 91);
    hashmap_put(hm, (void *) 9, (void *) 90);

    hashmap_put(hm2, (void *) 1, (void *) 92);
    hashmap_put(hm2, (void *) 5, (void *) 91);
    hashmap_put(hm2, (void *) 9, (void *) 90);

    hashmap_iterator(hm, &iter);

    /*  remove every key we iterate on */
    while ((key = hashmap_iterator_next(hm, &iter)))
    {
        CuAssertTrue(tc, NULL != hashmap_remove(hm2, key));
    }

    /*  check if the hashmap is empty */
    CuAssertTrue(tc, 0 == hashmap_count(hm2));
    hashmap_freeall(hm);
}
示例#2
0
void __print_client_contents()
{
    hashmap_iterator_t iter;

    for (
        hashmap_iterator(__clients, &iter);
        hashmap_iterator_has_next(__clients, &iter);
        )
    {
        void* bt, *cfg;
        client_t* cli;
        hashmap_iterator_t iter_connects;

        cli = hashmap_iterator_next_value(__clients, &iter);

        /* loop throught each connection for this peer */
        for (
            hashmap_iterator(cli->connections, &iter_connects);
            hashmap_iterator_has_next(cli->connections, &iter_connects);
            )
        {
            client_connection_t* cn;
            int jj;

            cn = hashmap_iterator_next_value(cli->connections, &iter_connects);

#if 0 /* debugging */
            {
                void* data;
                printf("cli: %d nethandle: %d inbox: %dB ",
                        cli->nethandle, cn->nethandle, bipbuf_get_spaceused(cn->inbox));
                data = bipbuf_peek(cn->inbox);
                for (jj=0; jj<bipbuf_get_spaceused(cn->inbox); jj++)
                {
                    printf("%c", ((char*)data)[jj]);
                }
            }
            printf("\n");
#endif
        }
    }
}
示例#3
0
static void __peer_release(peer_t* p)
{
    hashmap_iterator_t iter;
    piece_t* pce;

    for (hashmap_iterator(p->have_pieces, &iter);
        (pce = hashmap_iterator_next(p->have_pieces, &iter));)
    {
        hashmap_remove(p->have_pieces, p);
    }
}
void TestHashmaplinked_DoesNotHaveNextForEmptyIterator(
    CuTest * tc
)
{
    hashmap_t *hm;
    hashmap_iterator_t iter;

    hm = hashmap_new(__uint_hash, __uint_compare, 11);
    hashmap_iterator(hm, &iter);
    CuAssertTrue(tc, 0 == hashmap_iterator_has_next(hm, &iter));
    hashmap_freeall(hm);
}
示例#5
0
int bt_rarestfirst_selector_poll_best_piece(
    void *r,
    const void *peer
)
{
    rarestfirst_t *rf = r;
    heap_t *hp;
    peer_t *pr;
    void *p;
    int piece_idx;
    hashmap_iterator_t iter;
    piece_t *pce;

    if (!(pr = hashmap_get(rf->peers, peer)))
    {
        return -1;
    }

    /*  if we have no pieces, fail */
    if (0 == hashmap_count(pr->have_pieces))
    {
        return -1;
    }

    hp = heap_new(__cmp_piece, rf);

    /*  add to priority queue */
    for (hashmap_iterator(rf->pieces, &iter);
        (p = hashmap_iterator_next(rf->pieces, &iter));)
    {
        /* only add if peer has it */
        if (hashmap_get(pr->have_pieces, p))
        {
            pce = hashmap_get(rf->pieces, p);
            heap_offer(hp, pce);
        }
    }

    /*  queue best from priority queue */
    if ((pce = heap_poll(hp)))
    {
        piece_idx = pce->idx;
        hashmap_remove(rf->pieces, (void *) (long) pce->idx);
        hashmap_put(rf->pieces_polled, (void *) (long) pce->idx, pce);
    }
    else
    {
        piece_idx = -1;
    }

    heap_free(hp);
    return piece_idx;
}
示例#6
0
/**
 * poll info peer has information 
 * */
int network_poll(void* caller, void **udata,
               const int msec_timeout,
               int (*func_process) (void *caller,
                                    void* nethandle,
                                    const char* buf,
                                    unsigned int len),
               void (*func_process_connection) (void *,
                                                void* nethandle,
                                                char *ip,
                                                int port)
               )
{
    client_t* me = *udata;
    hashmap_iterator_t iter;

    /* loop throught each connection for this peer */
    for (
        hashmap_iterator(me->connections, &iter);
        hashmap_iterator_has_next(me->connections, &iter);
        )
    {
        client_connection_t* cn;

        cn = hashmap_iterator_next_value(me->connections, &iter);

        /* we need to process a connection request created by the peer */
        if (0 == cn->connect_status)
        {
            char ip[32];

            sprintf(ip, "%p", cn->nethandle);

#if 0 /* debugging */
            printf("processing connection me:%d them:%d\n",
                    me->nethandle, cn->nethandle);
#endif

            func_process_connection(me->bt, cn->nethandle, ip, 4000);
            cn->connect_status = CS_CONNECTED;
        }
        else if (!bipbuf_is_empty(cn->inbox))
        {
            int len = bipbuf_get_spaceused(cn->inbox);
            if (0 < len)
                func_process(me->bt,
                             (char*)cn->nethandle,
                             (char*)bipbuf_poll(cn->inbox, len), len);
        }
    }

    return 1;
}
void TestHashmaplinked_IterateAndRemoveDoesntBreakIteration(
    CuTest * tc
)
{
    hashmap_t *hm;
    hashmap_t *hm2;
    hashmap_iterator_t iter;
    void *key;

    hm = hashmap_new(__uint_hash, __uint_compare, 11);
    hm2 = hashmap_new(__uint_hash, __uint_compare, 11);

    hashmap_put(hm, (void *) 50, (void *) 92);
    hashmap_put(hm, (void *) 49, (void *) 91);
    hashmap_put(hm, (void *) 48, (void *) 90);
    hashmap_put(hm, (void *) 47, (void *) 89);
    hashmap_put(hm, (void *) 46, (void *) 88);
    hashmap_put(hm, (void *) 45, (void *) 87);
    /*  the following 3 collide: */
    hashmap_put(hm, (void *) 1, (void *) 92);
    hashmap_put(hm, (void *) 5, (void *) 91);
    hashmap_put(hm, (void *) 9, (void *) 90);

    hashmap_put(hm2, (void *) 50, (void *) 92);
    hashmap_put(hm2, (void *) 49, (void *) 91);
    hashmap_put(hm2, (void *) 48, (void *) 90);
    hashmap_put(hm2, (void *) 47, (void *) 89);
    hashmap_put(hm2, (void *) 46, (void *) 88);
    hashmap_put(hm2, (void *) 45, (void *) 87);
    /*  the following 3 collide: */
    hashmap_put(hm2, (void *) 1, (void *) 92);
    hashmap_put(hm2, (void *) 5, (void *) 91);
    hashmap_put(hm2, (void *) 9, (void *) 90);

    hashmap_iterator(hm, &iter);

    /*  remove every key we iterate on */
    while ((key = hashmap_iterator_next(hm, &iter)))
    {
        CuAssertTrue(tc, NULL != hashmap_remove(hm2, key));
        hashmap_remove(hm,key);
    }

    /*  check if the hashmap is empty */
    CuAssertTrue(tc, 0 == hashmap_count(hm2));
    hashmap_freeall(hm);
    hashmap_freeall(hm2);
}
示例#8
0
/**
 * @return peer that corresponds to conn_ctx, otherwise NULL */
void *bt_peermanager_conn_ctx_to_peer(void * pm, void* conn_ctx)
{
    bt_peermanager_t *me = pm;
    hashmap_iterator_t iter;

    /* find peerconn that has this conn_ctx */
    for (hashmap_iterator(me->peers,&iter);
         hashmap_iterator_has_next(me->peers,&iter);)
    {
        bt_peer_t* peer;

        peer = hashmap_iterator_next(me->peers,&iter);
        if (peer->conn_ctx == conn_ctx)
            return peer;
    }

    return NULL;
}
示例#9
0
void* bt_peermanager_get_peer_from_pc(void* pm, const void* pc)
{
    bt_peermanager_t *me = pm;
    hashmap_iterator_t iter;

    /* find peerconn that has this ip and port */
    for (hashmap_iterator(me->peers,&iter);
         hashmap_iterator_has_next(me->peers,&iter);)
    {
        bt_peer_t* p = hashmap_iterator_next(me->peers,&iter);

        if (p->pc == pc)
        {
            return p;
        }
    }
    return NULL;
}
示例#10
0
void bt_peermanager_forall(
        void* pm,
        void* caller,
        void* udata,
        void (*run)(void* caller, void* peer, void* udata))
{
    bt_peermanager_t *me = pm;
    hashmap_iterator_t iter;

    for (hashmap_iterator(me->peers,&iter);
         hashmap_iterator_has_next(me->peers,&iter);)
    {
        bt_peer_t* peer;

        peer = hashmap_iterator_next(me->peers,&iter);
        run(caller,peer,udata);
    }
}
示例#11
0
/**
 * @return 1 if the peer is within the manager */
int bt_peermanager_contains(void *pm, const char *ip, const int port)
{
    bt_peermanager_t *me = pm;
    hashmap_iterator_t iter;

    /* find peerconn that has this ip and port */
    for (hashmap_iterator(me->peers,&iter);
         hashmap_iterator_has_next(me->peers,&iter);)
    {
        bt_peer_t* peer;

        peer = hashmap_iterator_next(me->peers,&iter);
        if (!strcmp(peer->ip, ip) && peer->port == port)
        {
            return 1;
        }
    }
    return 0;
}
示例#12
0
void bt_rarestfirst_selector_free(
    void *r
)
{
    rarestfirst_t *rf = r;
    hashmap_iterator_t iter;
    peer_t* p;

    for (hashmap_iterator(rf->pieces, &iter);
        (p = hashmap_iterator_next(rf->pieces, &iter));)
    {
        hashmap_remove(rf->pieces, p);
        free(p);
    }

    hashmap_free(rf->peers);
    hashmap_free(rf->pieces);
    hashmap_free(rf->pieces_polled);
    free(rf);
}
void TestBT_Peer_share_20_pieces(CuTest * tc)
{
    int num_pieces;
    int ii;
    client_t* a, *b;
    hashmap_iterator_t iter;
    void* mt;
    char *addr;

    num_pieces = 50;
    clients_setup();
    mt = mocktorrent_new(num_pieces, 5);
    a = mock_client_setup(5);
    b = mock_client_setup(5);

    for (
        hashmap_iterator(clients_get(), &iter);
        hashmap_iterator_has_next(clients_get(), &iter);
        )
    {
        void* bt, *cfg;
        client_t* cli;

        cli = hashmap_iterator_next_value(clients_get(), &iter);
        bt = cli->bt;

        /* default configuration for clients */
        cfg = bt_dm_get_config(bt);
        config_set_va(cfg, "npieces", "%d", num_pieces);
        config_set(cfg, "piece_length", "5");
        config_set(cfg, "infohash", "00000000000000000000");

        /* add files/pieces */
        bt_piecedb_increase_piece_space(bt_dm_get_piecedb(bt), num_pieces * 5);
        for (ii = 0; ii < num_pieces; ii++)
        {
            char hash[21];
            void* pd;

            pd = bt_dm_get_piecedb(bt);
            mocktorrent_get_piece_sha1(mt, hash, ii);
            bt_piecedb_add_with_hash_and_size(pd, hash, 5);
        }
    }

    /* B will initiate the connection */
    asprintf(&addr, "%p", b);
    client_add_peer(a, NULL, 0, addr, strlen(addr), 0);

    __add_random_piece_subset_of_mocktorrent(
        bt_dm_get_piecedb(a->bt),
        mt, num_pieces);

    __add_piece_intersection_of_mocktorrent(
        bt_dm_get_piecedb(b->bt),
        bt_dm_get_piecedb(a->bt),
        mt, num_pieces);

    bt_dm_check_pieces(a->bt);
    bt_dm_check_pieces(b->bt);

    for (ii = 0; ii < 2000; ii++)
    {
#if 0   /* debugging */
        printf("\nStep %d:\n", ii + 1);
#endif
        bt_dm_periodic(a->bt, NULL);
        bt_dm_periodic(b->bt, NULL);

        network_poll(a->bt, (void*)&a, 0,
                     bt_dm_dispatch_from_buffer,
                     mock_on_connect);

        network_poll(b->bt, (void*)&b, 0,
                     bt_dm_dispatch_from_buffer,
                     mock_on_connect);
    }

    bt_dm_periodic(a->bt, NULL);
    bt_dm_periodic(b->bt, NULL);

//    bt_piecedb_print_pieces_downloaded(bt_dm_get_piecedb(a->bt));
//    bt_piecedb_print_pieces_downloaded(bt_dm_get_piecedb(b->bt));

    CuAssertTrue(tc, 1 ==
                 bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(a->bt)));
    CuAssertTrue(tc, 1 ==
                 bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(b->bt)));
}
void TestBT_Peer_shares_one_piece(
    CuTest * tc
)
{
    int ii;
    client_t* a, *b;
    hashmap_iterator_t iter;
    void* mt;
    char *addr;

    clients_setup();
    mt = mocktorrent_new(1, 5);
    a = mock_client_setup(5);
    b = mock_client_setup(5);

    for (
        hashmap_iterator(clients_get(), &iter);
        hashmap_iterator_has_next(clients_get(), &iter);
    )
    {
        char hash[21];

        client_t* cli = hashmap_iterator_next_value(clients_get(), &iter);
        void* bt = cli->bt;
        void *cfg = bt_dm_get_config(bt);
        /* default configuration for clients */
        config_set(cfg, "npieces", "1");
        config_set_va(cfg, "piece_length", "%d", 5);
        config_set(cfg, "infohash", "00000000000000000000");
        /* add files/pieces */
        //bt_piecedb_add_file(bt_dm_get_piecedb(bt),"test.txt",8,5);
        bt_piecedb_increase_piece_space(bt_dm_get_piecedb(bt), 5);
        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                                          mocktorrent_get_piece_sha1(mt, hash,
                                                  0), 5);
    }

    /* write blocks to client A */
    {
        void* data;
        bt_block_t blk;

        data = mocktorrent_get_data(mt, 0);
        blk.piece_idx = 0;
        blk.offset = 0;
        blk.len = 5;
        bt_diskmem_write_block(
            bt_piecedb_get_diskstorage(bt_dm_get_piecedb(a->bt)),
            NULL, &blk, data);
    }

    bt_dm_check_pieces(a->bt);
    bt_dm_check_pieces(b->bt);
    /* let validation jobs run */
    bt_dm_periodic(a->bt, NULL);
    CuAssertTrue(tc, 1 ==
                 bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(a->bt)));

    /* connect clients */
    asprintf(&addr, "%p", a);
    client_add_peer(b, NULL, 0, addr, strlen(addr), 0);

    for (ii = 0; ii < 10; ii++)
    {
#if 0   /* debugging */
        printf("\nStep %d:\n", ii + 1);
#endif

        bt_dm_periodic(a->bt, NULL);
        bt_dm_periodic(b->bt, NULL);

        network_poll(a->bt, (void*)&a, 0,
                     bt_dm_dispatch_from_buffer,
                     mock_on_connect);

        network_poll(b->bt, (void*)&b, 0,
                     bt_dm_dispatch_from_buffer,
                     mock_on_connect);

//        __print_client_contents();
    }

    /* let validation jobs run */
    bt_dm_periodic(a->bt, NULL);
    bt_dm_periodic(b->bt, NULL);

    CuAssertTrue(tc, 1 ==
                 bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(b->bt)));
}
/** a have message has to be sent by client B, for client A and C to finish */
void TestBT_Peer_three_share_all_pieces_between_each_other(CuTest * tc)
{
    int ii;
    client_t* a, *b, *c;
    hashmap_iterator_t iter;
    void* mt;
    char *addr;

    clients_setup();
    mt = mocktorrent_new(3,5);
    a = mock_client_setup(5);
    b = mock_client_setup(5);
    c = mock_client_setup(5);

    for (
        hashmap_iterator(clients_get(), &iter);
        hashmap_iterator_has_next(clients_get(), &iter);
        )
    {
        char hash[21];
        void* bt, *cfg;
        client_t* cli;

        cli = hashmap_iterator_next_value(clients_get(), &iter);
        bt = cli->bt;
        cfg = bt_dm_get_config(bt);
        /* default configuration for clients */
        config_set(cfg, "npieces", "3");
        config_set(cfg, "piece_length", "5");
        config_set(cfg, "infohash", "00000000000000000000");
        /* add files/pieces */
        bt_piecedb_increase_piece_space(bt_dm_get_piecedb(bt),20);
        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                mocktorrent_get_piece_sha1(mt,hash,0), 5);
        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                mocktorrent_get_piece_sha1(mt,hash,1), 5);
        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                mocktorrent_get_piece_sha1(mt,hash,2), 5);
    }

    /* write blocks to client A & B */
    {
        void* data;
        bt_block_t blk;

        blk.piece_idx = 0;
        blk.offset = 0;
        blk.len = 5;

        data = mocktorrent_get_data(mt,0);
        bt_diskmem_write_block(
                bt_piecedb_get_diskstorage(bt_dm_get_piecedb(a->bt)),
                NULL, &blk, data);

        blk.piece_idx = 1;
        data = mocktorrent_get_data(mt,1);
        bt_diskmem_write_block(
                bt_piecedb_get_diskstorage(bt_dm_get_piecedb(b->bt)),
                NULL, &blk, data);

        blk.piece_idx = 2;
        data = mocktorrent_get_data(mt,2);
        bt_diskmem_write_block(
                bt_piecedb_get_diskstorage(bt_dm_get_piecedb(c->bt)),
                NULL, &blk, data);
    }

    bt_dm_check_pieces(a->bt);
    bt_dm_check_pieces(b->bt);
    bt_dm_check_pieces(c->bt);

    /* A connects to B */
    asprintf(&addr,"%p", b);
    client_add_peer(a,NULL,0,addr,strlen(addr),0);
    /* B connects to C */
    asprintf(&addr,"%p", c);
    client_add_peer(b,NULL,0,addr,strlen(addr),0);

    for (ii=0; ii<10; ii++)
    {
#if 0 /* debugging */
        printf("\nStep %d:\n", ii+1);
#endif

        bt_dm_periodic(a->bt, NULL);
        bt_dm_periodic(b->bt, NULL);
        bt_dm_periodic(c->bt, NULL);

        network_poll(a->bt, (void*)&a, 0,
                bt_dm_dispatch_from_buffer,
                mock_on_connect);

        network_poll(b->bt, (void*)&b, 0,
                bt_dm_dispatch_from_buffer,
                mock_on_connect);

        network_poll(c->bt, (void*)&c, 0,
                bt_dm_dispatch_from_buffer,
                mock_on_connect);

//        __print_client_contents();
    }

//    bt_piecedb_print_pieces_downloaded(bt_dm_get_piecedb(a->bt));
//    bt_piecedb_print_pieces_downloaded(bt_dm_get_piecedb(b->bt));
//    bt_piecedb_print_pieces_downloaded(bt_dm_get_piecedb(c->bt));

    /* empty jobs */
    bt_dm_periodic(a->bt, NULL);
    bt_dm_periodic(b->bt, NULL);
    bt_dm_periodic(c->bt, NULL);

    CuAssertTrue(tc, 1 == bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(a->bt)));
    CuAssertTrue(tc, 1 == bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(b->bt)));
    CuAssertTrue(tc, 1 == bt_piecedb_all_pieces_are_complete(bt_dm_get_piecedb(c->bt)));
}
/**
 * Does the bt_dm_check_pieces() confirm if a piece is complete? */
void TestBT_Peer_shares_all_pieces_between_each_other(
    CuTest * tc
    )
{
    client_t* a, *b;
    hashmap_iterator_t iter;
    void* mt;

    clients_setup();
    mt = mocktorrent_new(2, 5);
    a = mock_client_setup(5);
    b = mock_client_setup(5);

    for (
        hashmap_iterator(clients_get(), &iter);
        hashmap_iterator_has_next(clients_get(), &iter);
        )
    {
        char hash[21];
        void* bt, *cfg;
        client_t* cli;

        cli = hashmap_iterator_next_value(clients_get(), &iter);
        bt = cli->bt;
        cfg = bt_dm_get_config(bt);
        /* default configuration for clients */
        config_set(cfg, "npieces", "2");
        config_set(cfg, "piece_length", "5");
        config_set(cfg, "infohash", "00000000000000000000");
        /* add files/pieces */
        bt_piecedb_increase_piece_space(bt_dm_get_piecedb(bt), 5);
        bt_piecedb_increase_piece_space(bt_dm_get_piecedb(bt), 12);

        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                                          mocktorrent_get_piece_sha1(mt, hash,
                                                                     0), 5);
        bt_piecedb_add_with_hash_and_size(bt_dm_get_piecedb(bt),
                                          mocktorrent_get_piece_sha1(mt, hash,
                                                                     1), 5);
    }

    /* write blocks to client A & B */
    {
        void* data;
        bt_block_t blk;

        blk.piece_idx = 0;
        blk.offset = 0;
        blk.len = 5;

        data = mocktorrent_get_data(mt, 0);
        bt_diskmem_write_block(
            bt_piecedb_get_diskstorage(bt_dm_get_piecedb(b->bt)),
            NULL, &blk, data);

        blk.piece_idx = 1;
        data = mocktorrent_get_data(mt, 1);
        bt_diskmem_write_block(
            bt_piecedb_get_diskstorage(bt_dm_get_piecedb(a->bt)),
            NULL, &blk, data);
    }

    bt_dm_check_pieces(a->bt);
    bt_dm_check_pieces(b->bt);

    bt_dm_periodic(a->bt, NULL);
    bt_dm_periodic(b->bt, NULL);

    CuAssertTrue(tc, bt_dm_piece_is_complete(a->bt, 1));
    CuAssertTrue(tc, bt_dm_piece_is_complete(b->bt, 0));
}