static tb_void_t tb_iterator_init_mem_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item) { // check tb_assert_return(iterator); tb_assert_return(itor < (tb_size_t)iterator->priv && item); // copy tb_memcpy((tb_byte_t*)iterator->data + itor * iterator->step, item, iterator->step); }
static tb_void_t tb_hash_map_itor_remove(tb_iterator_ref_t iterator, tb_size_t itor) { // check tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator; tb_assert_return(impl && impl->hash_list && impl->hash_size); // buck & item tb_size_t buck = tb_hash_map_index_buck(itor); tb_size_t item = tb_hash_map_index_item(itor); tb_assert_return(buck && item); buck--; item--; tb_assert_return(buck < impl->hash_size); // the step tb_size_t step = impl->element_name.size + impl->element_data.size; tb_assert_return(step); // get list tb_hash_map_item_list_t* list = impl->hash_list[buck]; tb_assert_return(list && list->size && item < list->size); // free item if (impl->element_name.free) impl->element_name.free(&impl->element_name, ((tb_byte_t*)&list[1]) + item * step); if (impl->element_data.free) impl->element_data.free(&impl->element_data, ((tb_byte_t*)&list[1]) + item * step + impl->element_name.size); // remove item from the list if (list->size > 1) { // move items if (item < list->size - 1) tb_memmov(((tb_byte_t*)&list[1]) + item * step, ((tb_byte_t*)&list[1]) + (item + 1) * step, (list->size - item - 1) * step); // update size list->size--; } // remove list else { // free it tb_free(list); // reset impl->hash_list[buck] = tb_null; } // update the impl item size impl->item_size--; }
static tb_void_t tb_demo_entry_copy(tb_pointer_t litem, tb_pointer_t ritem) { // check tb_assert_return(litem && ritem); // copy it ((tb_demo_entry_t*)litem)->data = ((tb_demo_entry_t*)ritem)->data; }
static tb_void_t tb_vector_itor_remove_range(tb_iterator_ref_t iterator, tb_size_t prev, tb_size_t next, tb_size_t size) { // check tb_vector_impl_t* impl = (tb_vector_impl_t*)iterator; tb_assert_return(impl); // remove the items if (size) tb_vector_nremove((tb_vector_ref_t)iterator, prev != impl->size? prev + 1 : 0, size); }
static tb_void_t tb_vector_itor_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item) { // check tb_vector_impl_t* impl = (tb_vector_impl_t*)iterator; tb_assert_return(impl); // copy impl->func.copy(&impl->func, impl->data + itor * iterator->step, item); }
static tb_void_t tb_hash_map_itor_copy(tb_iterator_ref_t iterator, tb_size_t itor, tb_cpointer_t item) { // check tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator; tb_assert_return(impl && impl->hash_list && impl->hash_size); // the buck and item tb_size_t b = tb_hash_map_index_buck(itor); tb_size_t i = tb_hash_map_index_item(itor); tb_assert_return(b && i); b--; i--; tb_assert_return(b < impl->hash_size); // step tb_size_t step = impl->element_name.size + impl->element_data.size; tb_assert_return(step); // list tb_hash_map_item_list_t* list = impl->hash_list[b]; tb_check_return(list && list->size && i < list->size); // note: copy data only, will destroy impl index if copy name impl->element_data.copy(&impl->element_data, ((tb_byte_t*)&list[1]) + i * step + impl->element_name.size, item); }
static tb_void_t tb_hash_map_itor_remove_range(tb_iterator_ref_t iterator, tb_size_t prev, tb_size_t next, tb_size_t size) { // check tb_hash_map_impl_t* impl = (tb_hash_map_impl_t*)iterator; tb_assert_return(impl && impl->hash_list && impl->hash_size); // no size tb_check_return(size); // the step tb_size_t step = impl->element_name.size + impl->element_data.size; tb_assert_return(step); // the first itor tb_size_t itor = prev? tb_hash_map_itor_next(iterator, prev) : tb_hash_map_itor_head(iterator); // the head buck and item tb_size_t buck_head = tb_hash_map_index_buck(itor); tb_size_t item_head = tb_hash_map_index_item(itor); tb_assert_return(buck_head && item_head); // compute index buck_head--; item_head--; tb_assert_return(buck_head < impl->hash_size && item_head < TB_HASH_MAP_BUCKET_ITEM_MAXN); // the last buck and the tail item tb_size_t buck_last; tb_size_t item_tail; if (next) { // next => buck and item buck_last = tb_hash_map_index_buck(next); item_tail = tb_hash_map_index_item(next); tb_assert_return(buck_last && item_tail); // compute index buck_last--; item_tail--; tb_assert_return(buck_last < impl->hash_size && item_tail < TB_HASH_MAP_BUCKET_ITEM_MAXN); } else { buck_last = impl->hash_size - 1; item_tail = -1; } // remove items: [itor, next) tb_size_t buck; tb_size_t item; tb_element_free_func_t name_free = impl->element_name.free; tb_element_free_func_t data_free = impl->element_data.free; for (buck = buck_head, item = item_head; buck <= buck_last; buck++, item = 0) { // the list tb_hash_map_item_list_t* list = impl->hash_list[buck]; tb_check_continue(list && list->size); // the tail tb_size_t tail = (buck == buck_last && next)? item_tail : list->size; tb_assert_abort(tail != -1); tb_check_continue(item < tail); // the data tb_byte_t* data = (tb_byte_t*)&list[1]; // free items tb_size_t i = 0; for (i = item; i < tail; i++) { if (name_free) name_free(&impl->element_name, data + i * step); if (data_free) data_free(&impl->element_data, data + i * step + impl->element_name.size); } // move items if (buck == buck_last && tail < list->size) tb_memmov(data + item * step, data + tail * step, (list->size - tail) * step); // update the list size list->size -= tail - item; // update the item size impl->item_size -= tail - item; } }