STL. Можно ли сохранить map (hash_map) на диске.
От: Serg777  
Дата: 22.01.02 14:07
Оценка:
Сравнительно недавно работаю с STL. Есть ли возможность сохранить весь map (hash_map) на диске? Хотелось бы быстро прочитать объект с диска, а не строить его каждый раз заново. Проблем нет, когда записей мало, но у меня их может быть несколько десятков тысяч. И так как это практически неизменяемая информация, хотелось бы один раз построить объект, сохранить, и затем быстренько читать то, что сохранено. В MFC такая возможность у объекта CMap есть.
Re: STL. Можно ли сохранить map (hash_map) на диске.
От: Юнусов Булат Россия  
Дата: 22.01.02 14:51
Оценка:
Здравствуйте Serg777, Вы писали:

S>Сравнительно недавно работаю с STL. Есть ли возможность сохранить весь map (hash_map) на диске? Хотелось бы быстро прочитать объект с диска, а не строить его каждый раз заново. Проблем нет, когда записей мало, но у меня их может быть несколько десятков тысяч. И так как это практически неизменяемая информация, хотелось бы один раз построить объект, сохранить, и затем быстренько читать то, что сохранено. В MFC такая возможность у объекта CMap есть.


А типы стандартные в мапе?
Или классы кем-то писанные?
Re: STL. Можно ли сохранить map (hash_map) на диске.
От: grs Россия  
Дата: 22.01.02 14:54
Оценка:
Здравствуйте Serg777, Вы писали:

S>Сравнительно недавно работаю с STL. Есть ли возможность сохранить весь map (hash_map) на диске? Хотелось бы быстро прочитать объект с диска, а не строить его каждый раз заново. Проблем нет, когда записей мало, но у меня их может быть несколько десятков тысяч. И так как это практически неизменяемая информация, хотелось бы один раз построить объект, сохранить, и затем быстренько читать то, что сохранено. В MFC такая возможность у объекта CMap есть.


Стандартной функции типа CObject::Serialize() нет. Но что мешает сделать все руками, там, на вскидку, цена вопроса — копейки?
Re[2]: STL. Можно ли сохранить map (hash_map) на диске.
От: Юнусов Булат Россия  
Дата: 22.01.02 15:08
Оценка:
Здравствуйте grs, Вы писали:

grs>Здравствуйте Serg777, Вы писали:


S>>Сравнительно недавно работаю с STL. Есть ли возможность сохранить весь map (hash_map) на диске? Хотелось бы быстро прочитать объект с диска, а не строить его каждый раз заново. Проблем нет, когда записей мало, но у меня их может быть несколько десятков тысяч. И так как это практически неизменяемая информация, хотелось бы один раз построить объект, сохранить, и затем быстренько читать то, что сохранено. В MFC такая возможность у объекта CMap есть.


grs>Стандартной функции типа CObject::Serialize() нет. Но что мешает сделать все руками, там, на вскидку, цена вопроса — копейки?


Я к тому что если типпы в мапе стандартные то все в самом деле просто.

#pragma warning(disable: 4786)

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>


template<class Key, class Value>
std::fstream& operator<<( std::fstream& fs, std::map<Key,Value> const &ob) throw ()
{
    fs << (int)ob.size() << std::endl;
    
    for(std::map<Key,Value>::const_iterator it = ob.begin(); it != ob.end(); ++it)
    {
        fs << it->first  << std::endl;  
        fs << it->second << std::endl;
    }
    return fs;
}

template<class Key, class Value>
std::fstream& operator>>( std::fstream& fs, std::map<Key,Value> &ob) throw ()
{
    ob.clear();
    int size;
    fs >> size;
    for(int i=0; i < size; ++i)
    {
        Key key;
        fs >> key;
        fs >> ob[key];
    }
    return fs;
}

int main(int argc, char* argv[])
{
    std::map< std::string, int > m;
    m["Hello"] = 1;
    m["World"] = 2;

    std::fstream fs;
    fs.open("data.txt", std::ios::out);

    fs << m;
    fs.close();

    fs.open("data.txt", std::ios::in);

    for(std::map< std::string, int>::iterator it = m.begin(); it != m.end(); ++it)
        std::cout << (*it).first << "  " << (*it).second << std::endl;


    return 0;
}


