Search code examples
c++vectoriteratorremove-if

C++ remove_if without iterating through whole vector


I have a vector of pointers, pointing to approx 10MB of packets. In that, from first 2MB, I wanna delete all those that matches my predicate. The problem here is remove_if iterates through the whole vector, even though its not required in my use case. Is there any other efficient way?

fn_del_first_2MB
{
    uint32 deletedSoFar = 0;
    uint32 deleteLimit = 2000000;

    auto it = std::remove_if (cache_vector.begin(), cache_vector.end(),[deleteLimit,&deletedSoFar](const rc_vector& item){
    if(item.ptr_rc->ref_count <= 0) {
        if (deletedSoFar < deleteLimit) {
            deletedSoFar += item.ptr_rc->u16packet_size;
        delete(item.ptr_rc->packet);    
        delete(item.ptr_rc);
            return true;
        }
        else    
            return false;
    }
    else
        return false;
    });
    cache_vector.erase(it, cache_vector.end());
}

In the above code, once the deletedSoFar is greater than deleteLimit, any iteration more than that is unwanted.


Solution

  • You may use your own loop:

    void fn_del_first_2MB()
    {
        const uint32 deleteLimit = 2000000;
    
        uint32 deletedSoFar = 0;
        auto dest = cache_vector.begin();
        auto it = dest
    
        for (; it != cache_vector.end(); ++it) {
            const auto& item = *it;
    
            if (item.ptr_rc->ref_count <= 0) {
                deletedSoFar += item.ptr_rc->u16packet_size;
                delete(item.ptr_rc->packet);    
                delete(item.ptr_rc);
                if (deletedSoFar >= deleteLimit) {
                    ++it;
                    break;
                }
            } else if (dest != it) {
                *dest = std::move(*it);
                ++dest;
            }
        }
        cache_vector.erase(dest, it);
    }