Exemplo n.º 1
0
Arquivo: heap.c Projeto: luxuan/tbox
static tb_void_t tb_test_heap_min_perf()
{
    // init heap
    tb_heap_ref_t heap = tb_heap_init(4096, tb_element_uint32());
    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_min: %lld ms", time);

    // exit heap
    tb_heap_exit(heap);
}
Exemplo n.º 2
0
tb_bool_t tb_heap_save(tb_heap_ref_t heap, tb_stream_ref_t stream)
{
    // check
    tb_heap_impl_t* impl = (tb_heap_impl_t*)heap;
    tb_assert_and_check_return_val(impl && stream, tb_false);
    tb_assert_and_check_return_val(impl->func.hash && impl->func.save, tb_false);
    
    // the offset
    tb_hize_t offset = tb_stream_offset(stream);

    // done
    tb_bool_t   ok = tb_false;
    tb_uint32_t crc32 = 0;
    do
    {
        // calc type
        crc32 = tb_crc_encode_cstr(TB_CRC_MODE_32_IEEE_LE, crc32, "heap");

        // calc item type
        crc32 = tb_crc_encode_value(TB_CRC_MODE_32_IEEE_LE, crc32, impl->func.type);

        // calc item size
        crc32 = tb_crc_encode_value(TB_CRC_MODE_32_IEEE_LE, crc32, impl->func.size);

        // save the head crc32
        if (!tb_stream_bwrit_u32_be(stream, crc32)) break;

        // the size
        tb_size_t size = tb_heap_size(heap);

        // save size
        if (!tb_stream_bwrit_u32_be(stream, (tb_uint32_t)size)) break;
        
        // save heap
        tb_size_t save = 0;
        tb_for_all (tb_cpointer_t, item, heap)
        {
            // save item
            if (!impl->func.save(&impl->func, item, stream)) break;

            // hash item
            tb_size_t hash = impl->func.hash(&impl->func, item, -1, 0);

            // calc item
            crc32 = tb_crc_encode_value(TB_CRC_MODE_32_IEEE_LE, crc32, hash);

            // update the save count
            save++;
        }

        // check
        tb_assert_and_check_break(save == size); 
 
        // save the body crc32
        if (!tb_stream_bwrit_u32_be(stream, crc32)) break;
        
        // ok
        ok = tb_true;

    } while (0);

    // failed? restore it
    if (!ok) tb_stream_seek(stream, offset);

    // ok?
    return ok;
}
Exemplo n.º 3
0
tb_size_t tb_priority_queue_size(tb_priority_queue_ref_t self)
{
    return tb_heap_size((tb_heap_ref_t)self);
}
Exemplo n.º 4
0
tb_bool_t tb_timer_spak(tb_timer_ref_t timer)
{
    // check
    tb_timer_impl_t* impl = (tb_timer_impl_t*)timer;
    tb_assert_and_check_return_val(impl && impl->pool && impl->heap, tb_false);

    // stoped?
    tb_check_return_val(!tb_atomic_get(&impl->stop), tb_false);

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

    // done
    tb_bool_t               ok = tb_false;
    tb_timer_task_func_t    func = tb_null;
    tb_cpointer_t           priv = tb_null;
    tb_bool_t               killed = tb_false;
    do
    {
        // empty? 
        if (!tb_heap_size(impl->heap))
        {
            ok = tb_true;
            break;
        }

        // the top task
        tb_timer_task_impl_t* task_impl = (tb_timer_task_impl_t*)tb_heap_top(impl->heap);
        tb_assert_and_check_break(task_impl);

        // check refn
        tb_assert(task_impl->refn);

        // the now
        tb_hong_t now = tb_timer_now(impl);

        // timeout?
        if (task_impl->when <= now)
        {
            // pop it
            tb_heap_pop(impl->heap);

            // save func and data for calling it later
            func = task_impl->func;
            priv = task_impl->priv;

            // killed?
            killed = task_impl->killed? tb_true : tb_false;

            // repeat?
            if (task_impl->repeat)
            {
                // update when
                task_impl->when = now + task_impl->period;

                // continue task_impl
                tb_heap_put(impl->heap, task_impl);
            }
            else 
            {
                // refn--
                if (task_impl->refn > 1) task_impl->refn--;
                // remove it from pool directly
                else tb_fixed_pool_free(impl->pool, task_impl);
            }
        }

        // ok
        ok = tb_true;

    } while (0);

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

    // done func
    if (func) func(killed, priv);

    // ok?
    return ok;
}
Exemplo n.º 5
0
tb_size_t tb_priority_queue_size(tb_priority_queue_ref_t queue)
{
    return tb_heap_size((tb_heap_ref_t)queue);
}
Exemplo n.º 6
0
Arquivo: heap.c Projeto: luxuan/tbox
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);
}