Удачи
Булат
Re[3]: STL. Можно ли сохранить map (hash_map) на диске.
От: Юнусов Булат Россия  
Дата: 22.01.02 15:12
Оценка:
Здравствуйте Юнусов Булат, Вы писали:
Ррр!
Ошибся! непроверил код.
Re[4]: STL. Можно ли сохранить map (hash_map) на диске.
От: Юнусов Булат Россия  
Дата: 22.01.02 15:18
Оценка:
Здравствуйте Юнусов Булат, Вы писали:

ЮБ>Здравствуйте Юнусов Булат, Вы писали:

ЮБ>Ррр!
ЮБ>Ошибся! непроверил код.

int main(int argc, char* argv[])
{
    std::map< std::string, int > m;
    m["Hello"] = 1;
    m["World"] = 2;

    std::fstream fs;
    fs.open("data.txt", std::ios::out);

    fs << m;
    fs.close();

    fs.open("data.txt", std::ios::in);
    m.clear(); // можно не делать т к при закрузке все равно это произойдет - это так для наглядности

    fs >> m;

    for(std::map< std::string, int>::iterator it = m.begin(); it != m.end(); ++it)
        std::cout << (*it).first << "  " << (*it).second << std::endl;

    fs.close();

    return 0;
}


Так верно
Re[3]: STL. Можно ли сохранить map (hash_map) на диске.
От: Аноним  
Дата: 22.01.02 15:40
Оценка:
Здравствуйте Юнусов Булат, Вы писали:

ЮБ>Я к тому что если типпы в мапе стандартные то все в самом деле просто.


Даже если нестандартные, то тоже несмертельно, определяешь для них операторы >> и << и вперед.
Да, к слову, если речь идет о десятках тысяч мало изменяемых записей, может это в какую-нибудь базу лучше запихивать, а не просто в файл?
Re[4]: STL. Можно ли сохранить map (hash_map) на диске.
От: Serg777  
Дата: 22.01.02 16:06
Оценка:
Спасибо всем!
А особенно Юнусову Булату!
Я в принципе понял, что бинарное сохранение таких объектов “в лоб” невозможно. Ведь идея была какая: все эти map строят вспомогательные объекты, а именно hash-таблицы, может быть еще что-то(я пока особо не вникал), и по окончанию работы объект сохраняет себя полностью (вместе со своими вспомогательными объектами). А при чтении из файла прочитывает всю свою кухню без создания этих вспомогательных объектов, одним движением. То что, предлагает Булат – это красивое переопределение операции записи в поток, но основная цель не достигается – каждая запись все равно добавляется со всеми вытекающими (а именно эти самые внутренние объекты заново строятся). Я думаю здесь надо как-то переопределить распределение памяти и распределять в некий буфер, или сразу на диске создавать объекты, но очень это сложно и не совсем понятно, стоит ли игра свеч. А с базой не хочется связываться по одной простой причине – код должен быть написан максимально переносимым и “чистым”, т.е. никаких продуктов сторонних разработчиков. Если есть такая СУБД, я готов ее использовать. Может кто-чего посоветует. Сейчас я отлаживаюсь под Windows. Когда-то давно я работал с db-Vista–ой. Есть и исходники, и проблем с использованием этих исходников вроде как не должно быть, но есть некоторые ”но”... Так что всем спасибо за участие в обсуждении проблемы.
Re[2]: STL. Можно ли сохранить map (hash_map) на диске.
От: Serg777  
Дата: 22.01.02 16:10
Оценка:
grs>Стандартной функции типа CObject::Serialize() нет. Но что мешает сделать все руками, там, на вскидку, цена вопроса — копейки?

Я бы так не сказал. По крайней мере переделать CMap тянет за собой столько всего... А в STL вспомогательные объекты protected
Re[5]: STL. Можно ли сохранить map (hash_map) на диске.
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 22.01.02 16:37
Оценка:
S>Я в принципе понял, что бинарное сохранение таких объектов “в лоб” невозможно. Ведь идея была какая: все эти map строят вспомогательные объекты, а именно hash-таблицы, может быть еще что-то(я пока особо не вникал), и по окончанию работы объект сохраняет себя полностью (вместе со своими вспомогательными объектами). А при чтении из файла прочитывает всю свою кухню без создания этих вспомогательных объектов, одним движением.

