Doppelter Speicherverbrauch beim Kopieren



  • In folgendem Code habe ich für kurze Zeit wegen des Kopiervorgangs den doppelten Speicherverbrauch:

    // Speicherbedarf OK.
    boost::unordered_map<std::string, Info> indexed_by_a;
    // Weiterer Code zum "befüllen" von <indexed_by_a>.
    boost::unordered_map<std::string, Info> indexed_by_b;
    // Ab hier wächst der Speicherbedarf bis auf das Doppelte.
    for (boost::unordered_map<std::string, Info>::const_iterator cit(
      indexed_by_a.begin()), cit_end(indexed_by_a.end());
      cit != cit_end; ++cit) {
      indexed_by_b.insert(
        std::pair<std::string, Info>(cit->second.b, cit->second));
    }
    indexed_by_a.clear();
    // Kopieren beendet, Speicherbedarf wieder OK.
    

    Gibt es eine Möglichkeit während des Kopierens den Speicherverbrauch zu reduzieren? Soweit ist weiss, ist es nicht möglich die Kopierbasis <indexed_by_a> beim Verwenden von Interatoren (also in der Schleife) zu manipulieren.

    Vielen Dank für Eure Ideen!
    T.



  • Vielleicht solltest Du Dir mal boost.multi_index angucken. Mir sieht es stark danach aus, als wenn Du genau das haben willst:

    #include <boost/multi_index_container.hpp>
    #include <boost/multi_index/ordered_index.hpp>
    #include <boost/multi_index/identity.hpp>
    #include <boost/multi_index/mem_fun.hpp>
    
    #include <string>
    #include <iostream>
    
    class info
    {
    public:
        info(std::string const & a, std::string const & b): m_a(a), m_b(b){}
        std::string const & a() const{ return m_a; }
        std::string const & b() const{ return m_b; }
    private:
        std::string m_a;
        std::string m_b;
    };
    
    std::ostream & operator<<(std::ostream & ostr, info const & i)
    {
        return (ostr << i.a() << ' ' << i.b());
    }
    
    struct by_index_a{};
    struct by_index_b{};
    
    namespace bmi = boost::multi_index;
    
    typedef bmi::multi_index_container
        < info
        , bmi::indexed_by
            < bmi::ordered_unique<bmi::tag<by_index_a>, bmi::const_mem_fun<info, std::string const &, &info::a> >
            , bmi::ordered_unique<bmi::tag<by_index_b>, bmi::const_mem_fun<info, std::string const &, &info::b> >
            >
        >
    info_storage;
    
    int main()
    {
        info_storage infos;
        infos.insert(info("hallo", "welt"));
        infos.insert(info("ciao", "mond"));
    
        std::cout << *infos.get<by_index_a>().find("ciao") << std::endl; //suche nach index a
        std::cout << *infos.get<by_index_b>().find("mond") << std::endl; //suche nach index b
    }
    

    Das würde das Kopieren komplett überflüssig machen.



  • Danke für den Hinweis!

    Hier meine Testimplementierung. Bin noch am Herausfinden, wie ich mit der Funktion "modify()" arbeiten kann.

    http://www.highscore.de/cpp/boost/container.html#container_multiindex

    #include <iostream>  // NOLINT
    #include <string>
    
    #include <boost/multi_index_container.hpp>
    #include <boost/multi_index/member.hpp>
    #include <boost/multi_index/hashed_index.hpp>
    #include <boost/multi_index/composite_key.hpp>
    
    struct entry {
      std::string path;
      std::string a;
      std::string b;
      std::string c;
    
      entry(const std::string& path, const std::string& a,
        const std::string& b, const std::string& c) : path(path), a(a),
        b(b), c(c) {
      }
    
      friend std::ostream& operator<<(std::ostream& os, const entry& e) {
        os << e.path << "\n" << e.a << "\n" << e.b << "\n" << e.c << "\n";
        return os;
      }
    };
    
    typedef boost::multi_index::multi_index_container<
      entry,
      boost::multi_index::indexed_by<
        boost::multi_index::hashed_non_unique<
          boost::multi_index::member<entry, std::string, &entry::path>
        >,
        boost::multi_index::hashed_non_unique<
          boost::multi_index::composite_key<
            entry,
            boost::multi_index::member<entry, std::string, &entry::a>,
            boost::multi_index::member<entry, std::string, &entry::b>,
            boost::multi_index::member<entry, std::string, &entry::c>
          >
        >
      >
    > entry_bimap;
    
    int main() {
      entry_bimap eb;
    
      eb.insert(entry("a.exe", "11", "22", "33"));
      eb.insert(entry("b.exe", "44", "55", "66"));
      eb.insert(entry("c.exe", "77", "88", "99"));
    
      std::cout << *eb.find("b.exe") << "\n";
      std::cout << *eb.get<1>().find(boost::make_tuple("77", "88", "99")) << "\n";
      const crc_bimap::nth_index<1>::type& x = eb.get<1>();
      std::cout << *x.find(boost::make_tuple("44", "55", "66")) << "\n";
    
      return 0;
    }
    

Anmelden zum Antworten