Esempio n. 1
0
/**
 * 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;
    }
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
/**
 * 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);
        }
    }
}
Esempio n. 4
0
/**
 * Testing of the first iterator is less than the second iterator.
 */
bool_t _deque_iterator_less(deque_iterator_t it_first, deque_iterator_t it_second)
{
    assert(_iterator_same_type(it_first, it_second));
    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_MAP_POINTER(it_first) < _DEQUE_ITERATOR_MAP_POINTER(it_second))
    {
        /* it_first and it_second are deque_begin(); */
        if(_DEQUE_ITERATOR_COREPOS(it_first) == _DEQUE_ITERATOR_AFTERLAST_POS(it_first) &&
           _DEQUE_ITERATOR_COREPOS(it_second) == _DEQUE_ITERATOR_FIRST_POS(it_second) &&
           _DEQUE_ITERATOR_MAP_POINTER(it_first) + 1 == _DEQUE_ITERATOR_MAP_POINTER(it_second))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    else if(_DEQUE_ITERATOR_MAP_POINTER(it_first) == _DEQUE_ITERATOR_MAP_POINTER(it_second))
    {
        return _DEQUE_ITERATOR_COREPOS(it_first) < _DEQUE_ITERATOR_COREPOS(it_second) ? true : false;
    }
    else
    {
        return false;
    }
}
Esempio n. 5
0
/**
 * Compare two iterators for equality.
 */
bool_t _deque_iterator_equal(deque_iterator_t it_first, deque_iterator_t it_second)
{
    assert(_iterator_same_type(it_first, it_second));
    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_MAP_POINTER(it_first) == _DEQUE_ITERATOR_MAP_POINTER(it_second) &&
       _DEQUE_ITERATOR_FIRST_POS(it_first) == _DEQUE_ITERATOR_FIRST_POS(it_second) &&
       _DEQUE_ITERATOR_AFTERLAST_POS(it_first) == _DEQUE_ITERATOR_AFTERLAST_POS(it_second) &&
       _DEQUE_ITERATOR_COREPOS(it_first) == _DEQUE_ITERATOR_COREPOS(it_second))
    {
        return true;
    }
    else
    {
        /* 
         * if the start corepos equal to the after last node and the finish 
         * corepos equal to the first position, the two iterator equal to.
         */
        if(_DEQUE_ITERATOR_MAP_POINTER(it_first) < _DEQUE_ITERATOR_MAP_POINTER(it_second))
        {
            if(_DEQUE_ITERATOR_MAP_POINTER(it_first) + 1 == _DEQUE_ITERATOR_MAP_POINTER(it_second) &&
               _DEQUE_ITERATOR_COREPOS(it_first) == _DEQUE_ITERATOR_AFTERLAST_POS(it_first) &&
               _DEQUE_ITERATOR_COREPOS(it_second) == _DEQUE_ITERATOR_FIRST_POS(it_second))
            {
                /* the it_first must be deque_begin. */
                assert(_DEQUE_ITERATOR_MAP_POINTER(it_first) == _DEQUE_ITERATOR_MAP_POINTER(_DEQUE_ITERATOR_CONTAINER(it_first)->_t_start));
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            if(_DEQUE_ITERATOR_MAP_POINTER(it_second) + 1 == _DEQUE_ITERATOR_MAP_POINTER(it_first) &&
               _DEQUE_ITERATOR_COREPOS(it_second) == _DEQUE_ITERATOR_AFTERLAST_POS(it_second) &&
               _DEQUE_ITERATOR_COREPOS(it_first) == _DEQUE_ITERATOR_FIRST_POS(it_first))
            {
                /* the it_second must be deque_begin. */
                assert(_DEQUE_ITERATOR_MAP_POINTER(it_second) == _DEQUE_ITERATOR_MAP_POINTER(_DEQUE_ITERATOR_CONTAINER(it_second)->_t_start));
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}
Esempio n. 6
0
/**
 * Access iterator reference data randomly with subscript.
 */
void* _deque_iterator_at(deque_iterator_t it_iter, int n_index)
{
    assert(_deque_iterator_belong_to_deque(_DEQUE_ITERATOR_CONTAINER(it_iter), it_iter));

    it_iter = iterator_next_n(it_iter, n_index);
    return (void*)_deque_iterator_get_pointer(it_iter);
}
Esempio n. 7
0
/**
 * 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;
    }
}
Esempio n. 8
0
/**
 * 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);
    }
}
Esempio n. 9
0
/**
 * 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;
}
Esempio n. 10
0
/**
 * 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;
}
Esempio n. 11
0
/**
 * Get the pointer that point to the iterator reference data.
 */
const void* _deque_iterator_get_pointer(deque_iterator_t it_iter)
{
    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)
    {
        return string_c_str((string_t*)_deque_iterator_get_pointer_auxiliary(it_iter));
    }
    else
    {
        return _deque_iterator_get_pointer_auxiliary(it_iter);
    }
}
Esempio n. 12
0
/**
 * 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);
    }
}
Esempio n. 13
0
/**
 * Get the iterator pointer auxiliary function.
 */
void* _deque_iterator_get_pointer_auxiliary(iterator_t it_iter)
{
    _byte_t* pby_pos = NULL;

    assert(_deque_iterator_belong_to_deque(_GET_DEQUE_CONTAINER(it_iter), it_iter));
    assert(!iterator_equal(it_iter, deque_end(_GET_DEQUE_CONTAINER(it_iter))));

    if(_GET_DEQUE_COREPOS(it_iter) != _GET_DEQUE_AFTERLAST_POS(it_iter))
    {
        pby_pos = _GET_DEQUE_COREPOS(it_iter);
    }
    else
    {
        /* 
         * when the iterator is begin and the corepos equal to afterlast 
         * then get the first element in next chunk.
         */
        _mappointer_t ppby_next = _GET_DEQUE_MAP_POINTER(it_iter) + 1;
        pby_pos = *ppby_next;
    }
    assert(pby_pos != NULL);

    return pby_pos;
}
Esempio n. 14
0
/**
 * 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;
}
Esempio n. 15
0
/**
 * 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;
}