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; }
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); }
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); }
tb_void_t tb_priority_queue_exit(tb_priority_queue_ref_t self) { tb_heap_exit((tb_heap_ref_t)self); }
tb_void_t tb_priority_queue_exit(tb_priority_queue_ref_t queue) { tb_heap_exit((tb_heap_ref_t)queue); }
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); }