/** * Calculate the distance between two iterators. */ int _deque_iterator_minus(deque_iterator_t it_first, deque_iterator_t it_second) { int n_span = 0; int n_prefix = 0; int n_suffix = 0; assert(_DEQUE_ITERATOR_CONTAINER(it_first) == _DEQUE_ITERATOR_CONTAINER(it_second)); assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_first), it_first)); assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_second), it_second)); if(_deque_iterator_equal(it_first, it_second)) { return 0; } else if(_deque_iterator_before(it_first, it_second)) { n_span = (_DEQUE_ITERATOR_MAP_POINTER(it_second) - _DEQUE_ITERATOR_MAP_POINTER(it_first) - 1) * _DEQUE_ELEM_COUNT; n_prefix = (_DEQUE_ITERATOR_AFTERLAST_POS(it_first) - _DEQUE_ITERATOR_COREPOS(it_first)) / _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_first)); n_suffix = (_DEQUE_ITERATOR_COREPOS(it_second) - _DEQUE_ITERATOR_FIRST_POS(it_second)) / _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_second)); return -(n_prefix + n_span + n_suffix); } else { n_span = (_DEQUE_ITERATOR_MAP_POINTER(it_first) - _DEQUE_ITERATOR_MAP_POINTER(it_second) - 1) * _DEQUE_ELEM_COUNT; n_prefix = (_DEQUE_ITERATOR_AFTERLAST_POS(it_second) - _DEQUE_ITERATOR_COREPOS(it_second)) / _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_second)); n_suffix = (_DEQUE_ITERATOR_COREPOS(it_first) - _DEQUE_ITERATOR_FIRST_POS(it_first)) / _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_first)); return n_prefix + n_span + n_suffix; } }
/** * Shrink deque at begin. */ void _deque_shrink_at_begin(deque_t* pdeq_deque, size_t t_shrinksize) { deque_iterator_t it_oldbegin; deque_iterator_t it_newbegin; deque_iterator_t it_iter; _mappointer_t ppby_map = NULL; bool_t b_result = false; assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); it_oldbegin = deque_begin(pdeq_deque); t_shrinksize = t_shrinksize < deque_size(pdeq_deque) ? t_shrinksize : deque_size(pdeq_deque); it_newbegin = iterator_next_n(deque_begin(pdeq_deque), t_shrinksize); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_newbegin)); /* destroy all elements */ for(it_iter = it_oldbegin; !iterator_equal(it_iter, it_newbegin); it_iter = iterator_next(it_iter)) { b_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_DESTROY_FUNCTION(pdeq_deque)(_deque_iterator_get_pointer_auxiliary(it_iter), &b_result); assert(b_result); } pdeq_deque->_t_start = it_newbegin; for(ppby_map = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) - 1; ppby_map >= _GET_DEQUE_MAP_POINTER(it_oldbegin); --ppby_map) { _alloc_deallocate(&pdeq_deque->_t_allocator, *ppby_map, _GET_DEQUE_TYPE_SIZE(pdeq_deque), _DEQUE_ELEM_COUNT); *ppby_map = NULL; } }
/** * Get the iterator that reference next data. */ deque_iterator_t _deque_iterator_next(deque_iterator_t it_iter) { size_t t_beyondsize = 0; assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); _DEQUE_ITERATOR_COREPOS(it_iter) += _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)); /* at the node after the last node */ if(_DEQUE_ITERATOR_COREPOS(it_iter) >= _DEQUE_ITERATOR_AFTERLAST_POS(it_iter)) { t_beyondsize = _DEQUE_ITERATOR_COREPOS(it_iter) - _DEQUE_ITERATOR_AFTERLAST_POS(it_iter); assert(t_beyondsize == 0 || t_beyondsize == _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter))); /* is the current pos is not the last pos of map */ if(_DEQUE_ITERATOR_MAP_POINTER(it_iter) < _DEQUE_ITERATOR_MAP_POINTER(_DEQUE_ITERATOR_CONTAINER(it_iter)->_t_finish)) { _DEQUE_ITERATOR_MAP_POINTER(it_iter) += 1; _DEQUE_ITERATOR_FIRST_POS(it_iter) = *_DEQUE_ITERATOR_MAP_POINTER(it_iter); _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)) * _DEQUE_ELEM_COUNT; _DEQUE_ITERATOR_COREPOS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + t_beyondsize; } } assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); return it_iter; }
/** * Initialize data within range [it_begin, it_end) according to deque element data type. */ void _deque_init_elem_range_auxiliary(deque_t* pdeq_deque, deque_iterator_t it_begin, deque_iterator_t it_end) { deque_iterator_t it_iter; assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque) || _deque_is_created(pdeq_deque)); assert(_deque_iterator_belong_to_deque(_GET_DEQUE_CONTAINER(it_begin), it_begin)); assert(_deque_iterator_belong_to_deque(_GET_DEQUE_CONTAINER(it_end), it_end)); assert(iterator_equal(it_begin, it_end) || _deque_iterator_before(it_begin, it_end)); /* initialize new elements */ if(_GET_DEQUE_TYPE_STYLE(pdeq_deque) == _TYPE_CSTL_BUILTIN) { /* get element type name */ char s_elemtypename[_TYPE_NAME_SIZE + 1]; _type_get_elem_typename(_GET_DEQUE_TYPE_NAME(pdeq_deque), s_elemtypename); for(it_iter = it_begin; !iterator_equal(it_iter, it_end); it_iter = iterator_next(it_iter)) { _GET_DEQUE_TYPE_INIT_FUNCTION(pdeq_deque)(_deque_iterator_get_pointer_auxiliary(it_iter), s_elemtypename); } } else { for(it_iter = it_begin; !iterator_equal(it_iter, it_end); it_iter = iterator_next(it_iter)) { bool_t t_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_INIT_FUNCTION(pdeq_deque)(_deque_iterator_get_pointer_auxiliary(it_iter), &t_result); assert(t_result); } } }
/** * Destroy data, the data type and deque element data type are same. */ void _deque_destroy_varg_value_auxiliary(deque_t* pdeq_deque, void* pv_varg) { bool_t b_result = false; assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque) || _deque_is_created(pdeq_deque)); /* destroy varg value and free memory */ b_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_DESTROY_FUNCTION(pdeq_deque)(pv_varg, &b_result); assert(b_result); }
/** * Get the iterator that reference previous data. */ deque_iterator_t _deque_iterator_prev(deque_iterator_t it_iter) { assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); _DEQUE_ITERATOR_COREPOS(it_iter) -= _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)); /* before the first pos */ if(_DEQUE_ITERATOR_COREPOS(it_iter) < _DEQUE_ITERATOR_FIRST_POS(it_iter)) { /* is the current node is not the first node */ if(_DEQUE_ITERATOR_MAP_POINTER(it_iter) > _DEQUE_ITERATOR_MAP_POINTER(_DEQUE_ITERATOR_CONTAINER(it_iter)->_t_start)) { _DEQUE_ITERATOR_MAP_POINTER(it_iter) -= 1; _DEQUE_ITERATOR_FIRST_POS(it_iter) = *_DEQUE_ITERATOR_MAP_POINTER(it_iter); _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)) * _DEQUE_ELEM_COUNT; _DEQUE_ITERATOR_COREPOS(it_iter) = _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) - _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)); } } assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); return it_iter; }
/** * Set iterator reference data. */ void _deque_iterator_set_value(deque_iterator_t it_iter, const void* cpv_value) { bool_t b_result = false; assert(cpv_value != NULL); assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); assert(!iterator_equal(it_iter, deque_end(_DEQUE_ITERATOR_CONTAINER(it_iter)))); /* char* */ if(strncmp(_GET_DEQUE_TYPE_BASENAME(_DEQUE_ITERATOR_CONTAINER(it_iter)), _C_STRING_TYPE, _TYPE_NAME_SIZE) == 0) { string_assign_cstr((string_t*)_deque_iterator_get_pointer_auxiliary(it_iter), (char*)cpv_value); } else { b_result = _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)); _GET_DEQUE_TYPE_COPY_FUNCTION(_DEQUE_ITERATOR_CONTAINER(it_iter))( _deque_iterator_get_pointer_auxiliary(it_iter), cpv_value, &b_result); assert(b_result); } }
/** * Move element range to deque begin. */ deque_iterator_t _deque_move_elem_to_begin( deque_t* pdeq_deque, deque_iterator_t it_begin, deque_iterator_t it_end, size_t t_step) { assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_begin)); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_end)); assert(iterator_equal(it_begin, it_end) || _deque_iterator_before(it_begin, it_end)); if(!iterator_equal(it_begin, it_end) && t_step != 0) { deque_iterator_t it_targetbegin; deque_iterator_t it_targetend; bool_t b_result = false; it_targetbegin = it_begin; it_targetend = it_end; it_targetbegin = iterator_prev_n(it_targetbegin, t_step); it_targetend = iterator_prev_n(it_targetend, t_step); assert(_deque_iterator_before(it_targetbegin, it_targetend)); for(; iterator_less(it_targetbegin, it_targetend) && iterator_less(it_begin, it_end); it_targetbegin = iterator_next(it_targetbegin), it_begin = iterator_next(it_begin)) { b_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_COPY_FUNCTION(pdeq_deque)( _deque_iterator_get_pointer_auxiliary(it_targetbegin), _deque_iterator_get_pointer_auxiliary(it_begin), &b_result); assert(b_result); } assert(iterator_equal(it_targetbegin, it_targetend) && iterator_equal(it_begin, it_end)); return it_targetend; } else { return iterator_prev_n(it_end, t_step); } }
/** * Move element range to deque end. */ deque_iterator_t _deque_move_elem_to_end( deque_t* pdeq_deque, deque_iterator_t it_begin, deque_iterator_t it_end, size_t t_step) { assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_begin)); assert(_deque_iterator_belong_to_deque(pdeq_deque, it_end)); assert(iterator_equal(it_begin, it_end) || _deque_iterator_before(it_begin, it_end)); /* if it_begin != it_end then do move */ if(!iterator_equal(it_begin, it_end) && t_step != 0) { /* the target range of move */ deque_iterator_t it_targetbegin; deque_iterator_t it_targetend; bool_t b_result = false; it_targetbegin = it_begin; it_targetend = it_end; it_targetbegin = iterator_next_n(it_targetbegin, t_step); it_targetend = iterator_next_n(it_targetend, t_step); assert(_deque_iterator_before(it_targetbegin, it_targetend)); while(!iterator_equal(it_targetbegin, it_targetend) && !iterator_equal(it_begin, it_end)) { it_targetend = iterator_prev(it_targetend); it_end = iterator_prev(it_end); b_result = _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_TYPE_COPY_FUNCTION(pdeq_deque)( _deque_iterator_get_pointer_auxiliary(it_targetend), _deque_iterator_get_pointer_auxiliary(it_end), &b_result); assert(b_result); } assert(iterator_equal(it_begin, it_end) && iterator_equal(it_targetbegin, it_targetend)); } return it_begin; }
/** * Get the iterator that reference next n data. */ deque_iterator_t _deque_iterator_next_n(deque_iterator_t it_iter, int n_step) { int n_offset = 0; int n_span = 0; deque_t* pdeq_deque = NULL; assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); if(n_step == 0) { return it_iter; } /* * n_step > 0 * |<---- n_offset ---->| * it_iter ->|<---- n_step ---->| * +----------------+--------+ +-----------------+ +------------+-------------+ * | | | | ... | | * +----------------+--------+ +-----------------+ +------------+-------------+ * ^ ^ ^ * +--------------------+ +--+ +--------------+ * +-------+-+--+--+--+-----+--+--+----------+ * map | | | | ... | | | * +-------+----+-----+-----+-----+----------+ * |<-- n_span -->| * * ==================================================================================== * n_step < 0 * |<---- n_offset ---->| * |<---- n_step ---->|<- it_iter * +----------------+--------+ +-----------------+ +------------+-------------+ * | | | | ... | | * +----------------+--------+ +-----------------+ +------------+-------------+ * ^ ^ ^ * +--------------------+ +--+ +--------------+ * +-------+-+--+--+--+-----+--+--+----------+ * map | | | | ... | | | * +-------+----+-----+-----+-----+----------+ * |<-- n_span -->| */ pdeq_deque = _DEQUE_ITERATOR_CONTAINER(it_iter); n_offset = n_step + (_DEQUE_ITERATOR_COREPOS(it_iter) - _DEQUE_ITERATOR_FIRST_POS(it_iter)) / _GET_DEQUE_TYPE_SIZE(pdeq_deque); if(n_offset >= 0 && n_offset <= _DEQUE_ELEM_COUNT) { _DEQUE_ITERATOR_COREPOS(it_iter) += n_step * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } else { n_span = n_offset > 0 ? (n_offset + _DEQUE_ELEM_COUNT - 1) / _DEQUE_ELEM_COUNT - 1 : -((-n_offset + _DEQUE_ELEM_COUNT - 1) / _DEQUE_ELEM_COUNT); _DEQUE_ITERATOR_MAP_POINTER(it_iter) += n_span; _DEQUE_ITERATOR_FIRST_POS(it_iter) = *_DEQUE_ITERATOR_MAP_POINTER(it_iter); _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)) * _DEQUE_ELEM_COUNT; _DEQUE_ITERATOR_COREPOS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + (n_offset - n_span * _DEQUE_ELEM_COUNT) * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } /* corepos == afterlast and current chunk is't last chunk */ if(_DEQUE_ITERATOR_COREPOS(it_iter) == _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) && _DEQUE_ITERATOR_MAP_POINTER(it_iter) != _DEQUE_ITERATOR_MAP_POINTER(pdeq_deque->_t_finish)) { _DEQUE_ITERATOR_MAP_POINTER(it_iter) += 1; _DEQUE_ITERATOR_FIRST_POS(it_iter) = *_DEQUE_ITERATOR_MAP_POINTER(it_iter); _DEQUE_ITERATOR_AFTERLAST_POS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter) + _GET_DEQUE_TYPE_SIZE(_DEQUE_ITERATOR_CONTAINER(it_iter)) * _DEQUE_ELEM_COUNT; _DEQUE_ITERATOR_COREPOS(it_iter) = _DEQUE_ITERATOR_FIRST_POS(it_iter); } assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter)); return it_iter; }
/** * Test iterator referenced data is within the deque. */ bool_t _deque_iterator_belong_to_deque(const deque_t* cpdeq_deque, deque_iterator_t it_iter) { deque_iterator_t it_cur = _create_deque_iterator(); _byte_t* pby_startpos = NULL; _byte_t* pby_finishpos = NULL; assert(cpdeq_deque != NULL); assert(_deque_is_inited(cpdeq_deque)); assert(_GET_DEQUE_CONTAINER(it_iter) == cpdeq_deque); assert(_GET_DEQUE_CONTAINER_TYPE(it_iter) == _DEQUE_CONTAINER); assert(_GET_DEQUE_ITERATOR_TYPE(it_iter) == _RANDOM_ACCESS_ITERATOR); /* the the map pointer is valid */ for(_GET_DEQUE_MAP_POINTER(it_cur) = _GET_DEQUE_MAP_POINTER(cpdeq_deque->_t_start); _GET_DEQUE_MAP_POINTER(it_cur) <= _GET_DEQUE_MAP_POINTER(cpdeq_deque->_t_finish); _GET_DEQUE_MAP_POINTER(it_cur) += 1) { if(_GET_DEQUE_MAP_POINTER(it_cur) == _GET_DEQUE_MAP_POINTER(it_iter)) { _GET_DEQUE_FIRST_POS(it_cur) = *_GET_DEQUE_MAP_POINTER(it_cur); _GET_DEQUE_AFTERLAST_POS(it_cur) = _GET_DEQUE_FIRST_POS(it_cur) + _GET_DEQUE_TYPE_SIZE(cpdeq_deque) * _DEQUE_ELEM_COUNT; break; } } if(_GET_DEQUE_FIRST_POS(it_cur) == NULL) { return false; } /* test the iterator in suti with the map node */ if(_GET_DEQUE_FIRST_POS(it_cur) != _GET_DEQUE_FIRST_POS(it_iter) || _GET_DEQUE_AFTERLAST_POS(it_cur) != _GET_DEQUE_AFTERLAST_POS(it_iter)) { return false; } /* test the element pointer is valid */ /* * if the current pos equal begin pos * +-----------------------------------------+ * |first| ... ... | corepos | ... data ... | afterlast * +-----------------------------------------+ * or corepos == afterlast */ if(_GET_DEQUE_MAP_POINTER(it_cur) == _GET_DEQUE_MAP_POINTER(cpdeq_deque->_t_start)) { /* the begin pointer point to afterlast and the it_cur is begin */ if(_GET_DEQUE_COREPOS(cpdeq_deque->_t_start) == _GET_DEQUE_AFTERLAST_POS(cpdeq_deque->_t_start)) { if(_GET_DEQUE_COREPOS(it_iter) == _GET_DEQUE_AFTERLAST_POS(it_iter)) { return true; } else { return false; } } /* in begin container and the begin pointer not point to afterlast */ else { pby_startpos = _GET_DEQUE_COREPOS(cpdeq_deque->_t_start); pby_finishpos = _GET_DEQUE_AFTERLAST_POS(cpdeq_deque->_t_start) - _GET_DEQUE_TYPE_SIZE(cpdeq_deque); } } /* if the current pos equal end pos * +------------------------------------------+ * |first| ... data ... | corepos | ... ... | afterlast * +------------------------------------------+ */ else if(_GET_DEQUE_MAP_POINTER(it_cur) == _GET_DEQUE_MAP_POINTER(cpdeq_deque->_t_finish)) { pby_startpos = _GET_DEQUE_FIRST_POS(cpdeq_deque->_t_finish); pby_finishpos = _GET_DEQUE_COREPOS(cpdeq_deque->_t_finish); } else { pby_startpos = _GET_DEQUE_FIRST_POS(it_cur); pby_finishpos = _GET_DEQUE_AFTERLAST_POS(it_cur) - _GET_DEQUE_TYPE_SIZE(cpdeq_deque); } for(_GET_DEQUE_COREPOS(it_cur) = pby_startpos; _GET_DEQUE_COREPOS(it_cur) <= pby_finishpos; _GET_DEQUE_COREPOS(it_cur) += _GET_DEQUE_TYPE_SIZE(cpdeq_deque)) { if(_GET_DEQUE_COREPOS(it_cur) == _GET_DEQUE_COREPOS(it_iter)) { return true; } } return false; }
/** * Expand deque at begin. */ deque_iterator_t _deque_expand_at_begin(deque_t* pdeq_deque, size_t t_expandsize, deque_iterator_t* pit_pos) { deque_iterator_t it_oldbegin; size_t t_remainsize = 0; /* the remain size in first container */ assert(pdeq_deque != NULL); assert(_deque_is_inited(pdeq_deque)); #ifndef NDEBUG if(pit_pos != NULL) { assert(_deque_iterator_belong_to_deque(_GET_DEQUE_CONTAINER(*pit_pos), *pit_pos)); } #endif /* NDEBUG */ it_oldbegin = deque_begin(pdeq_deque); /* if the capacity of first container is enough for expand size */ t_remainsize = (_GET_DEQUE_COREPOS(it_oldbegin) - _GET_DEQUE_FIRST_POS(it_oldbegin)) / _GET_DEQUE_TYPE_SIZE(pdeq_deque); if(t_expandsize < t_remainsize) { /* set the new begin iterator */ _GET_DEQUE_COREPOS(pdeq_deque->_t_start) -= t_expandsize * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } else { size_t t_nomemsize = 0; /* the size that they have no memory */ size_t t_chunksize = 0; /* the chunk for new element */ size_t t_prefixsize = 0; /* the valid size in front chunk */ size_t t_remainfrontmapsize = 0; /* the remain space at the map begin */ size_t t_remainmapsize = 0; /* the remain space in the map */ _byte_t** ppby_newchunk = NULL; /* the pointer to new chunk */ size_t i = 0; /* caculate the expand chunk number */ t_nomemsize = t_expandsize - t_remainsize; t_chunksize = (t_nomemsize + _DEQUE_ELEM_COUNT - 1) / _DEQUE_ELEM_COUNT; t_prefixsize = t_nomemsize % _DEQUE_ELEM_COUNT; if(t_prefixsize == 0) { t_chunksize++; } t_remainfrontmapsize = _GET_DEQUE_MAP_POINTER(it_oldbegin) - pdeq_deque->_ppby_map; t_remainmapsize = pdeq_deque->_t_mapsize - (_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1); /* if chunk remain space is not enough for expand size then grow the map for expand chunk */ if(t_chunksize > t_remainmapsize) { size_t t_validmapsize = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1; int n_newmapstartpos = 0; int n_oldmapstartpos = (pdeq_deque->_t_mapsize - t_validmapsize) / 2; int n_newposofoldchunk = 0; int n_posdistance = 0; /* the distance of pit_pos and map */ size_t t_growsize = (t_chunksize - t_remainmapsize + _DEQUE_MAP_GROW_STEP - 1) / _DEQUE_MAP_GROW_STEP * _DEQUE_MAP_GROW_STEP; /* grow size multiple of eight */ _mappointer_t ppby_oldmap = pdeq_deque->_ppby_map; /* old map */ size_t t_oldmapsize = pdeq_deque->_t_mapsize; /* new map */ pdeq_deque->_t_mapsize += t_growsize; pdeq_deque->_ppby_map = _alloc_allocate(&pdeq_deque->_t_allocator, sizeof(_byte_t*), pdeq_deque->_t_mapsize); assert(pdeq_deque->_ppby_map != NULL); memset(pdeq_deque->_ppby_map, 0x00, sizeof(_byte_t*) * pdeq_deque->_t_mapsize); /* copy the chunk pointer from old map to new map */ n_newmapstartpos = (pdeq_deque->_t_mapsize - (t_validmapsize + t_chunksize)) / 2; n_newposofoldchunk = n_newmapstartpos + t_chunksize; memcpy(pdeq_deque->_ppby_map + n_newposofoldchunk, ppby_oldmap + n_oldmapstartpos, sizeof(_byte_t*) * t_validmapsize); /* get the pit_pos distance */ if(pit_pos != NULL) { n_posdistance = _GET_DEQUE_MAP_POINTER(*pit_pos) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); } /* reset the start, finish and old front iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) = pdeq_deque->_ppby_map + n_newposofoldchunk; _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) = pdeq_deque->_ppby_map + n_newposofoldchunk + t_validmapsize - 1; _GET_DEQUE_MAP_POINTER(it_oldbegin) = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); /* modify pit_pos */ if(pit_pos != NULL) { _GET_DEQUE_MAP_POINTER(*pit_pos) = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + n_posdistance; } _alloc_deallocate(&pdeq_deque->_t_allocator, ppby_oldmap, sizeof(_byte_t*), t_oldmapsize); } /* else if the chunk remain space is enough for expand size */ else if(t_chunksize > t_remainfrontmapsize && t_chunksize <= t_remainmapsize) { size_t t_oldvalidmapsize = _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) - _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + 1; /* old valid chunk count in old map */ size_t t_newvalidmapsize = t_oldvalidmapsize + t_chunksize; /* the valid chunk count in new map */ size_t t_oldstartpossize = (pdeq_deque->_t_mapsize - t_oldvalidmapsize) / 2; /* the chunk start pos in old map */ size_t t_newstartpossize = (pdeq_deque->_t_mapsize - t_newvalidmapsize) / 2; /* the chunk start pos in new map */ size_t t_newposofoldchunk = t_newstartpossize + t_chunksize; /* the chunk in new map pos */ size_t t_movesize = t_newposofoldchunk - t_oldstartpossize; /* the distance of move */ /* move the valid chunk pointer in map */ memmove(_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) + t_movesize, _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start), sizeof(_byte_t*) * t_oldvalidmapsize); /* reset the start, finish and oldend iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) += t_movesize; _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_finish) += t_movesize; _GET_DEQUE_MAP_POINTER(it_oldbegin) += t_movesize; if(pit_pos != NULL) { _GET_DEQUE_MAP_POINTER(*pit_pos) += t_movesize; } } /* allocate the chunk */ for(i = 0, ppby_newchunk = _GET_DEQUE_MAP_POINTER(it_oldbegin) - 1; i < t_chunksize; ++i, --ppby_newchunk) { *ppby_newchunk = _alloc_allocate(&pdeq_deque->_t_allocator, _GET_DEQUE_TYPE_SIZE(pdeq_deque), _DEQUE_ELEM_COUNT); assert(*ppby_newchunk != NULL); } /* set new start iterator */ _GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start) = _GET_DEQUE_MAP_POINTER(it_oldbegin) - t_chunksize; _GET_DEQUE_FIRST_POS(pdeq_deque->_t_start) = *_GET_DEQUE_MAP_POINTER(pdeq_deque->_t_start); _GET_DEQUE_AFTERLAST_POS(pdeq_deque->_t_start) = _GET_DEQUE_FIRST_POS(pdeq_deque->_t_start) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(pdeq_deque->_t_start) = _GET_DEQUE_AFTERLAST_POS(pdeq_deque->_t_start) - t_prefixsize * _GET_DEQUE_TYPE_SIZE(pdeq_deque); } /* the old front is original front */ if(_GET_DEQUE_COREPOS(it_oldbegin) == _GET_DEQUE_AFTERLAST_POS(it_oldbegin)) { assert(*(_GET_DEQUE_MAP_POINTER(it_oldbegin) + 1) != NULL); _GET_DEQUE_MAP_POINTER(it_oldbegin) += 1; _GET_DEQUE_FIRST_POS(it_oldbegin) = *_GET_DEQUE_MAP_POINTER(it_oldbegin); _GET_DEQUE_AFTERLAST_POS(it_oldbegin) = _GET_DEQUE_FIRST_POS(it_oldbegin) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(it_oldbegin) = _GET_DEQUE_FIRST_POS(it_oldbegin); } /* the *pit_pos is original front */ if(pit_pos != NULL && _GET_DEQUE_COREPOS(*pit_pos) == _GET_DEQUE_AFTERLAST_POS(*pit_pos)) { assert(*(_GET_DEQUE_MAP_POINTER(*pit_pos) + 1) != NULL); _GET_DEQUE_MAP_POINTER(*pit_pos) += 1; _GET_DEQUE_FIRST_POS(*pit_pos) = *_GET_DEQUE_MAP_POINTER(*pit_pos); _GET_DEQUE_AFTERLAST_POS(*pit_pos) = _GET_DEQUE_FIRST_POS(*pit_pos) + _DEQUE_ELEM_COUNT * _GET_DEQUE_TYPE_SIZE(pdeq_deque); _GET_DEQUE_COREPOS(*pit_pos) = _GET_DEQUE_FIRST_POS(*pit_pos); } /* initialize all new elements */ _deque_init_elem_range_auxiliary(pdeq_deque, deque_begin(pdeq_deque), it_oldbegin); return it_oldbegin; }