Короче говоря, прийдется писать собственную реализацию? Чтобы иметь к ней "тайный" доступ для сохранения не только данных но и, по человечески говоря, индексов к ним.

Вообщем, пора менять подпись на "Все сам, все сам, своими рукамим ..."
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re: STL. Можно ли сохранить map (hash_map) на диске.
От: Lexey Россия  
Дата: 22.01.02 16:39
Оценка: 9 (2)
Здравствуйте Serg777, Вы писали:

S>Сравнительно недавно работаю с STL. Есть ли возможность сохранить весь map (hash_map) на диске? Хотелось бы быстро прочитать объект с диска, а не строить его каждый раз заново. Проблем нет, когда записей мало, но у меня их может быть несколько десятков тысяч. И так как это практически неизменяемая информация, хотелось бы один раз построить объект, сохранить, и затем быстренько читать то, что сохранено. В MFC такая возможность у объекта CMap есть.


Думаю, при желании можно так извратиться.
Создавать memory-mapped файл с фиксированным базовым адресом и переписать new/delete (или stl'ный аллокатор так), чтобы они выделяли память в этом memory-mapped файле. Затем файл закрывать, а объекты не удалять.
В последствии файл вновь мапируется и восстанавливаются указатели на объекты.
Re[4]: STL. Можно ли сохранить map (hash_map) на диске.
От: Юнусов Булат Россия  
Дата: 22.01.02 18:07
Оценка:
Здравствуйте Аноним, Вы писали:

А>Здравствуйте Юнусов Булат, Вы писали:


ЮБ>>Я к тому что если типпы в мапе стандартные то все в самом деле просто.


А>Даже если нестандартные, то тоже несмертельно, определяешь для них операторы >> и << и вперед.

Это очевидно.
Просто когда определите << и >> для Foo&
Непременно захотите определить << и >> для Foo*
Аппетит он во время еды приходит — всяко кому то захочется писать так: map<ключ, Foo*> foo_ptr_map; fs >> foo_ptr_map;
Чтобы не настал сковородец, придется для каждого класса приписать метод для получения его имени
сохранять это имя при <<
завести где нибудь map<string, lpfnCreate> и упихивать туда lpfnCreate при руклблудном IMPLEMENT_SERIAL
грузить имя при >>
создавать класс юзая lpfnCreate
потом класс сам себя за уши и вытащит из fstream
Короче серилизация в классическом виде по полной программе
Re[2]: STL. Можно ли сохранить map (hash_map) на диске.
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 23.01.02 06:39
Оценка:
L>Думаю, при желании можно так извратиться.
L>Создавать memory-mapped файл с фиксированным базовым адресом и переписать new/delete (или stl'ный аллокатор так), чтобы они выделяли память в этом memory-mapped файле. Затем файл закрывать, а объекты не удалять.
L>В последствии файл вновь мапируется и восстанавливаются указатели на объекты.
Сначало прибалдел , а потом появился вопрос — каким образом восстанавливать указатели будем? Конечно, самый дубовый способ — это открывать проекцию по одному и тому же адресу и std::map создавать в том же файле. Вообщем накладно как-то получается.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: STL. Можно ли сохранить map (hash_map) на диске.
От: Lexey Россия  
Дата: 23.01.02 08:15
Оценка:
Здравствуйте Коваленко Дмитрий, Вы писали:

L>>Думаю, при желании можно так извратиться.

L>>Создавать memory-mapped файл с фиксированным базовым адресом и переписать new/delete (или stl'ный аллокатор так), чтобы они выделяли память в этом memory-mapped файле. Затем файл закрывать, а объекты не удалять.
L>>В последствии файл вновь мапируется и восстанавливаются указатели на объекты.
КД>Сначало прибалдел , а потом появился вопрос — каким образом восстанавливать указатели будем? Конечно, самый дубовый способ — это открывать проекцию по одному и тому же адресу и std::map создавать в том же файле. Вообщем

Именно это я и имел в виду (фиксированный базовый адрес). Это совсем не накладно и не дубово, единственная проблема — удастся ли всегда смапировать файл по одному и тому же адресу.

>накладно как-то получается.


Можно конечно попытаться самому указатели править, но вот это уже действительно большой геморрой.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.