c++sortingvectorstxxl

STXXL: How to sort Vector of pairs on second element?


Similar Question is available here: How do I sort a vector of pairs based on the second element of the pair? but I am interested in External Memory Sorting.

I have tried using the analogies from Internal Memory Sorting but the error occurs in sorter_stream.h file of STXXL as:

My code :

#include <iostream>
#include <stxxl/vector>
#include <stxxl/sorter>
#include <limits>
using namespace std;

typedef std::pair<int,int> my_pair;

struct my_comparator
{
    bool operator()(const my_pair& left, const my_pair& right)
    {
        return left.first < right.first;
    }
    int min_value() const
    {
        return std::numeric_limits<int>::min();
    }
    int max_value() const
    {
        return std::numeric_limits<int>::max();
    }
};
int main()
{
    typedef stxxl::sorter<my_pair, my_comparator> sorter_type;
    sorter_type int_sorter(my_comparator(), 64 * 1024 * 1024);
    for (int i = 10; i > 0; i--)
    {
        int_sorter.push(my_pair(i,i+10));
    }
    int_sorter.sort();  // sort elements (in ascending order)
    while (!int_sorter.empty())
    {
        std::cout << (*int_sorter).first << " "<<(*int_sorter).second<<endl;
        ++int_sorter;
    }
    return 0;
}

Error :

sort_stream.h(481): error C2679: binary '=' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)

UPDATE:

Changing the return type of min_value(),max_value() function to my_pair as:

struct my_comparator
{
    bool operator()(const my_pair& left, const my_pair& right)
    {
        return left.first < right.first;
    }

    my_pair min_value() const
    {
        return my_pair(std::numeric_limits<int>::min(),std::numeric_limits<int>::min());
    }
    my_pair max_value() const
    {
        return my_pair(std::numeric_limits<int>::max(),std::numeric_limits<int>::max());
    }

};

gives the following Error:

sort_helper.h(94): error C3848: expression having type 'const my_comparator' would lose some const-volatile qualifiers in order to call 'bool my_comparator::operator ()(const my_pair &,const my_pair &)'

P.S. : Being a novice (Reputation<50) , I am not allowed to comment, that's why writing a new Question.


Solution

  • Got the following example in STXXL:Sorter Section which addresses the same problem.

    Code:

    #include <stxxl/sorter>
    #include <stxxl/stats>
    #include <stxxl/timer>
    #include <stxxl/random>
    #include <limits>
    struct TwoInteger
    {
        int i, j;
        TwoInteger()
        { }
        TwoInteger(int _i, int _j)
            : i(_i), j(_j)
        { }
    };
    struct TwoIntegerComparator
    {
        bool operator () (const TwoInteger& a, const TwoInteger& b) const
        {
            return a.i < b.i;
        }
        TwoInteger min_value() const
        {
            return TwoInteger(std::numeric_limits<int>::min(), std::numeric_limits<int>::min());
        }
        TwoInteger max_value() const
        {
            return TwoInteger(std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
        }
    };
    int main()
    {
        // template parameter <ValueType, CompareType, BlockSize(optional), AllocStr(optional)>
        typedef stxxl::sorter<TwoInteger, TwoIntegerComparator, 1*1024*1024> sorter_type;
        // create sorter object (CompareType(), MainMemoryLimit)
        sorter_type int_sorter(TwoIntegerComparator(), 64 * 1024 * 1024);
        stxxl::random_number32 rand32;
        stxxl::timer Timer1;
        Timer1.start();
        // insert random numbers from [0,100000)
        for (size_t i = 0; i < 1000; ++i)
        {
            int_sorter.push(TwoInteger(rand32() % 100000, (int)i));    // fill sorter container
        }
        Timer1.stop();
        STXXL_MSG("push time: " << (Timer1.mseconds() / 1000));
        stxxl::timer Timer2;
        Timer2.start();
        int_sorter.sort();  // switch to output state and sort
        Timer2.stop();
        STXXL_MSG("sort time: " << (Timer2.mseconds() / 1000));
        // echo sorted elements
        while (!int_sorter.empty())
        {
            std::cout << int_sorter->i << " ";  // access value
            ++int_sorter;
        }
        return 0;
    }