Beispiel #1
0
tb_heap_ref_t tb_heap_init(tb_size_t grow, tb_item_func_t func)
{
    // check
    tb_assert_and_check_return_val(grow, tb_null);
    tb_assert_and_check_return_val(func.size && func.data && func.dupl && func.repl, tb_null);

    // done
    tb_bool_t       ok = tb_false;
    tb_heap_impl_t* impl = tb_null;
    do
    {
        // make impl
        impl = tb_malloc0_type(tb_heap_impl_t);
        tb_assert_and_check_break(impl);

        // init impl
        impl->size = 0;
        impl->grow = grow;
        impl->maxn = grow;
        impl->func = func;
        tb_assert_and_check_break(impl->maxn < TB_HEAD_MAXN);

        // init iterator
        impl->itor.mode     = TB_ITERATOR_MODE_FORWARD | TB_ITERATOR_MODE_REVERSE | TB_ITERATOR_MODE_RACCESS | TB_ITERATOR_MODE_MUTABLE;
        impl->itor.priv     = tb_null;
        impl->itor.step     = func.size;
        impl->itor.size     = tb_heap_itor_size;
        impl->itor.head     = tb_heap_itor_head;
        impl->itor.last     = tb_heap_itor_last;
        impl->itor.tail     = tb_heap_itor_tail;
        impl->itor.prev     = tb_heap_itor_prev;
        impl->itor.next     = tb_heap_itor_next;
        impl->itor.item     = tb_heap_itor_item;
        impl->itor.copy     = tb_heap_itor_copy;
        impl->itor.comp     = tb_heap_itor_comp;
        impl->itor.remove   = tb_heap_itor_remove;

        // make data
        impl->data = (tb_byte_t*)tb_nalloc0(impl->maxn, func.size);
        tb_assert_and_check_break(impl->data);

        // ok
        ok = tb_true;

    } while (0);

    // failed?
    if (!ok)
    {
        // exit it
        if (impl) tb_heap_exit((tb_heap_ref_t)impl);
        impl = tb_null;
    }

    // ok?
    return (tb_heap_ref_t)impl;
}
Beispiel #2
0
tb_void_t tb_timer_exit(tb_timer_ref_t timer)
{
    // check
    tb_timer_impl_t* impl = (tb_timer_impl_t*)timer;
    tb_assert_and_check_return(impl);

    // stop it
    tb_atomic_set(&impl->stop, 1);

    // wait loop exit
    tb_size_t tryn = 10;
    while (tb_atomic_get(&impl->work) && tryn--) tb_msleep(500);

    // warning
    if (!tryn && tb_atomic_get(&impl->work)) tb_trace_w("[timer]: the loop has been not exited now!");

    // post event
    tb_spinlock_enter(&impl->lock);
    tb_event_ref_t event = impl->event;
    tb_spinlock_leave(&impl->lock);
    if (event) tb_event_post(event);

    // enter
    tb_spinlock_enter(&impl->lock);

    // exit heap
    if (impl->heap) tb_heap_exit(impl->heap);
    impl->heap = tb_null;

    // exit pool
    if (impl->pool) tb_fixed_pool_exit(impl->pool);
    impl->pool = tb_null;

    // exit event
    if (impl->event) tb_event_exit(impl->event);
    impl->event = tb_null;

    // leave
    tb_spinlock_leave(&impl->lock);

    // exit lock
    tb_spinlock_exit(&impl->lock);

    // exit it
    tb_free(impl);
}
Beispiel #3
0
static tb_void_t tb_test_heap_max_perf()
{
    // init element
    tb_element_t element = tb_element_uint32(); element.comp = tb_test_heap_max_comp;

    // init heap
    tb_heap_ref_t heap = tb_heap_init(4096, element);
    tb_assert_and_check_return(heap);

    // clear rand
    tb_random_clear(tb_null);

    // init time
    tb_hong_t time = tb_mclock();

    // profile
    __tb_volatile__ tb_size_t i = 0;
    __tb_volatile__ tb_size_t n = 100000;
    __tb_volatile__ tb_size_t p;
    for (i = 0; i < n; i++) tb_heap_put(heap, (tb_pointer_t)(tb_size_t)tb_random_range(tb_null, 0, 50));
    for (i = 0; tb_heap_size(heap); i++) 
    {
        // get the top value
        tb_size_t v = (tb_size_t)tb_heap_top(heap);

        // check order
        tb_assert_abort(!i || p >= v);

        // save the previous value
        p = v;

        // pop it
        tb_heap_pop(heap);
    }

    // exit time
    time = tb_mclock() - time;

    // trace
    tb_trace_i("heap_max: %lld ms", time);

    // exit heap
    tb_heap_exit(heap);
}
Beispiel #4
0
tb_void_t tb_priority_queue_exit(tb_priority_queue_ref_t self)
{
    tb_heap_exit((tb_heap_ref_t)self);
}
Beispiel #5
0
tb_void_t tb_priority_queue_exit(tb_priority_queue_ref_t queue)
{
    tb_heap_exit((tb_heap_ref_t)queue);
}
Beispiel #6
0
static tb_void_t tb_test_heap_min_func()
{
    // init heap
    tb_heap_ref_t heap = tb_heap_init(16, tb_element_uint32());
    tb_assert_and_check_return(heap);

    // clear rand
    tb_random_clear(tb_null);

    // make heap
    tb_size_t i = 0;
    for (i = 0; i < 100; i++) 
    {
        // the value
        tb_uint32_t val = tb_random_range(tb_null, 0, 50);

        // trace
//      tb_trace_i("heap_min: put: %u", val);

        // put it
        tb_heap_put(heap, tb_u2p(val));
    }

    // clear rand
    tb_random_clear(tb_null);

    // remove some values
    for (i = 0; i < 100; i++) 
    {
        // the value
        tb_uint32_t val = tb_random_range(tb_null, 0, 50);

        // remove it?
        if (!(i & 3))
        {
            tb_size_t itor = tb_find_all(heap, tb_u2p(val));
            if (itor != tb_iterator_tail(heap)) tb_heap_remove(heap, itor);
        }
    }

    // append heap
    for (i = 0; i < 30; i++) 
    {
        // the value
        tb_uint32_t val = tb_random_range(tb_null, 0, 50);

        // put it
        tb_heap_put(heap, tb_u2p(val));
    }

    // trace
    tb_trace_i("");

    // dump heap
    while (tb_heap_size(heap)) 
    {
        // put it
        tb_uint32_t val = (tb_uint32_t)(tb_size_t)tb_heap_top(heap);

        // trace
        tb_trace_i("heap_min: pop: %u", val);

        // pop it
        tb_heap_pop(heap);
    }

    // exit heap
    tb_heap_exit(heap);
}