Здравствуйте, adontz, Вы писали:
A>Ну положим Intel'овский весьма сильно совместим с MSVC, так что я думаю даже переделывать особо ничего не придёться, а Microsoft Visual C++, Intel C++ Compiler и GNU C++ Compiler это уже весьма большая аудитория. Не побось сказать, что более половины всех разработчиков.
Ну что здесь сказать? Закон потребления пива 20/80: 20% компиляторов покрывают 80 процентов потребностей.
Если вы расчитываете, что сделаете продукт заточенный на 20% наиболее распространенных компиляторов и создадите себе достаточную аудиторию за счет того, что пользователей этих компиляторов гораздо больше, то вы, определенно, правы. Вполне надежный маркетинговый ход. Надеюсь, что в вашем случае он сработает. Но вам придется здесь столкнуться с серьезными конкурентами вроде boost, s11n.net и даже большим объемом унаследованного кода, который использует MFC сериализацию. Поэтому искрене желаю вам успеха на этом поприще.
Но кроме mainstream существуют еще и менее известные, менее раскрученные, но не менее перспективные направления. Например, кроме ОС общего назначения (Win, Linux, BSD, Solaris), есть еще экзотические ОС общего назначения (HP-UX, AIX), ОС реального времени (QNX, VxWoks) и встраиваемые системы (PalmOS, SymbianOS). Кроме задач "офисного программирования", "автоматизации" и "web-программирования" есть еще и другие предметные области. Например системы АСУТП, CAD/CAM приложения, приложения для проведения on-line банковских транзакций, приложения для систем реального времени, для встраиваемых устройств, для ресуроемких научных вычислений и т.д. Большая часть этих задач нуждается в специализированных инструментах.
Например, в обсуждениях вашего проекта McSeem2 приводил примеры того, как правильно подобранный формат хранения данных мог уменьшить объем их представления в разы. Для многих проектов это критически важно. Например, в CAD приложениях. Если для представления средненького чертежа потребуется сохранить 10000 объектов, то вопрос, как их сохранять, встанет очень остро. Например, если двоичный образ объекта занимает 16 байт, а XML-образ 32 байта (оптимистическое предположение), то вместо 160000Kb один чертеж будет занимать 320000Kb. А если в проекте используется не один чертеж, а 5000? Здесь и архивирование не поможет. Я когда-то читал, что при проектировании одного из Боингов использвался CAD пакет, который сохранял информацию в объектную БД (то ли Versant, то ли ObjectivityDB, точно не помню). И это была единственная(!) БД, которая могла удовлетворить нужды проектировщиков, т.к. объемы некоторых чертежей превышали 4Gb.
Мне как раз интереснее такие, не mainstream, проекты и задачи -- в них простора больше, требования выше, а проторенных тропинок меньше. Поэтому не думаю, что ObjESSty будет конкурировать с вашей системой. Поэтому не нужно подводить меня (или себя) к мысли, что ваш продукт более правильный, чем мой. Он -- иной А места всем хватит.
A>>>Вопрос в том зачем это запрещать если человеку действительно надо? E>>Потому, что с моей точки зрения, разработчик класса должен определять разрешать ли классу сериализоваться или нет.
A>Ну вот разработчики std::vector ничего такого не думали, однако всериализовать вектор надо ОК, сдесь сделали заплатку, а дальше?
В отличии от boost, ACE и других объектных библиотек с собственными контейнерами, std::vector является стандартным типом C++. ObjESSty позволяет сериализовать атрибуты стандартных типов C++: char, short, int, float, double, std::string, std::vector, std::list, std::deque, std::set, std::multiset, std::map, std::multimap и обычный одномерный вектор. Только элементами контейнеров должны быть либо объекты стандартных типов, либо сериализуемые объекты. Вполне логичная, и стройная система. Никаких заплаток.
Станут какие-то типы boost-а стандартом, тогда можно будет и о них поговорить.
E>>А если кому-то нужно сериализовать несериализуемый класс -- нет проблем, напиши объект-хранилище нужных атрибутов и сохраняй его вместо исходного объекта. Да, трудоемко.
A>Я так как возиться будет лень (это главный двигатель прогресса), то библиотеку спишут. Удобство использования в конечном итоге важнейший критерий. Но если делается велосипед на любителя, но и вопросов нет.
adontz, ИМХО, вы излишне оптимистично относитесь к вопросам сериализации. Почему-то во главу угла ставите то, что сериализация происходит легко, гладко и незаметно. Достаточно спроектировать нужную для предметной области модель данных, описать C++ типы, применить к парочке объектов супер-мега-тул и все! Все довольны, все смеются! Боюсь, что это не так. Можно рассмотреть несколько аспектов:
1. Объем занимаемых данных. Если объем данных в сериализованном виде критичен для задачи, то здесь будут оцениваться не только возможности инструмента сериализации. Предположим, что кроме XML представления, инструмент может очень эффективно строить двоичное представление (что само по себе уже не просто, попробуйте хотя бы приблизиться к эффективности Asn1 PER). Но, может оказаться, что наибольшая эффективность достигается изменением модели данных на предметном уровне. Скажем в ОП какую-то ломаную линию на чертеже выгодно представлять в виде std::list< pointer * >. А вот сериализовать ее лучше в виде обычного вектора pointer-ов. И окажется, что уже на предметном уровне придется выбирать, что и как будет сериализовано. Т.е. все равно придется выделять сериализуемые типы и явно с ними работать, как с сериализуемыми.
2. Транзактность. Почему-то об этом при обсуждении средств сериализации ничего не говорят, но это важно. Пусть при заполнении пустого архива (хранилища) транзактность не важна, не запишется -- перепишем архив и все. Но при модификации архива? Жалко же терять 20Mb данных из-за того, что произошел сбой при добавлении в архив 5Kb новых объектов. Но, если хранилище поддерживает транзакции, то в приложении, которое занимается сериализацией, нужно будет добавлять код по управлению транзакциями (begin/commit/rollback), диагностику того, что последняя транзакция не была зафиксирована, инициированием восстановления архива и т.д. Окажется, что код сериализации/десериализации уже не так прост.
3. Конкурентный доступ к архивам. Например, несколько приложений работают в связке (типичный unix way). Одно приложение пишет что-то в архив, а другие по ходу дела извлекают из него данные и обрабатывают. Пример: subversion, которая хранит все в хитром сериализованном представлении в BerkeleyDB (до версии 1.1 это был единственный back-end). Тут окажется, что инструмент должен предоставлять средства многопользовательского доступа к хранилищу. А приложения, которые используют этот инструмент, должны учитывать, то, что их могут заблокировать или отказать в проведении операции из-за чужой блокировки. И опять, обращение к сериализации/десериализации уже не будет простым.
4. Формат сериализованного представления. Возьмем XML, здесь извращений побольше. Хорошо, когда инструмент сериализации может использовать собственный DTD для сериализуемых данных. Но тогда, фактически, получается "полузакрытый" формат данных. С одной стороны, он базируется на открытых инструментах, но с другой -- DTD диктуете вы. Хорошо, если все согласны его использовать (имеется в виду, что кроме C++ приложения с автоматической сериализацией, есть еще и другие приложения, на других языках, которые таких инструментов не имеют). А если вам скажут -- что это за proprietary формат? Ах, вам так удобнее данные сохранять? Ну это ваши проблемы. У нас есть отраслевой стандарт, для него уже определены стандартные DTD и у нас уже код для него написан. И будут в ваше приложение передавать XML-и, которые на автоматический парсинг не очень-то и расчитаны. Либо парсить его автоматически нельзя, т.к. нужно делать специфическую обработку ошибок. Пример: спецификация Visa 3D Secure. Набор XML-документов с определенной структурой. Но на парсинг которых накладываются очень жесткие ограничения, проверяемые при сертификации продукта. И если в каком-то проекте есть вручную написанный код для сериализации/десериализации таких XML-документов, то этот код и будет использоваться даже для промежуточного сохранения документов в БД. И сериализации/десериализации в этом приложении будет отводиться одна из самых главных ролей.
Я это все к тому, что необходимость сериализации и требования к ней нужно определять в проекте с самого начала. Иначе могут придти бОльшие неприятности. А раз так, то и типы, подлежащие сериализации могут быть специальным образом выделены (вплоть до размещения в отдельных пространствах имен). И на этом фоне я не считаю, что необходимость производить сериализуемые типы от специального базового типа является драконовским условием.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Вот здесь профессор Дуглас Шмидт описывает паттерн Asynchronous Completion Token. Суть патерна в том, что клиент, выполняя запрос к серверу, передает на сервер специальный объект (Asynchronous Completion Token -- ACT). Сервер возвращает этот объект клиенту в ответе. Благодоря ACT клиент понимает, на какой именно из его запросов ответил сервер. Особенно это удобно при асинхронном взаимодействии клиента и сервера, когда по одному каналу связи идут потоки запросов и ответов. Ключевым моментом в паттерне Asynchronous Completion Token является то, что объект ACT, в общем случае, является непрозрачным для сервера (т.е. сервер совершенно не знает, что именно находится в ACT).
Забавно, что я наткнулся на описание этого паттерна вскоре после того, как реализовал с помощью ObjESSty подобный механизм. В моем случае требовалось организовать цепочку процессов (которые, возможно, работают на разных узлах сети) и которые в асинхронном режиме обслуживают запросы (транзакции) клиента, подключенного к одному из концов этой цепочки (эта цепочка выглядит для клиента как один сервер). Причем каждая транзакция состоит из нескольких сообщений. Например, одна из транзакций состоит из трех сообщений:
1. send -- инициируется клиентом и содержит описание необходимых действий. Клиент повторяет его до тех пор, пока не получит send_result.
2. send_result -- отсылается клиенту в ответ на send. Повторяется до тех пор, пока клиент не пришлет send_finish. Сделано это для того, чтобы в случае потери единичного send_result клиент не инициировал запрос send еще раз.
3. send_finish -- отсылается клиентом в ответ на send_result. Это сообщение говорит серверу, что клиент полностью завершил транзакцию и что сервер может удалить у себя информацию о данной транзакции.
Такая трехфазная схема позволяет организовать асинхронное взаимодействие между клиентом и сервером через один канал. Клиент может инициировать несколько send не дожидаясь ответа на предудущие send. Однако, эта схема требует, чтобы каждая транзакция имела уникальный идентификатор.
Вопрос был в том, как представить идентификаторы транзакций. Особенность еще и в том, что к серверу могли подключаться несколько клиентов, каждый из которых использует собственные идентификаторы. А внутри сервера сообщения от разных клиентов могли смешиваться. В типовом случае сервер состоял из трех процессов:
— первый являлся шлюзом между клиентами и остальной частью сервера (gate). Этих процессов может быть несколько, в зависимости от того, какой транспорт предпочитает конкретный клиент;
— второй процесс (router) занимался выбором конкретного процесса для выполнения запроса клиента. В простейшем случае сервер содержал только один router, к которому подключаются все gate-ы;
— третий процесс (service) занимался выполнением запросов клиентов. Этих процессов может быть несколько.
Таким образом, в один процесс router стекаются запросы от всех клиентов. И router должен получать вместе с каждым запросом уникальный идентификатор запроса. И последующие в цепочке запросы так же должны получать уникальные идентификаторы.
Если бы в качестве идентификаторов транзакций использовались какие-либо простые значения, например уникальные целые числа (UID), то каждый процесс в цепочке, который мог обрабатывать запросы нескольких клиентов, был бы вынужден сохранять полученный от клиента UID, назначать транзакции собственный UID и передавать дальше именно собственный UID. Получив ответ процессу небходимо было по своему UID восстановить исходный UID и ретранслировать ответ клиенту уже с исходным UID. А это означало бы, что все процессы в цепочке должны были бы быть state-ful. Но для некоторых процессов это было слишком накладно. Для того же router-а например.
Поэтому здесь хорошо подходит идея ACT в качестве идентификатора транзакции. Каждый процесс в цепочке получает от предыдущего узла ACT, строит на его основе собственный ACT, сохраняя прямо в нем исходное значение, и передает запрос дальше со своим ACT. Получив ответ, процесс из своего ACT извлекает исходное значение и уже с ним ретранслирует ответ.
Вопрос здесь лишь в том, как удобно сделать работу с непрозрачными ACT. В случае с ObjESSty он разрешился посредством использования механизма subclassing by extension. Для идентификатора транзакции был заведен базовый класс:
Для того, чтобы передавать производные от mbsms_2::trx_id_t идентификаторы транзакций в сообщениях send, send_result, send_finish нужно использовать указатели на mbsms_2::trx_id_t и динамически созданные объекты конкретных типов идентификаторов. Для упрощения работы с арибутами-указателями был создан вспомогательный сериализуемый умный указатель (на самом деле он не такой уже и умный -- для копирования объектов используется их клонирование):
Далее в сообщениях хранятся именно mbsms_2::trx_id_wrapper_t:
class MBSMS_2_TYPE send_t :
public mbapi_3::msg_t
{
OESS_SERIALIZER_EX( send_t, MBSMS_2_TYPE )
public :
//! Конструктор по умолчанию.
/*!
Присваивает всем полям пустые значения.
*/
send_t();
//! Инициализирующий конструктор.
send_t(
//! Идентификатор данной транзакции на стороне отправителя
//! сообщения send_t.const mbsms_2::trx_id_wrapper_t & originator_trx,
....... );
/*!
\since 2.0.0
Конструктор для случая перемаршрутизации сообщения.
Явно задается новый originator_trx, остальные атрибуты берутся
из исходного объекта.
*/
send_t(
//! Идентификатор данной транзакции на стороне отправителя сообщения.const mbsms_2::trx_id_wrapper_t & originator_trx,
//! Исходный объект.const send_t & original );
...
private :
//! Идентификатор данной транзакции на стороне отправителя
//! сообщения send_t.
/*! \since v.2.0.0 */
mbsms_2::trx_id_wrapper_t m_originator_trx;
...
};
Процесс router использует для идентификации проходящих через него транзакций собственный тип идентификатора:
class trx_id_t
: public mbsms_2::trx_id_t
{
OESS_SERIALIZER( trx_id_t )
private :
//! Идентификатор клиента, от которого был получен исходный
//! идентификатор транзакции.
/*!
Может быть пустым, если исходного идентификатора транзакции
не было.
*/
mbapi_3::client_dest_t m_client;
//! Исходный идентификатор транзакции, который был получен от
//! клиента.
/*!
Может быть нулевым, если исходного идентификатора транзакции
не было.
*/
mbsms_2::trx_id_wrapper_t m_original;
public :
/*!
Устанавливает все значения пустыми значениями.
*/
trx_id_t();
/*!
Полностью инициализирующий конструктор.
*/
trx_id_t(
const mbapi_3::client_dest_t & client,
const mbsms_2::trx_id_wrapper_t & original );
//! Клонирование объекта.
std::auto_ptr< mbsms_2::trx_id_t >
clone() const;
//! Является ли объект пустым.
/*!
\return true, если m_client является пустым.
*/bool
is_empty() const;
//! Получить доступ к идентификатору клиента.const mbapi_3::client_dest_t &
client() const;
//! Получить доступ к идентификатор транзакции клиента.const mbsms_2::trx_id_wrapper_t &
original() const;
};
При такой схеме идентификаторы транзакций (ACT) получаются непрозрачными, но с ними удобно работать, т.к. они являются производными от одного базового типа.
Конечно же, такую схему можно было бы реализовать и без ObjESSty. Например, можно было использовать в качестве идентификаторов транзакций строки. И затем процесс router формировал свою строку, в которую включал бы идентификатор клиента и исходный ACT. А затем парсил бы ее. Так, собственно, все и происходит на самом нижнем уровне в ObjESSty, просто это скрыто от программиста.
Подобный механизм "непрозрачных" ACT можно реализовать с использованием любой системы сериализации, это не только ObjESSty. И даже без системы сериализации, вручную. Просто здесь я показал, как это получилось сделать посредством ObjESSty.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
Основная идея в ObjESSty -- это необходимость описания схемы данных на специальном языке и объявление сериализуемых типов производными от специального класса oess_1::stdsn::serializable_t
Вот после этого я уже даже скачивать не стал. Эсть такое понятие как гибкость (flexibility). Данная система уже при прочтении первых строк документации показывает себя не как гибкая (если класс (например std::vector) не производен от oess_1::stdsn::serializable_t то может быть сериализован).
Вообще идея производности от класса очень очень плохая.
Читаем далее
ObjESSty реализован на языке C++ и предназначен для использования в C++ приложениях. Поэтому в ObjESSty встроена поддержка атрибутов-указателей и атрибутов-контейнеров STL.
О! std::vector таки может быть сериализован, зато все другие классы (не std, например boost::shared_ptr) идут лесом
Здравствуйте, eao197, Вы писали:
E>Да, для данного конкретного случая я тоже так думаю. Но вот если добавлять в ObjESSty функциональность по поддержке индексов, то хотелось бы сразу сделать максимально универсальное решение. E>Объемы данных, я думаю будут порядка 1M-3M значений и хранить их нужно будет в течении двух-трех дней, после чего переодически удалять устаревшие объекты (для чего еще нужен будет индекс по timestamp-у).
Делаешь хеши допустим по 8 байт. При нормальном распределении получится вероятность конфликта — 2**64/2**20. Тут можно даже и 4 байтами обойтись. При поиске формируешь хеш, ищешь хеш, дойдя до листовых проверяешь исходные значения. Так как при конфликте все значения находятся рядом, проверяешь следующее. В результате и овцы сыты и волки целы. Работы на день с бумагой(по незнанию) и час кодирования.
E>Открою секрет -- я знаю мало, просто поверхам но из разных областей. Именно это, имхо, и позволило сделать ObjESSty, т.к. там есть совершенно разные задачи -- начиная от парсинга DDL и заканчавая поддержкой восстанавливаемости. Если бы я был спецом в алгоритмах, то я бы, вероятно, занимался оптимизацией работы с кешем, но до релиза бы так и не добрался
Открою секрет. Знание алгоритмов позволяет просто оценивать эффективность на бумажке и до реализации.
E>Ну прям как я E>Только я бы хотел дойти и до того, чтобы и в коммерции мне за изобретение велосипедов платили... Вот тут: Re[7]: Методология дворника.
за высказанные ими замечения в соседней ветви. Резюмировать их можно следующим образом:
— плохо, что для сериализации требуется делать сериализуемый тип производным от специального базового типа;
— плохо, что исходя из вышеозначенного пункта органичивается количество типов, объекты которых могут быть сериализованны;
— плохо, что нет поддержки сериализации в XML и других форматов, отличных от собственного формата ObjESSty.
Замечания ожидаемые. Но, надеюсь, что из рассмотрения было упущено то, что ObjESSty это не только и не столько инструемент для сериализации данных. Начинался проект ObjESSty как проект для создания простой объектной БД и сериализация явилась в ObjESSty, можно сказать, побочным продуктом. Если ее рассматривать в отрыве от БД ObjESSty, то указанные выше замечания кажутся мне вескими. Но дело в том, что основная часть ObjESSty -- это объектная БД.
Вот сделал описание этой БД. Мне было бы интересно мнение участников форума и об этой стороне ObjESSty. Сразу хочу сказать, что сейчас oess_1::db далека от того, что даже я хотел бы в ней видеть. В планах есть внедрение в oess_1::db:
— поддержки индексов (точнее: поддержки возможности индексации содержимого слайса несколькими разными ключами);
— поддержки именованных (корневых) объектов (это понятие из области объектных БД, там можно было дать некоторым объктам уникальные имена и использовать их в качестве "точек входа" в БД);
— предоставления возможности работы с БД нескольким процессам (для чего активно собираюсь использовать возможности ACE).
Буду рад также любым конструктивным предложениям и идеям.
Еще одним из недостатков было указано использование "нетрадиционной" системы компиляции проекта, для использования которой нужно устанавливать язык Ruby. Так же ожидаемое замечание. Но пока я не нашел инструмента, который бы позволял мне поддерживать сразу несколько платформ с помощью одного и того же проектного файла. И при этом бы без проблем поддерживал используемую мной систему каталогов в проекте. Так же буду рад любым конструктивным предложениям по этому поводу.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, adontz, Вы писали:
E>>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
A>
A>Основная идея в ObjESSty -- это необходимость описания схемы данных на специальном языке и объявление сериализуемых типов производными от специального класса oess_1::stdsn::serializable_t
A>Вот после этого я уже даже скачивать не стал. Эсть такое понятие как гибкость (flexibility). Данная система уже при прочтении первых строк документации показывает себя не как гибкая (если класс (например std::vector) не производен от oess_1::stdsn::serializable_t то может быть сериализован).
ObjESSty ведет свою историю не от средств сериализации, а от объектно-ориентированных баз данных. А там подход, когда схема данных имеет одно описание на специальном языке, а представление в языке программирование имеет другое (аналогичное, но другое) описание -- в порядке вещей. Причин тому может быть масса. Например:
— описание на DDL (Data Definition Language) позволяет осуществлять эволюцию схемы данных с автоматическим преобразованием уже сохраненных в БД данных;
— описание на DDL позволяет строить отображение данных в несколько языков программирования. Аналогичный пример -- Corba IDL, из которого можно получить код хоть для C++, хотя для Java;
— описание на DDL позволяет строить инструменты, которые делают "читабельный" дамп сохраненных данных без необходимости ручного программирования. Более того, они позволяют строить инструменты, которые изменяют данные в БД без программирования на C++;
— схема данных в БД и в приложении может различаться. Например, в приложении может использоваться более старая схема данных, чем в БД и БД по DDL описанию умеет обрабатывать это на лету;
— сериализации и сохранению могут подвергаться не все атрибуты объекта, а только часть из них.
A>Вообще идея производности от класса очень очень плохая.
На вкус и цвет...
В объектных базах данных обычной практикой является произведение persistent классов от специального базового класса. В этом есть как идеологический момент (ведь это нормально, когда сериализуемый объект удовлетворяет какому-то интерфейсу, т.е. наследуется от общего предка), так и чисто практический. В базовом классе сосредотачивается функциональность, которая нужна всем производным сериализуемым классам, но которая не должна дублироваться в производных классах. Поэтому я вполне сознательно пошел на то, чтобы в ObjESSty был общий корень иерархии сериализуемых типов.
Вот, например, какую функциональность реализует oess_1::stdsn::serializable_t: Опциональные поля, Расширяемые типы, subclassing by extension.
Для поддержки этих возможностей все равно в сериализуемый класс пришлось бы добавлять какие-то данные (пусть и спрятанные за хитрым макросом). Но в общем базовом классе эти поля уже есть и они не требуют для себя места в производных классах. А если их добавлять в каждый производный класс, то при нескольких уровнях наследования это начнет выливаться в накладные расходы.
Кроме того, oess_1::stdsn::serializable_t не обязательно должен быть единственным базовым. Он вполне может быть примесью.
A>Читаем далее A>
A>ObjESSty реализован на языке C++ и предназначен для использования в C++ приложениях. Поэтому в ObjESSty встроена поддержка атрибутов-указателей и атрибутов-контейнеров STL.
A>О! std::vector таки может быть сериализован, зато все другие классы (не std, например boost::shared_ptr) идут лесом
Не знаю, куда должны идти все остальные типы, но в сериализацию должны идти типы, которые явно для этого расчитаны (имхо). Особенно если объекты этих типов содержат указатели. Ведь C++ не smalltalk, где можно часть памяти виртуальной машины сохранить, а затем восстановить.
Здесь так же есть аналогия с Corba IDL -- ведь в Corba не любой объект может быть использован для Corba-взаимодействия, а только тот, который описан на IDL.
Практика показала, что в сложных программах существуют сотни, если не тысячи C++ типов, но сериализуется только малая часть из них. Поэтому даже накладные расходы на описание этих типов в DDL можно считать несущественными.
A>
A>Я не буду скачивать ни mmx_ru ни ruby чтоб поглядеть на библиотеку которая мне уже не нравиться. Неужели нельзя было сделать vcproj/make файл?
Кросс-платформенный инструмент для компиляции C++ проектов -- это вообще больной вопрос. Кроме mxx_ru я знаком только с двумя такими инструментами: Boost.Jam и SCons. Но первый, по своему удобству использования, не сильно далеко ушел от обычного make (кто не верит, пусть попробует адаптировать Boost.Jam под какой-нибудь новый компилятор). SCons более удобен для меня, но он требует Python, который не меньше Ruby. К тому же мне проще программировать на Ruby, чем на Python.
А vcproj и makefile я не делаю из-за того, что сейчас в ObjESSty 39 проектных файлов. С помощью mxx_ru это поддается управлению. Но во что выльется адаптация проектных файлов хотя бы для трех компиляторов на трех платформах? А сопровождать это как? Ведь многоплатформенность ObjESSty -- это одно из самых главных требований.
Кроме того, если вам таки не нравится весь инструмент, то зачем хаить его систему компиляции? Вы ведь все равно использовать его не будете
Наличие же в Boost-е собственной системы компиляции никого не смущает?
A>По идее вообще не должно компилироваться.
Так и не компилиться
Вот, что было:
class app_data_t :
public oess_1::stdsn::serializable_t
{
OESS_SERIALIZER( app_data_t )
Исправляем:
class app_data_t :
public oess_1::stdsn::serializable_t
{
OESS_SERIALIZER( my_app_data_t )
Получаем:
sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(6) : error C2511: 'void app_data_t::oess_serializer_t::unpack_self(oess_1::stdsn::ient_t &,app_data_t &,oess_1::stdsn::isubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(17) : error C2511: 'void app_data_t::oess_serializer_t::unpack(oess_1::stdsn::ient_t &,app_data_t &,oess_1::stdsn::isubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(29) : error C2511: 'void app_data_t::oess_serializer_t::unpack_complete(oess_1::stdsn::ient_t &,app_data_t &)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(37) : error C2511: 'void app_data_t::oess_serializer_t::pack_self(oess_1::stdsn::oent_t &,const app_data_t &,oess_1::stdsn::osubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(48) : error C2511: 'void app_data_t::oess_serializer_t::pack(oess_1::stdsn::oent_t &,const app_data_t &,oess_1::stdsn::osubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(60) : error C2511: 'void app_data_t::oess_serializer_t::pack_complete(oess_1::stdsn::oent_t &,const app_data_t &)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(67) : error C2511: 'void *app_data_t::oess_serializer_t::cast(const std::string &,app_data_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(106) : error C2660: 'app_data_t::oess_serializer_t::unpack' : function does not take 3 arguments
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(107) : error C2660: 'app_data_t::oess_serializer_t::unpack_complete' : function does not take 2 arguments
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(114) : error C2660: 'app_data_t::oess_serializer_t::pack' : function does not take 3 arguments
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(115) : error C2664: 'app_data_t::oess_serializer_t::pack_complete' : cannot convert parameter 2 from 'const app_data_t' to 'const int'
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(121) : error C2660: 'app_data_t::oess_serializer_t::cast' : function does not take 2 arguments
A>И отсутсвие поддержки XML окончательно поставило крест на всём проекте
Ну, на проекте это точно крест не поставит Максимум, на его распространении
Сейчас XML является мэйнстримом и есть куча попыток писать в него и читать из него. Зачем же еще одна попытка?
Моей задачей изначально было создание компактного двоичного представления и быстрых средств его формирования/разбора. Ведь есть же еще предметные области, в которых XML просто по определению не подходит из-за своих объемов/скорости. Вот там бы ObjESSty и мог найти свое применение.
A>Вот такие пироги
Спасибо за ваше мнение.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
Небольшое замечание: в рахиве все файлы с x-битом установленным. ИМХО не очень удобно find напускать . Можно с чегонить
не того бит снять.
Здравствуйте, eao197, Вы писали:
E>Спасибо! Исправил: http://eao197.narod.ru/objessty/oess.1.4.0-b2.tar.bz2 E>Впредь постараюсь дистрибутивы под Linux-ом собирать, а то потрированные под Win утилиты вот такие фокусы откалывают.
хмм... может архив не закачал? (без прокси сливал, все равно тоже самое)
В сам код еще не смотрел, да врядли я чего-то такого скажу . Тут и без меня наговорят .
При сборке ругалось вот так:
$gcc -v
Reading specs from /usr/lib/gcc-lib/i486-linux/3.3.6/specs
Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang
--prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3
--enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --enable-clocale=gnu
--enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux
Thread model: posix
gcc version 3.3.6 (Debian 1:3.3.6-5)
$ ./build.rb
ar: creating lib/libcls.2.7.0.a
ar: creating lib/libsmart_ref.3.1.0.a
oess_1/util_cpp_serializer/main.cpp:136:2: warning: no newline at end of file
running unit test: ./test.reenterability...
error_count: 0
running unit test: ./test.stdsn.shptr...
launching './test.stdsn.shptr ./test.stdsn.shptr > test/stdsn/shptr/result.test'...
comparing 'test/stdsn/shptr/result.test' and 'test/stdsn/shptr/result.ok'
running unit test: ./test.stdsn.shptr.cloneable...
launching './test.stdsn.shptr.cloneable ./test.stdsn.shptr > test/stdsn/shptr.cloneable/result.test'...
comparing 'test/stdsn/shptr.cloneable/result.test' and 'test/stdsn/shptr.cloneable/result.ok'
In file included from oess_1/file/file.cpp:50:
oess_1/defs/log/h/err.hpp:40:1: warning: "LOG_ERR" redefined
In file included from /usr/include/syslog.h:1,
from ace/os_include/os_syslog.h:28,
from ace/OS.h:329,
from oess_1/file/file.cpp:48:
/usr/include/sys/syslog.h:54:1: warning: this is the location of the previous definition
ar: creating lib/liboess_zlib.1.4.0.a
ar: creating lib/libpcre.4.5.a
ar: creating lib/libpcre++.0.9.5.a
running unit test: ./test.storage.is_exists...
running unit test: ./test.storage.create...
running unit test: ./test.storage.snapshot_collection...
running unit test: ./test.stream_storage.create...
running unit test: ./test.stream_storage.entity...
running unit test: ./test.oess_db.create...
running unit test: ./test.oess_db.ent_raw...
ar: creating lib/libargs.4.3.a
In file included from test/bench/chain_storage/create_update/main.cpp:72:
test/bench/chain_storage/create_update/10000_create.cpp:1250:55: warning: no newline at end of file
In file included from test/bench/chain_storage/create_update/main.cpp:89:
test/bench/chain_storage/create_update/10000_create_half.cpp:625:56: warning: no newline at end of file
In file included from test/bench/chain_storage/create_update/main.cpp:107:
test/bench/chain_storage/create_update/10000_load.cpp:1250:46: warning: no newline at end of file
In file included from test/bench/chain_storage/create_update/main.cpp:125:
test/bench/chain_storage/create_update/10000_update_index.cpp:1250:45: warning: no newline at end of file
In file included from test/bench/chain_storage/create_update/main.cpp:151:
test/bench/chain_storage/create_update/10000_update_size.cpp:1250:56: warning: no newline at end of file
In file included from test/bench/chain_storage/create_update/main.cpp:168:
test/bench/chain_storage/create_update/10000_destroy_half.cpp:625:46: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:70:
test/bench/stream_storage/create_update/1000_create.cpp:125:55: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:87:
test/bench/stream_storage/create_update/1000_create_half.cpp:63:25: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:105:
test/bench/stream_storage/create_update/1000_load.cpp:125:38: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:123:
test/bench/stream_storage/create_update/1000_update_index.cpp:125:39: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:149:
test/bench/stream_storage/create_update/1000_update_size.cpp:125:55: warning: no newline at end of file
In file included from test/bench/stream_storage/create_update/main.cpp:166:
test/bench/stream_storage/create_update/1000_destroy_half.cpp:63:19: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:124:
test/bench/oess_db/create_update/10000_create.cpp:1250:55: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:143:
test/bench/oess_db/create_update/10000_create_half.cpp:625:56: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:163:
test/bench/oess_db/create_update/10000_load.cpp:1250:46: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:183:
test/bench/oess_db/create_update/10000_update_index.cpp:1250:45: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:211:
test/bench/oess_db/create_update/10000_update_size.cpp:1250:56: warning: no newline at end of file
In file included from test/bench/oess_db/create_update/main.cpp:230:
test/bench/oess_db/create_update/10000_destroy_half.cpp:625:46: warning: no newline at end of file
running unit test: ./sample_subextension...
running unit test: ./sample_subextension.auto_ptr...
Ну и по build системе. Почему все-таки mxx, а не какой-нить scons. Ну или может даже CMake?
C чем столкнулся:
1. Ставил ruby (не самый распространенный язык, и так в системе зоопарк: python,perl,clisp вот еще ruby)
2. Распаковывал mxx_ru в каталог с проектом, все распаковалось туда, где стоял (был в <project_root>/dev).
При этом в build.rb ссылки на mxx_ru/cpp и т.д. Неплохо былоб чтобы их архива все распаковывалось сразу в mxx_ru .
3. Поправил скрипт (ибо не везде /usr/local/bin/ruby, в дебиане например просто в /usr/bin)
4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
Неплохо было бы сделать что-то вроде .settings или чего-то похожего чтобы не править скрипт. Сценарий:
$ pwd
~/src/oess/dev
$ mkdir build-debug
$ cd build-debug
$ cp ../settings.default ./settings
$ vi settings
// правим, ставим что это DEBUG, файлы класть сюда
$ ../build.rb
...
// далее
$ mkdir build-release
// аналогично, но для release
E>И если есть возможность рассказать, то разскажи. Моя благодарность не будет знать границ в рамках доступных мне оценок
Хе-хе. Это я люблю.
Вобщем система такая. Три главных свойства Б+ индекса за которые его любят базоведы:
1. Логарифмический поиск, добавление и удаление
2. Доступ к листьям как к сортированному списку
3. Хранение в сегментах.
Мне как-то приходилось делать Б+ дерево. Но одной из задач мне нужно было находить количество элементов в заданном диапазоне. Поэтому ключи были неуникальными. В результате, я мог не доходя до листьев(а это дисковые операции) оценивать количество объектов в заданном диапазоне.
В System/R была несколько другая система. Там правда для ихнего оптимизатора эта задача и не нужна была. В ихнем Б+ дереве были действительно уникальные значения. В листьях хранился список PID с указателями на кортежи. Ессно, при этом был организован и доступ к сортированному списку как по списку листьев со спуском на внутренние списки PID.
Поэтому я и сказал, что почти прав. То есть можно, и так, и так.
Здравствуйте, eao197, Вы писали:
AR>>Ваш продукт мне кажется очень похожим на Versant FastObjects t7. Кстати, рекомендую посмотреть на то, как там реализованы B+ tree индексы.
E>С интересом посмотрю, а где можно исходники глянуть?
Ну исходники — вряд ли. Но в документации описанию механизма индексации посвящено страниц 20 (см. Collected Technical Documentation — C++, главу 8, стр 639-...) (для доступа к документу может потребоваться регистрация на сайте).
Re[8]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, aka50, Вы писали:
E>>А почему ты MPC из ACE не используешь? A>Причина одна: A>1. Perl.
Понятно. Почти как моя причина не использовать SCons
A>>>>>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
E>>>>Для того, чтобы скомпилировать в Debug нужно было просто указать в командной строке --mxx-cpp-debug. Аналогично для Release: --mxx-cpp-release. A>>>Хмм... но тогда былоб неполохо build.rb --help чтоб работал.
E>>Это в документации было написано A>Не в документации, а в target.rb еще и в cp1251
Здравствуйте, adontz, Вы писали:
A>Здравствуйте, eao197, Вы писали:
E>>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
ObjESSty разрабатывается с расчетом на максимальную переносимость. Для достижения этого используется библиотека ACE и кросс-платформенный инструмент для компиляции C++ проектов mxx_ru.
Про mxx_ru уже сказали. Так еще и ACE нужно тянуть за собой. То еще сокровище, в нем, если я ничего не путаю, свои контейнеры, не STL-евские.
ACE вроде для писания всяких распределенных систем главным образом предназначена. Зачем тут-то она нужна?
Ощущения некой монстроузности
Re[5]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, hth, Вы писали:
E>>>Здесь я не нашел ничего принципиально нового для себя. Все же я сторонник того, чтобы сериализующий/десериализующий код генерировался автоматически. И автоматически отслеживались изменения схемы данных. В очень большом числе задач это возможно.
hth>>я хотел бы отметить, что в ROOTe serialisation делается автоматически, hth>>т.е. Streamer method генерится на основе C++ metadata information. hth>>C++ metadata information также спасается в файл вместе с обьектом. hth>>Это позволяет реализовать поддержку scheema evolution - hth>>даже если схема класса изменилась, все равно возможно прочитать hth>>файлы обьектами имеющими "старую" схему.
E>А ROOT работает еще на чем-нибудь, кроме CInt?
CINT — это и есть сам корень ROOTa
E>А ROOT позволяет сериализовать только часть атрибутов класса?
позволяет сериализовать все атрибуты,
при этом если атрибут, является pointer сериализуется и обьект, на который
указывает pointer. Это позволяет иметь directory structure inside file
Пример тут http://carrot.cern.ch/CarrotExamples/hsimple.root
Конечно есть опции (специальные комментарии "напротив" атрибута)
позволяюшие не писать этот атрибут в файл
E>А сериализовать только те атрибуты, значение которых отличается от значения по-умолчанию?
сериализуются значения атрибутов на момент записи
Re[4]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, adontz, Вы писали:
A>А как тебе вот такой сценарий. Программист пишет программу и ему вдруг (а иначе и не бывает) понадобилась сериализация. Он будет скачивать монстра на пару мегабайт к которому прилагается 2 (ACE, mxx_ru) средства разрабтки и 2 (DDL, Ruby) языка или возьмёт удобную систему, которая работает после простого копирования и сама генерирует большую часть нужного уме кода?
Если бы такие универсальные системы были, то жизнь была бы прекрасна. Но на практике оказывается, что продукт, который хорошо работает в одной предметной области, будет не приспособлен к другой продметной области. Поэтому инструементов должно быть много, хороших и разных.
На счет больших объемов...
Ну вот мне потребовались средства, которые я не смог написать сам -- взял ACE и все завелось. Кому-то потребуется сериализация, возмет ObjESSty, увидит, что там ACE. А в ACE еще и многопоточность, и синхронизация, и сокеты, и SSL, и memory-mapped files, и pipes, и все это работает практически везде. Лепота
Если серьезно, то использование boost сейчас не вызывает особых вопросов, хотя boost и поболее будет. ACE -- это аналог boost по мощности, но в другой области. И не такой ракрученный бренд, к сожалению, как boost.
Насчет Ruby+mxx_ru это действительно вопрос. Пока он другого решения не имеет.
A>>>Вообще идея производности от класса очень очень плохая. E>>На вкус и цвет...
A>Это вопрос расширяемости и гибкости.
Я думаю, что это вопрос некоей принципиальной позиции. Если человеку кажется, что опроизводность от специального класса -- это зло, то вопрос можно закрывать -- ObjESSty однозначно не подойдет.
Я же стаю на другой позиции. Если у меня есть класс Window, то я не ожидаю, что его можно сериализовать. Поэтому могу запихивать в него все что хочу. Более того, я знаю, что никто не сможет его сериализовать. Поэтому не ожидаю никаких проблем. Но вот приходит кто-то с каким-то мега-тулом и сериализует мое окно, вместе с указателем на огромное дерево или граф вспомогательных объектов. И как мне это запретить? Явно указывать, что атрибут такой-то класса Window сериализации не подлежит? Тогда чем это отличается от того, чтобы заранее говорить, что вот только эти типы и вот эти их атрибуты должны сериализоваться и все?
E>>В объектных базах данных обычной практикой является произведение persistent классов от специального базового класса. В этом есть как идеологический момент (ведь это нормально, когда сериализуемый объект удовлетворяет какому-то интерфейсу, т.е. наследуется от общего предка),
A>Это как раз НЕ нормально. Должен быть принцип plug-and-play. Никаких изменений в уже существующих класса. Я же не должен переписывать весь Boost только чтобы возспользоваться чудо-сериализацией.
Не очень понимаю о чем речь. Сериализуют в приложении как раз органиченое число прикладных типов. Которые, как правило, к boost или другим объектным библиотекам не имеют отношения. Эти типы объявляются сериализуемыми. Опять же, я привел факт того, что в объектных базах было распространенной практикой использовать специальный базовый класс. Я просто пошел в том же направлении.
E>>так и чисто практический. В базовом классе сосредотачивается функциональность, которая нужна всем производным сериализуемым классам, но которая не должна дублироваться в производных классах.
A>По вышеуказанным причинам функциональность надо сосредотачивать в глобальных функциях, а не в методах классов.
Здесь нужно дать еще одну ссылку, про которую я забыл: Неизвестные расширения. Вот для хранения этих неизвестных расширений и нужны атрибуты в базовом классе, от которого наследуются остальные сериализуемые классы.
A>Вот это-то и есть расширяемость, когда тип изначально не расчитывался на сериализацию, но сделать это всётаки можно.
Выше я уже привел свое мнение по этому поводу. Добавлю, что наличие специального базового класса есть важная характеристика ObjESSty. Если из-за нее ObjESSty где-то не найдет применения -- значит судьба такая, это следствие осознано принятого проектного решения.
E>>Практика показала, что в сложных программах существуют сотни, если не тысячи C++ типов, но сериализуется только малая часть из них. Поэтому даже накладные расходы на описание этих типов в DDL можно считать несущественными.
A>Имеет проблемы с синхронизацией DDL и C++ определения.
Пока да, имеет. Руки еще не дошли до инструмента, который бы по DDL генерировал C++ класс с getter-ами/setter-ами.
E>>Кросс-платформенный инструмент для компиляции C++ проектов -- это вообще больной вопрос. Кроме mxx_ru я знаком только с двумя такими инструментами: Boost.Jam и SCons. Но первый, по своему удобству использования, не сильно далеко ушел от обычного make (кто не верит, пусть попробует адаптировать Boost.Jam под какой-нибудь новый компилятор). SCons более удобен для меня, но он требует Python, который не меньше Ruby. К тому же мне проще программировать на Ruby, чем на Python.
A>Странный подход. Обычно делают так: пишут под одну платформу то что надо, а под другие портируют создавая новые файлы либо пользуясь препроцессором.
Извините, adontz, но тут у меня большой печальный опыт. Я уже десять лет занимаюсь кросс-платформенной разработкой. Довелось поработать (не считая MS-DOS в университете) и в Win3.11 параллельно с WinNT, и под OS/2, и под различными версиями Linux-а, под FreeBSD и Solaris чуть-чуть, под OS/9000, теперь и под HPNonStop. Наилучший результат достигается тогда, когда разработка изначально идет сразу под несколько платформ. Вносится изменение в проект, тут же тестируется под всем, чем можно. Если оставлять на потом, то это плохо заканчивается. Вплоть до обнаружения того, что из-за особенностей OS выбранное проектное решение оказывается нежизнеспособным.
E>>А vcproj и makefile я не делаю из-за того, что сейчас в ObjESSty 39 проектных файлов. С помощью mxx_ru это поддается управлению. Но во что выльется адаптация проектных файлов хотя бы для трех компиляторов на трех платформах? А сопровождать это как? Ведь многоплатформенность ObjESSty -- это одно из самых главных требований.
A>Делаешь для одной платформы. Если это кому-то нужно, то найдётся смельчак и портирует код под другую платформу.
А если смельчака не найдется, а самому потребуется? Пока оказывается, что проще настроить mxx_ru на новый компилятор/OS, чем править десятки проектных файлов. Ведь во что выливается изъятие одного файла из проекта и добавление вместо него новых двух? В правку всех проектных файлов. А если проектный файл не текстовый, а среды разработки для него под рукой нет?
Товарищи из ACE решили подобную проблему тем, что у них есть своя система описания проектов, из которой через Perl скрипты генерируются родные vcproj/makefile/etc для разных компиляторов.
A>Я не видел ни одного человека, который бы пользовался MSVC++ из коммандной строки.
Не сромно так говорить, но можешь посмотреть на одного -- меня. Работаю 90% под WinXP. Из инструемнтов -- vim, sh (портированные unix-utils), mxx_ru, MSDN. Нет проблем. Правда GUI я не пишу уже, года полтора назад писал на Qt, там Visual Studio так же не нужен был.
A>Бост пишет не один человек.
SCons начинал писать и продолжает развивать один человек.
E>>Сейчас XML является мэйнстримом и есть куча попыток писать в него и читать из него. Зачем же еще одна попытка? A>Писать и читать может каждый дурак. Вопрос в том как это делать удобно.
Под попытками читать и писать я подразумевал проекты сериализации, которые пытаются это делать (adontz -- это не камень в твой огород).
Применительно к ObjESSty, в теории, можно сделать и сериализацию в XML, т.к. реально сериализацией занимаются классы, производные от oess_1::stdsn::ient_t/oent_t. Но на практике я не вижу в этом практического интереса. По моему, ObjESSty должно двигаться куда-то в сторону Asn1 (PER в частности), а не в XML.
A>Версионность? Очевидно такая вешь нацелена на крупные проекты, а в них backward compability важное условие.
Чистой версионности, как в некоторых объектных БД, у меня в ObjESSty нет. Сейчас есть Расширяемые типы, subclassing by extension и Неизвестные расширения. В планах есть создание утилиты, которая бы сравнивала две схемы данных и автоматически преобразовывала сериализованные значения из одной схемы (версии) в другу. В своей первой СУБД я такое уже делал. В ObjESSty еще не успел.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, aka50, Вы писали:
A>Здравствуйте, eao197, Вы писали:
E>>Спасибо! Исправил: http://eao197.narod.ru/objessty/oess.1.4.0-b2.tar.bz2 E>>Впредь постараюсь дистрибутивы под Linux-ом собирать, а то потрированные под Win утилиты вот такие фокусы откалывают.
A>хмм... может архив не закачал? (без прокси сливал, все равно тоже самое)
С LOG_ERR поправлю. Предупреждения пострараюсь то же, но т.к. я больше работаю по Windows, но это совешенно несмертельное предупреждение и имеет тендецию появляться вновь
A>Ну и по build системе. Почему все-таки mxx, а не какой-нить scons. Ну или может даже CMake?
CMake когда-то смотрел, мне не понравилось.
Для scons-а мне бы пришлось доделывать поддержку платформы NonStop да и выбранную структуру проекта, вероятно, пришлось бы менять. А программировать на python-е мне не хотелось. Ruby больше понравился.
A>2. Распаковывал mxx_ru в каталог с проектом, все распаковалось туда, где стоял (был в <project_root>/dev). A> При этом в build.rb ссылки на mxx_ru/cpp и т.д. Неплохо былоб чтобы их архива все распаковывалось сразу в mxx_ru .
Поправлю обязательно.
A>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
Для того, чтобы скомпилировать в Debug нужно было просто указать в командной строке --mxx-cpp-debug. Аналогично для Release: --mxx-cpp-release.
A> Неплохо было бы сделать что-то вроде .settings или чего-то похожего чтобы не править скрипт. Сценарий:
Ok. На эту тему покурю. Сложного, вроде, ничего нет.
Постараюсь в ближайшее время сделать все это.
Андрей, а какую информацию о тебе в THANKS включить?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[4]: [ANN] ObjESSty - еще один проект сериализации
Я следил за этими ветками. Только ситуация немного иная: у меня есть проект, который я начал разрабатывать под свои нужды. И под свои нужды использовал, постепенно развивая его. Теперь этот проект достиг момента, когда им можно воспользоваться не только мне. О чем я и сказал.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[10]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, adontz, Вы писали:
A>Вопрос в том одно ли это и то же делать ширпотреб и специнструмент? ИМХО второе делается только на заказ и за серьёзные деньги. Конечно надёться какое-нибудь исключение, но суть именно такова.
Я не делаю ни того, ни другого -- я делаю то, что мне интересно.
Только при попытке объективно оценить ситуацию я понимаю, что вряд ли смогу сделать mainstream-овый инструмент. Но вот инструемент для каких то специфических целей -- это вполне возможно.
A>Проблема в том, что MFC::CArray и ATL::CString для многих не менее стандартны, но системе уже чужды. A>Вот это-то я и называю не гибкостью, когда все типы невольно деляться на build-in и user-defined. A>Представьте себе Си++ без перегрузки операторов и поймёте о чём речь.
Повторю еще раз, я считаю, что сериализация -- это серьезный вопрос. Для успешного решения которого вполне допустимо делить типы на свои и чужие. Ведь когда речь идет о РСУБД, вполне нормальной считается ситуация, что СУБД поддерживает только ограниченное количество типов, а все остальное требует делать на их основе.
A>Я не хочу зависеть от производителя библиотеки в плане выбора типов данных
Ok. Кто же вам мешает. Вы делаете продукт, который позволит сериализовать все, что угодно. Пусть именно этим он и привлекает к себе стороников.
A>Если что-то кажеться сейчас неосуществимым это не значит, что это что-то действительно неосуществимо. A>Описаное вами выше это именно то к чему я стремлюсь. А когда добьюсь, то наверное поставлю себе новую, ещё более крутую цель.
Успехов!
E>>1. Объем занимаемых данных. Если объем данных в сериализованном виде критичен для задачи, то здесь будут оцениваться не только возможности инструмента сериализации. Предположим, что кроме XML представления, инструмент может очень эффективно строить двоичное представление (что само по себе уже не просто, попробуйте хотя бы приблизиться к эффективности Asn1 PER). Но, может оказаться, что наибольшая эффективность достигается изменением модели данных на предметном уровне. Скажем в ОП какую-то ломаную линию на чертеже выгодно представлять в виде std::list< pointer * >. А вот сериализовать ее лучше в виде обычного вектора pointer-ов. И окажется, что уже на предметном уровне придется выбирать, что и как будет сериализовано. Т.е. все равно придется выделять сериализуемые типы и явно с ними работать, как с сериализуемыми.
A>В этом проявляется гибкость. Автоматически нагенерированная сериализация и не должна быть оптимальной по всем параметрам. Она должна удовлетворять всего одному требованию — безглючность. A>Если что-то сильно не устраивает отключаем автомат и пишем руками.
Если вы возьмете стандартную ASN1 PER сериализацию и нормальный инструмент, который ее полностью поддерживает, то вы увидите, что есть автоматическая сериализация, которая эффективна, как минимум: по объему результирующего образа и по скорости сериализации/десериализации. Но даже ASN1 PER можно сделать еще эффективнее, если сериализовать "правильные" для сериализации типы, а не те типы, которыми удобно оперировать в программе.
E>>2. Транзактность. Почему-то об этом при обсуждении средств сериализации ничего не говорят, но это важно. Пусть при заполнении пустого архива (хранилища) транзактность не важна, не запишется -- перепишем архив и все. Но при модификации архива? Жалко же терять 20Mb данных из-за того, что произошел сбой при добавлении в архив 5Kb новых объектов. Но, если хранилище поддерживает транзакции, то в приложении, которое занимается сериализацией, нужно будет добавлять код по управлению транзакциями (begin/commit/rollback), диагностику того, что последняя транзакция не была зафиксирована, инициированием восстановления архива и т.д. Окажется, что код сериализации/десериализации уже не так прост.
A>Это не есть проблема сериализации как таковой. Я выделял три объекта: сериализуемый объект, архив отвечающий за формат хранения данных и последовательный поток байт. Вот поддержка транзакций это функциональность потока байт, но не сериализуемого объекта или архива.
Я и не говорил, что это проблема сериализации. Это проблема использования инструемента сериализации, который, в идеальном случае, транзактность должен обеспечивать. А прикладной код должен учитывать транзактность (см. выше).
A>Когда вы пишете в файл, то транзакции отрываются и закрываются не вызовом функций, а неявно, драйвером NTFS или вовсе не используются на FAT32. Так и с сериализацией. Транзакциями неявно управляет поток байт.
Плохая аналогия. Файловая система еще не в состоянии обеспечить логическую целостность файла. Хотя бы потому, что сбой может произойти между двумя последующими write в программе. Т.е. файловая система корректно зафиксирует результат первого write и физически файл будет неповрежденным, но вот логической целостностью он обладать уже не будет.
E>>3. Конкурентный доступ к архивам. Например, несколько приложений работают в связке (типичный unix way). Одно приложение пишет что-то в архив, а другие по ходу дела извлекают из него данные и обрабатывают. Пример: subversion, которая хранит все в хитром сериализованном представлении в BerkeleyDB (до версии 1.1 это был единственный back-end). Тут окажется, что инструмент должен предоставлять средства многопользовательского доступа к хранилищу. А приложения, которые используют этот инструмент, должны учитывать, то, что их могут заблокировать или отказать в проведении операции из-за чужой блокировки. И опять, обращение к сериализации/десериализации уже не будет простым.
A>Опять таки проблемы потока, но не архива или сериализуемого объекта.
Это не проблемы потока, это проблемы приложения. Что должно делать приложение, если ему говорят, что поток сейчас заблокирован другим приложением? Повторять попытку сразу? После тайм-аута? Сколько попыток делать? Или вообще не делать? Или сам поток не вернет управление пока не разблокируется? А если есть deadlock-и?
E>>4. Формат сериализованного представления. Возьмем XML, здесь извращений побольше. Хорошо, когда инструмент сериализации может использовать собственный DTD для сериализуемых данных. Но тогда, фактически, получается "полузакрытый" формат данных. С одной стороны, он базируется на открытых инструментах, но с другой -- DTD диктуете вы. Хорошо, если все согласны его использовать (имеется в виду, что кроме C++ приложения с автоматической сериализацией, есть еще и другие приложения, на других языках, которые таких инструментов не имеют). А если вам скажут -- что это за proprietary формат? Ах, вам так удобнее данные сохранять? Ну это ваши проблемы. У нас есть отраслевой стандарт, для него уже определены стандартные DTD и у нас уже код для него написан. И будут в ваше приложение передавать XML-и, которые на автоматический парсинг не очень-то и расчитаны. Либо парсить его автоматически нельзя, т.к. нужно делать специфическую обработку ошибок. Пример: спецификация Visa 3D Secure. Набор XML-документов с определенной структурой. Но на парсинг которых накладываются очень жесткие ограничения, проверяемые при сертификации продукта. И если в каком-то проекте есть вручную написанный код для сериализации/десериализации таких XML-документов, то этот код и будет использоваться даже для промежуточного сохранения документов в БД. И сериализации/десериализации в этом приложении будет отводиться одна из самых главных ролей.
A>Опять таки вот она гибкость. Не нравиться автоматически сгенерированный код — пиши свой. Просто случаев когда надо писать свой, по сравнению со случаями когда надо написать по принципу "лишь бы работало" достаточно мало. Поэтому автоматическая генерация кода сериализации с возможностью вкраплений сериализации написаной ручками это ИМХО весьма перспективное направление.
Принцип "лишь бы работало" приводит к тому, что неудачные решения уходят в эксплуатацию, а потом их невозможно заменить на удачные из-за соображений обратной совместимости.
adontz, а есть еще притензии к ObjESSty, кроме:
— наличия специального базового типа, от которого все должны наследоваться;
— поддержки ограниченного количества типов;
— использования собственного средства компиляции проектов;
— отсутствия поддержки XML
?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, eao197, Вы писали:
E>>Вот здесь профессор Дуглас Шмидт описывает паттерн Asynchronous Completion Token. Суть патерна в том, что клиент, выполняя запрос к серверу, передает на сервер специальный объект (Asynchronous Completion Token -- ACT). Сервер возвращает этот объект клиенту в ответе. Благодоря ACT клиент понимает, на какой именно из его запросов ответил сервер. Особенно это удобно при асинхронном взаимодействии клиента и сервера, когда по одному каналу связи идут потоки запросов и ответов. Ключевым моментом в паттерне Asynchronous Completion Token является то, что объект ACT, в общем случае, является непрозрачным для сервера (т.е. сервер совершенно не знает, что именно находится в ACT).
E>>Забавно, что я наткнулся на описание этого паттерна вскоре после того, как реализовал с помощью ObjESSty подобный механизм. В моем случае требовалось организовать цепочку процессов (которые, возможно, работают на разных узлах сети) и которые в асинхронном режиме обслуживают запросы (транзакции) клиента, подключенного к одному из концов этой цепочки (эта цепочка выглядит для клиента как один сервер). Причем каждая транзакция состоит из нескольких сообщений. Например, одна из транзакций состоит из трех сообщений: E>>1. send -- инициируется клиентом и содержит описание необходимых действий. Клиент повторяет его до тех пор, пока не получит send_result. E>>2. send_result -- отсылается клиенту в ответ на send. Повторяется до тех пор, пока клиент не пришлет send_finish. Сделано это для того, чтобы в случае потери единичного send_result клиент не инициировал запрос send еще раз. E>>3. send_finish -- отсылается клиентом в ответ на send_result. Это сообщение говорит серверу, что клиент полностью завершил транзакцию и что сервер может удалить у себя информацию о данной транзакции. E>>Такая трехфазная схема позволяет организовать асинхронное взаимодействие между клиентом и сервером через один канал. Клиент может инициировать несколько send не дожидаясь ответа на предудущие send. Однако, эта схема требует, чтобы каждая транзакция имела уникальный идентификатор.
А>По-моему это называется "тройное рукопожатие" подобные вещи были уже реализованы еще в прошлом веке например в TCP-IP.
И что? TCP/IP -- это транспортный протокол, а не прикладной. Я же говорил о прикладном протоколе.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
А>>По-моему это называется "тройное рукопожатие" подобные вещи были уже реализованы еще в прошлом веке например в TCP-IP.
E>И что? TCP/IP -- это транспортный протокол, а не прикладной. Я же говорил о прикладном протоколе.
Я просто к тому, что такая схема взаимных подтверждений используется во многих местах. Не рассматривайте как наезд
В течении последних двух лет я занимался собственным проектом для сериализации и долговременного хранения сложных C++ объектов: Object Entity Serialization & Stability (ObjESSty). Наконец сейчас он достиг уровня, при котором его не стыдно показать общественности. Что я и делаю при помощи этого сообщения.
Страничка проекта: http://eao197.narod.ru/objessty
Страничка, как и последняя версия проекта находится в состоянии работоспособной beta-версии. Могут наблюдаться различные кривости/ошибки/описки/опечатки, но при наличии интереса и предложений все может быть доведено до ума.
Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
С наилучшими пожеланиями
Евгений Охотников.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, alsemm, Вы писали:
A>Про mxx_ru уже сказали. Так еще и ACE нужно тянуть за собой. То еще сокровище, в нем, если я ничего не путаю, свои контейнеры, не STL-евские.
Хорошей стороной ACE является то, что из него можно брать только то, что тебе необходимо. Никого не заставляют использовать средства ACE, если они не нужны. ObjESSty, например, все берет из STL, а из ACE только платформенно-зависимые средства. Да и в скомпилированном виде ace.dll всего-то 900Kb в release-режиме.
A>ACE вроде для писания всяких распределенных систем главным образом предназначена. Зачем тут-то она нужна?
Изначально я взялся использовать ACE из-за того, что мне потребовались кросс-платформенные средства работы с файловой системой. Свои писать не хотелось, т.к. собственный опыт был и повторять его с учетом различных тонких несовпадений на разных платформах не хотелось. Выбирал между STLsoft, Boost и ACE. STLsoft отпал сразу. Нынешний Boost потяжелее ACE будет, а из реально системных средств в нем filesystem и многопоточность. А в ACE, кроме этого, еще и различные виды IPC. Поэтому остановился на ACE с учетом того, что со временем хотелось бы сделать в ObjESSty возможность работы в клиент-серверном режиме (как BerkeleyDB это делает для предоставления нескольким процессам работать с одной БД).
A>Ощущения некой монстроузности
Да, после подключения ACE так оно и стало. До ACE архив был где-то 200Kb, зато все самому приходилось переписывать на каждой из платформ.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>ObjESSty ведет свою историю не от средств сериализации, а от объектно-ориентированных баз данных. А там подход, когда схема данных имеет одно описание на специальном языке, а представление в языке программирование имеет другое (аналогичное, но другое) описание -- в порядке вещей. Причин тому может быть масса.
А как тебе вот такой сценарий. Программист пишет программу и ему вдруг (а иначе и не бывает) понадобилась сериализация. Он будет скачивать монстра на пару мегабайт к которому прилагается 2 (ACE, mxx_ru) средства разрабтки и 2 (DDL, Ruby) языка или возьмёт удобную систему, которая работает после простого копирования и сама генерирует большую часть нужного уме кода?
A>>Вообще идея производности от класса очень очень плохая. E>На вкус и цвет...
Это вопрос расширяемости и гибкости.
E>В объектных базах данных обычной практикой является произведение persistent классов от специального базового класса. В этом есть как идеологический момент (ведь это нормально, когда сериализуемый объект удовлетворяет какому-то интерфейсу, т.е. наследуется от общего предка),
Это как раз НЕ нормально. Должен быть принцип plug-and-play. Никаких изменений в уже существующих класса. Я же не должен переписывать весь Boost только чтобы возспользоваться чудо-сериализацией.
E>так и чисто практический. В базовом классе сосредотачивается функциональность, которая нужна всем производным сериализуемым классам, но которая не должна дублироваться в производных классах.
По вышеуказанным причинам функциональность надо сосредотачивать в глобальных функциях, а не в методах классов.
E>Не знаю, куда должны идти все остальные типы, но в сериализацию должны идти типы, которые явно для этого расчитаны (имхо). Особенно если объекты этих типов содержат указатели. Ведь C++ не smalltalk, где можно часть памяти виртуальной машины сохранить, а затем восстановить.
Вот это-то и есть расширяемость, когда тип изначально не расчитывался на сериализацию, но сделать это всётаки можно.
E>Практика показала, что в сложных программах существуют сотни, если не тысячи C++ типов, но сериализуется только малая часть из них. Поэтому даже накладные расходы на описание этих типов в DDL можно считать несущественными.
Имеет проблемы с синхронизацией DDL и C++ определения.
E>Кросс-платформенный инструмент для компиляции C++ проектов -- это вообще больной вопрос. Кроме mxx_ru я знаком только с двумя такими инструментами: Boost.Jam и SCons. Но первый, по своему удобству использования, не сильно далеко ушел от обычного make (кто не верит, пусть попробует адаптировать Boost.Jam под какой-нибудь новый компилятор). SCons более удобен для меня, но он требует Python, который не меньше Ruby. К тому же мне проще программировать на Ruby, чем на Python.
Странный подход. Обычно делают так: пишут под одну платформу то что надо, а под другие портируют создавая новые файлы либо пользуясь препроцессором.
E>А vcproj и makefile я не делаю из-за того, что сейчас в ObjESSty 39 проектных файлов. С помощью mxx_ru это поддается управлению. Но во что выльется адаптация проектных файлов хотя бы для трех компиляторов на трех платформах? А сопровождать это как? Ведь многоплатформенность ObjESSty -- это одно из самых главных требований.
Делаешь для одной платформы. Если это кому-то нужно, то найдётся смельчак и портирует код под другую платформу.
E>Кроме того, если вам таки не нравится весь инструмент, то зачем храить его систему компиляции? Вы ведь все равно использовать его не будете
Я не видел ни одного человека, который бы пользовался MSVC++ из коммандной строки.
E>Наличие же в Boost-е собственной системы компиляции никого не смущает?
Бост пишет не один человек.
E>Получаем: E>
E>sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
E>sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
E>sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
E>sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
E>sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
E>sample\app_recovery\main.cpp(62) : error C2143: syntax error : missing ',' before '&'
E>sample\app_recovery\main.cpp(62) : error C2061: syntax error : identifier 'my_app_data_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(6) : error C2511: 'void app_data_t::oess_serializer_t::unpack_self(oess_1::stdsn::ient_t &,app_data_t &,oess_1::stdsn::isubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(17) : error C2511: 'void app_data_t::oess_serializer_t::unpack(oess_1::stdsn::ient_t &,app_data_t &,oess_1::stdsn::isubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(29) : error C2511: 'void app_data_t::oess_serializer_t::unpack_complete(oess_1::stdsn::ient_t &,app_data_t &)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(37) : error C2511: 'void app_data_t::oess_serializer_t::pack_self(oess_1::stdsn::oent_t &,const app_data_t &,oess_1::stdsn::osubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(48) : error C2511: 'void app_data_t::oess_serializer_t::pack(oess_1::stdsn::oent_t &,const app_data_t &,oess_1::stdsn::osubclass_extension_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(60) : error C2511: 'void app_data_t::oess_serializer_t::pack_complete(oess_1::stdsn::oent_t &,const app_data_t &)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(67) : error C2511: 'void *app_data_t::oess_serializer_t::cast(const std::string &,app_data_t *)' : overloaded member function not found in 'app_data_t::oess_serializer_t'
E> sample\app_recovery\main.cpp(62) : see declaration of 'app_data_t::oess_serializer_t'
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(106) : error C2660: 'app_data_t::oess_serializer_t::unpack' : function does not take 3 arguments
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(107) : error C2660: 'app_data_t::oess_serializer_t::unpack_complete' : function does not take 2 arguments
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(114) : error C2660: 'app_data_t::oess_serializer_t::pack' : function does not take 3 arguments
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(115) : error C2664: 'app_data_t::oess_serializer_t::pack_complete' : cannot convert parameter 2 from 'const app_data_t' to 'const int'
E> No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
E>d:\home\eao\sandboxes\oess_1\tags\1.4.0-b1\dev\sample\app_recovery\main.ddl.cpp(121) : error C2660: 'app_data_t::oess_serializer_t::cast' : function does not take 2 arguments
19 ошибок и ни из одной не ясно чтоже произошло Но то что не компилируется это несомненно плюс.
A>>И отсутсвие поддержки XML окончательно поставило крест на всём проекте E>Ну, на проекте это точно крест не поставит Максимум, на его распространении E>Сейчас XML является мэйнстримом и есть куча попыток писать в него и читать из него. Зачем же еще одна попытка?
Писать и читать может каждый дурак. Вопрос в том как это делать удобно.
E>Моей задачей изначально было создание компактного двоичного представления и быстрых средств его формирования/разбора. Ведь есть же еще предметные области, в которых XML просто по определению не подходит из-за своих объемов/скорости. Вот там бы ObjESSty и мог найти свое применение.
Версионность? Очевидно такая вешь нацелена на крупные проекты, а в них backward compability важное условие.
Здравствуйте, eao197, Вы писали:
E>Если бы такие универсальные системы были, то жизнь была бы прекрасна.
Вот я и разрабатываю такую Осталось только добавить в список поддерживаемых компиляторов GCC и всё будет ОК.
A>>Это вопрос расширяемости и гибкости. E>Я думаю, что это вопрос некоей принципиальной позиции. Если человеку кажется, что опроизводность от специального класса -- это зло, то вопрос можно закрывать -- ObjESSty однозначно не подойдет.
Если прочесть те два топика ссылки на которые я дал, то станет видно, что такую позицию занимает довольно много людей.
E>Я же стаю на другой позиции. Если у меня есть класс Window, то я не ожидаю, что его можно сериализовать. Поэтому могу запихивать в него все что хочу. Более того, я знаю, что никто не сможет его сериализовать. Поэтому не ожидаю никаких проблем. Но вот приходит кто-то с каким-то мега-тулом и сериализует мое окно, вместе с указателем на огромное дерево или граф вспомогательных объектов. И как мне это запретить?
Вопрос в том зачем это запрещать если человеку действительно надо?
E>Не очень понимаю о чем речь. Сериализуют в приложении как раз органиченое число прикладных типов.
Но некоторые из них определены в сторонних библиотеках, как например std::string. А если я использую другой класс строки?
A>>Вот это-то и есть расширяемость, когда тип изначально не расчитывался на сериализацию, но сделать это всётаки можно.
E>Выше я уже привел свое мнение по этому поводу. Добавлю, что наличие специального базового класса есть важная характеристика ObjESSty. Если из-за нее ObjESSty где-то не найдет применения -- значит судьба такая, это следствие осознано принятого проектного решения.
ОК, просто это большой минус в глазах многих потенциальных потребителей.
A>>Делаешь для одной платформы. Если это кому-то нужно, то найдётся смельчак и портирует код под другую платформу. E>А если смельчака не найдется, а самому потребуется?
Если смельчака не найдёться, значит проект никому не нужен
E>Не сромно так говорить, но можешь посмотреть на одного -- меня. Работаю 90% под WinXP. Из инструемнтов -- vim, sh (портированные unix-utils), mxx_ru, MSDN. Нет проблем. Правда GUI я не пишу уже, года полтора назад писал на Qt, там Visual Studio так же не нужен был.
И mainstream компилятор VC++? Думаю всё-таки gcc.
E>Под попытками читать и писать я подразумевал проекты сериализации, которые пытаются это делать (adontz -- это не камень в твой огород).
Моя пока ничего не пишет. Я временно погряз в написании сопуствующих вещей.
Здравствуйте, adontz, Вы писали:
E>>Если бы такие универсальные системы были, то жизнь была бы прекрасна.
A>Вот я и разрабатываю такую Осталось только добавить в список поддерживаемых компиляторов GCC и всё будет ОК.
Раз за вас, у вас еще есть оптимизм
Только GCC -- это еще не все компиляторы. Даже на Windows есть еще пара-тройка. Borland C++, MetaWare, например. А есть платформы, на которые GCC еще и не портирован -- HPNonStop.
A>Если прочесть те два топика ссылки на которые я дал, то станет видно, что такую позицию занимает довольно много людей.
Но это аргумент к чему? К тому, чтобы переделать ObjESSty? Это уже не реально.
E>>Я же стаю на другой позиции. Если у меня есть класс Window, то я не ожидаю, что его можно сериализовать. Поэтому могу запихивать в него все что хочу. Более того, я знаю, что никто не сможет его сериализовать. Поэтому не ожидаю никаких проблем. Но вот приходит кто-то с каким-то мега-тулом и сериализует мое окно, вместе с указателем на огромное дерево или граф вспомогательных объектов. И как мне это запретить?
A>Вопрос в том зачем это запрещать если человеку действительно надо?
Потому, что с моей точки зрения, разработчик класса должен определять разрешать ли классу сериализоваться или нет. А если кому-то нужно сериализовать несериализуемый класс -- нет проблем, напиши объект-хранилище нужных атрибутов и сохраняй его вместо исходного объекта. Да, трудоемко. Зато гибко: один и тот же класс можно сериализовать разными инструментами, а он ничего и не знает
E>>Не очень понимаю о чем речь. Сериализуют в приложении как раз органиченое число прикладных типов.
A>Но некоторые из них определены в сторонних библиотеках, как например std::string. А если я использую другой класс строки?
Как раз std::string ObjESSty сериализует
На счет остальных классов -- см. выше.
A>ОК, просто это большой минус в глазах многих потенциальных потребителей.
Так ведь я и не продавец
A>Если смельчака не найдёться, значит проект никому не нужен
А я как же
E>>Не сромно так говорить, но можешь посмотреть на одного -- меня. Работаю 90% под WinXP. Из инструемнтов -- vim, sh (портированные unix-utils), mxx_ru, MSDN. Нет проблем. Правда GUI я не пишу уже, года полтора назад писал на Qt, там Visual Studio так же не нужен был.
A>И mainstream компилятор VC++? Думаю всё-таки gcc.
Как раз под Windows -- mainstream компилятор это VC++ 7.1. А Borland C++, MinGW и cygwin я использую для проверки.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Рад за вас, у вас еще есть оптимизм E>Только GCC -- это еще не все компиляторы. Даже на Windows есть еще пара-тройка. Borland C++, MetaWare, например. А есть платформы, на которые GCC еще и не портирован -- HPNonStop.
Ну положим Intel'овский весьма сильно совместим с MSVC, так что я думаю даже переделывать особо ничего не придёться, а Microsoft Visual C++, Intel C++ Compiler и GNU C++ Compiler это уже весьма большая аудитория. Не побось сказать, что более половины всех разработчиков.
A>>Если прочесть те два топика ссылки на которые я дал, то станет видно, что такую позицию занимает довольно много людей. E>Но это аргумент к чему? К тому, чтобы переделать ObjESSty? Это уже не реально.
A>>Вопрос в том зачем это запрещать если человеку действительно надо? E>Потому, что с моей точки зрения, разработчик класса должен определять разрешать ли классу сериализоваться или нет.
Ну вот разработчики std::vector ничего такого не думали, однако всериализовать вектор надо ОК, сдесь сделали заплатку, а дальше?
E>А если кому-то нужно сериализовать несериализуемый класс -- нет проблем, напиши объект-хранилище нужных атрибутов и сохраняй его вместо исходного объекта. Да, трудоемко.
Я так как возиться будет лень (это главный двигатель прогресса), то библиотеку спишут. Удобство использования в конечном итоге важнейший критерий. Но если делается велосипед на любителя, но и вопросов нет.
Здравствуйте, eao197, Вы писали:
E>Если вы расчитываете, что сделаете продукт заточенный на 20% наиболее распространенных компиляторов и создадите себе достаточную аудиторию за счет того, что пользователей этих компиляторов гораздо больше, то вы, определенно, правы. Вполне надежный маркетинговый ход.
Стараюсь
E>Надеюсь, что в вашем случае он сработает. Но вам придется здесь столкнуться с серьезными конкурентами вроде boost, s11n.net и даже большим объемом унаследованного кода, который использует MFC сериализацию. Поэтому искрене желаю вам успеха на этом поприще.
Конкурентов я не боюсь. Волков бояться в лес не ходить. А большой объём унаследованного кода не достанеться ни мне ни комубы-то ни было ещё из конкурентов. Его просто когда-нибудь перепишут.
E>Но кроме mainstream существуют еще и менее известные, менее раскрученные, но не менее перспективные направления. Например, кроме ОС общего назначения (Win, Linux, BSD, Solaris), есть еще экзотические ОС общего назначения (HP-UX, AIX), ОС реального времени (QNX, VxWoks) и встраиваемые системы (PalmOS, SymbianOS). Кроме задач "офисного программирования", "автоматизации" и "web-программирования" есть еще и другие предметные области. Например системы АСУТП, CAD/CAM приложения, приложения для проведения on-line банковских транзакций, приложения для систем реального времени, для встраиваемых устройств, для ресуроемких научных вычислений и т.д. Большая часть этих задач нуждается в специализированных инструментах.
Вопрос в том одно ли это и то же делать ширпотреб и специнструмент? ИМХО второе делается только на заказ и за серьёзные деньги. Конечно надёться какое-нибудь исключение, но суть именно такова.
E>А места всем хватит.
E>В отличии от boost, ACE и других объектных библиотек с собственными контейнерами, std::vector является стандартным типом C++. ObjESSty позволяет сериализовать атрибуты стандартных типов C++: char, short, int, float, double, std::string, std::vector, std::list, std::deque, std::set, std::multiset, std::map, std::multimap и обычный одномерный вектор. Только элементами контейнеров должны быть либо объекты стандартных типов, либо сериализуемые объекты. Вполне логичная, и стройная система. Никаких заплаток.
Проблема в том, что MFC::CArray и ATL::CString для многих не менее стандартны, но системе уже чужды.
Вот это-то я и называю не гибкостью, когда все типы невольно деляться на build-in и user-defined.
Представьте себе Си++ без перегрузки операторов и поймёте о чём речь.
E>Станут какие-то типы boost-а стандартом, тогда можно будет и о них поговорить.
Я не хочу зависеть от производителя библиотеки в плане выбора типов данных
E>adontz, ИМХО, вы излишне оптимистично относитесь к вопросам сериализации. Почему-то во главу угла ставите то, что сериализация происходит легко, гладко и незаметно. Достаточно спроектировать нужную для предметной области модель данных, описать C++ типы, применить к парочке объектов супер-мега-тул и все! Все довольны, все смеются!
В начале прошлого века люди по 30 минут неподвижно сидели перед дагеротипами, кто тогда думал, что можно будет нажать кнопку и уже через 15 секунд получить фотографию?
Если что-то кажеться сейчас неосуществимым это не значит, что это что-то действительно неосуществимо.
Описаное вами выше это именно то к чему я стремлюсь. А когда добьюсь, то наверное поставлю себе новую, ещё более крутую цель.
E>1. Объем занимаемых данных. Если объем данных в сериализованном виде критичен для задачи, то здесь будут оцениваться не только возможности инструмента сериализации. Предположим, что кроме XML представления, инструмент может очень эффективно строить двоичное представление (что само по себе уже не просто, попробуйте хотя бы приблизиться к эффективности Asn1 PER). Но, может оказаться, что наибольшая эффективность достигается изменением модели данных на предметном уровне. Скажем в ОП какую-то ломаную линию на чертеже выгодно представлять в виде std::list< pointer * >. А вот сериализовать ее лучше в виде обычного вектора pointer-ов. И окажется, что уже на предметном уровне придется выбирать, что и как будет сериализовано. Т.е. все равно придется выделять сериализуемые типы и явно с ними работать, как с сериализуемыми.
В этом проявляется гибкость. Автоматически нагенерированная сериализация и не должна быть оптимальной по всем параметрам. Она должна удовлетворять всего одному требованию — безглючность.
Если что-то сильно не устраивает отключаем автомат и пишем руками.
E>2. Транзактность. Почему-то об этом при обсуждении средств сериализации ничего не говорят, но это важно. Пусть при заполнении пустого архива (хранилища) транзактность не важна, не запишется -- перепишем архив и все. Но при модификации архива? Жалко же терять 20Mb данных из-за того, что произошел сбой при добавлении в архив 5Kb новых объектов. Но, если хранилище поддерживает транзакции, то в приложении, которое занимается сериализацией, нужно будет добавлять код по управлению транзакциями (begin/commit/rollback), диагностику того, что последняя транзакция не была зафиксирована, инициированием восстановления архива и т.д. Окажется, что код сериализации/десериализации уже не так прост.
Это не есть проблема сериализации как таковой. Я выделял три объекта: сериализуемый объект, архив отвечающий за формат хранения данных и последовательный поток байт. Вот поддержка транзакций это функциональность потока байт, но не сериализуемого объекта или архива.
Когда вы пишете в файл, то транзакции отрываются и закрываются не вызовом функций, а неявно, драйвером NTFS или вовсе не используются на FAT32. Так и с сериализацией. Транзакциями неявно управляет поток байт.
E>3. Конкурентный доступ к архивам. Например, несколько приложений работают в связке (типичный unix way). Одно приложение пишет что-то в архив, а другие по ходу дела извлекают из него данные и обрабатывают. Пример: subversion, которая хранит все в хитром сериализованном представлении в BerkeleyDB (до версии 1.1 это был единственный back-end). Тут окажется, что инструмент должен предоставлять средства многопользовательского доступа к хранилищу. А приложения, которые используют этот инструмент, должны учитывать, то, что их могут заблокировать или отказать в проведении операции из-за чужой блокировки. И опять, обращение к сериализации/десериализации уже не будет простым.
Опять таки проблемы потока, но не архива или сериализуемого объекта.
E>4. Формат сериализованного представления. Возьмем XML, здесь извращений побольше. Хорошо, когда инструмент сериализации может использовать собственный DTD для сериализуемых данных. Но тогда, фактически, получается "полузакрытый" формат данных. С одной стороны, он базируется на открытых инструментах, но с другой -- DTD диктуете вы. Хорошо, если все согласны его использовать (имеется в виду, что кроме C++ приложения с автоматической сериализацией, есть еще и другие приложения, на других языках, которые таких инструментов не имеют). А если вам скажут -- что это за proprietary формат? Ах, вам так удобнее данные сохранять? Ну это ваши проблемы. У нас есть отраслевой стандарт, для него уже определены стандартные DTD и у нас уже код для него написан. И будут в ваше приложение передавать XML-и, которые на автоматический парсинг не очень-то и расчитаны. Либо парсить его автоматически нельзя, т.к. нужно делать специфическую обработку ошибок. Пример: спецификация Visa 3D Secure. Набор XML-документов с определенной структурой. Но на парсинг которых накладываются очень жесткие ограничения, проверяемые при сертификации продукта. И если в каком-то проекте есть вручную написанный код для сериализации/десериализации таких XML-документов, то этот код и будет использоваться даже для промежуточного сохранения документов в БД. И сериализации/десериализации в этом приложении будет отводиться одна из самых главных ролей.
Опять таки вот она гибкость. Не нравиться автоматически сгенерированный код — пиши свой. Просто случаев когда надо писать свой, по сравнению со случаями когда надо написать по принципу "лишь бы работало" достаточно мало. Поэтому автоматическая генерация кода сериализации с возможностью вкраплений сериализации написаной ручками это ИМХО весьма перспективное направление.
Здравствуйте, eao197, Вы писали:
E>Я не делаю ни того, ни другого -- я делаю то, что мне интересно.
То есть проект — для души? Сам таким болел. Закончится тем, что всё перепишешь ещё лучше, чем советовали
E>Повторю еще раз, я считаю, что сериализация -- это серьезный вопрос.
ОК, только лично меня твой подход не избавляет от этой серьёзности, а подавляет ею.
A>>В этом проявляется гибкость. Автоматически нагенерированная сериализация и не должна быть оптимальной по всем параметрам. Она должна удовлетворять всего одному требованию — безглючность. A>>Если что-то сильно не устраивает отключаем автомат и пишем руками.
E>Если вы возьмете стандартную ASN1 PER сериализацию и нормальный инструмент, который ее полностью поддерживает, то вы увидите, что есть автоматическая сериализация, которая эффективна, как минимум: по объему результирующего образа и по скорости сериализации/десериализации. Но даже ASN1 PER можно сделать еще эффективнее, если сериализовать "правильные" для сериализации типы, а не те типы, которыми удобно оперировать в программе.
ОК, вот ещё одна умопомрачительная задача: сделать множества "правильных" для сериализации типов и типов удобных для использования в программе идентичными.
E>Плохая аналогия. Файловая система еще не в состоянии обеспечить логическую целостность файла. Хотя бы потому, что сбой может произойти между двумя последующими write в программе. Т.е. файловая система корректно зафиксирует результат первого write и физически файл будет неповрежденным, но вот логической целостностью он обладать уже не будет.
Поэтому я и ввёл методы scope_begin/scope_end.
E>Это не проблемы потока, это проблемы приложения. Что должно делать приложение, если ему говорят, что поток сейчас заблокирован другим приложением? Повторять попытку сразу? После тайм-аута? Сколько попыток делать? Или вообще не делать? Или сам поток не вернет управление пока не разблокируется? А если есть deadlock-и?
Поток кинет исключение с кодом ошибки. Программа сама решит что делать: повторить попытку или выдать сообщение об ошибке. Более того политика обработки ошибок вполне может задаваться потоку каким-нибуд set_flags(int) до использованияи тогда можно будет указать правило типа "попытайсятри раза ожидая не более 3 секунд а потом киньб исключение". Вобщем технических проблем с обработкой ошибок нет.
A>>Опять таки вот она гибкость. Не нравиться автоматически сгенерированный код — пиши свой. Просто случаев когда надо писать свой, по сравнению со случаями когда надо написать по принципу "лишь бы работало" достаточно мало. Поэтому автоматическая генерация кода сериализации с возможностью вкраплений сериализации написаной ручками это ИМХО весьма перспективное направление.
E>Принцип "лишь бы работало" приводит к тому, что неудачные решения уходят в эксплуатацию, а потом их невозможно заменить на удачные из-за соображений обратной совместимости.
Есть такое дело. Но сразу хорошая вешь не появляеться. Любой проект проходит некоторую эволюцию начиная с весьма посредственных результатов.
E>adontz, а есть еще притензии к ObjESSty, кроме: E>- наличия специального базового типа, от которого все должны наследоваться;
+ E>- поддержки ограниченного количества типов;
+ E>- использования собственного средства компиляции проектов;
дело не в том собственное оно или нет. Если вместе с проектом будут идти vbs и pl файл то всё ок. А так качать много чего надо. E>- отсутствия поддержки XML
Я бы сказал шире — плохая расширяемость. Насколько легко подключить новое хранилище или формат хранения данных?
Здравствуйте, adontz, Вы писали:
A>>>В этом проявляется гибкость. Автоматически нагенерированная сериализация и не должна быть оптимальной по всем параметрам. Она должна удовлетворять всего одному требованию — безглючность. A>>>Если что-то сильно не устраивает отключаем автомат и пишем руками.
E>>Если вы возьмете стандартную ASN1 PER сериализацию и нормальный инструмент, который ее полностью поддерживает, то вы увидите, что есть автоматическая сериализация, которая эффективна, как минимум: по объему результирующего образа и по скорости сериализации/десериализации. Но даже ASN1 PER можно сделать еще эффективнее, если сериализовать "правильные" для сериализации типы, а не те типы, которыми удобно оперировать в программе.
A>ОК, вот ещё одна умопомрачительная задача: сделать множества "правильных" для сериализации типов и типов удобных для использования в программе идентичными.
Не реальная. Но вечный двигатель до сих пор изобретают.
E>>Плохая аналогия. Файловая система еще не в состоянии обеспечить логическую целостность файла. Хотя бы потому, что сбой может произойти между двумя последующими write в программе. Т.е. файловая система корректно зафиксирует результат первого write и физически файл будет неповрежденным, но вот логической целостностью он обладать уже не будет.
A>Поэтому я и ввёл методы scope_begin/scope_end.
E>>adontz, а есть еще притензии к ObjESSty, кроме: E>>- наличия специального базового типа, от которого все должны наследоваться; A>+
Понятно. E>>- поддержки ограниченного количества типов; A>+
Понятно. E>>- использования собственного средства компиляции проектов; A>дело не в том собственное оно или нет. Если вместе с проектом будут идти vbs и pl файл то всё ок. А так качать много чего надо.
pl -- это Perl? А если у меня на машине Perl-а нет? Вот принципиально не люблю Perl-а и не ставлю себе, пока сильно не прижмет.
E>>- отсутствия поддержки XML A>Я бы сказал шире — плохая расширяемость. Насколько легко подключить новое хранилище или формат хранения данных?
А насколько просто подключить к SQLite или MetaKit, или BerkeleyDB новое хранилище или формат хранения данных? Ведь ObjESSty изначально создавалась как восстановочная БД, а возможность сериализации (я считаю не слабая), явилась побочным продуктом. Который сейчас используется и независимо от восстановочной БД.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[13]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Не реальная. Но вечный двигатель до сих пор изобретают.
В рамках языка да, а в рамках языка+компилятора не знаю.
A>>дело не в том собственное оно или нет. Если вместе с проектом будут идти vbs и pl файл то всё ок. А так качать много чего надо. E>pl -- это Perl? А если у меня на машине Perl-а нет? Вот принципиально не люблю Perl-а и не ставлю себе, пока сильно не прижмет.
VBScript для Windows и Perl для Unix. Делать они должны одно и то же.
A>>Я бы сказал шире — плохая расширяемость. Насколько легко подключить новое хранилище или формат хранения данных? E>А насколько просто подключить к SQLite или MetaKit, или BerkeleyDB новое хранилище или формат хранения данных?
А к MySQL? Вот кстати хороший пример. Как БД ничего особенного (даже хранимок нет), зато очень удобное расширение SQL и несколько хранилищь на выбор с разными возможностями.
Нужен совет по возможным способам реализации индексов. В БД обычно применяют индексы на основе B+ деревьев. Но, как я понимаю, в B+ дереве должны храниться только уникальные ключи. В ObjESSty зачастую хранятся объекты, у которых ключи не уникальны. Например, если в качестве ключа используется время создания объекта, в виде time_t (в одну секунду может быть создано несколько объектов). Сейчас при работе с такими объектами в памяти строится std::multimap по времени создания. Затем с помощью lower_bound выбираются все объекты, время создания которых больше нужного значения.
Есть необходимость поддержки таких multimap прямо на уровне ObjESSty, чтобы не приходилось вручную строить std::multimap при открытии БД. Если бы можно было использовать обычный map, то я бы просто взял B+ дерево. Но вот по поводу multimap у меня заминка.
Может я не прав, по поводу B+ дерева?
Может существуют еще какие-то механизмы организации индексов во внешней памяти (кроме B+ деревьев)?
Буду признателен за любые предложения и ссылки на соответствующие материалы.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Добрый день!
E>В течении последних двух лет я занимался собственным проектом для сериализации и долговременного хранения сложных C++ объектов: Object Entity Serialization & Stability (ObjESSty). Наконец сейчас он достиг уровня, при котором его не стыдно показать общественности. Что я и делаю при помощи этого сообщения.
E>Страничка проекта: http://eao197.narod.ru/objessty E>Страничка, как и последняя версия проекта находится в состоянии работоспособной beta-версии. Могут наблюдаться различные кривости/ошибки/описки/опечатки, но при наличии интереса и предложений все может быть доведено до ума.
E>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
E>С наилучшими пожеланиями E>Евгений Охотников.
хотелось бы узнать у автора проeкта —
"как на счет" scheema evolution?
И посоветовать, "в качестве обмена опытом", посмотреть на
то, как сериализация делается автоматически на основе
C++ reflection information discussed today at http://rsdn.ru/Forum/Message.aspx?mid=1059505
Здравствуйте, hth, Вы писали:
hth>Здравствуйте, eao197, Вы писали:
E>>Добрый день!
hth>хотелось бы узнать у автора проeкта — hth>"как на счет" scheema evolution?
Спасибо за интересный вопрос.
Прежде всего, давайте я опишу, как я понимаю термин scheme evolution. Под эволюцией схемы данных я понимаю такое изменение схемы данных, которое приводит к изменению сериализованного образа объекта. Под такие изменения попадают:
— изменение иерархии наследования: добавление базового типа, изъятие базового типа, изменение типа наследования (например, обычный базовый тип становится виртуальным базовым типом или наоборот, виртуальный базовый тип становится обычным базовым типом);
— изменение типов данных атрибутов;
— изменение списка атрибутов: добавление атрибутов или удаление атрибутов.
Сразу оговорюсь, что scheme evolution в чистом виде в ObjESSty сейчас нет. В моей предыдущей попытке создать ООСУБД такая поддержка была и я хотел бы со временем добавить ее и в ObjESSty, но здесь сказывается недостаток времени.
Так же, по опыту предыдущей работы, обработку изменения схемы данных очень удобно делать на уровне списка атрибутов: для конкретного типа строится полный список атрибутов, как собственных, так и унаследованных. Таких списков получается два -- один для старого варианта схемы данных, второй -- для нового варианта. Пересечение таких списков как раз и показывает изменение схемы данных.
В ObjESSty отсутствие полноценной поддержки схемы данных не сказывалось критическим образом по следующим причинам:
1. Сериализация с помощью ObjESSty используется для организации обмена сообщения между процессами. Поскольку каждый процесс является самостоятельным проектом, который самостоятельно развивается, то спецификация (схема данных) сообщений не может быть просто так изменена. Т.е. схема данных определяет интерфейс. Который, будучи однажды зафиксированным, уже не может быть изменен. Такая ситуация, насколько я знаю, существует с интерфейсами и в CORBA, и в COM. Поэтому в ObjESSty особо и не требовалось изменять структуру существующих сообщений так, чтобы на другой стороне новая структура была адекватно понята.
2. ObjESSty поддерживает два механизма для расширения существующей схемы данных. Т.е. уже описанные атрибуты и базовые типы не изменяются, но можно добавить новые атрибуты, которые будут проигнорированы на стороне, которая использует старую схему данных. Один механизм -- это механизм "расширяющихся типов", т.е. список их атрибутов может быть просто расширен. Второй механизм -- т.н. subclassing by extension, позволяет передавать в сообщениях объекты полиморфных типов, про которые принимающая сторона просто ничего не знает. В двух словах эти механизмы не опишешь, а подробнее можно прочитать здесь, здесь и здесь.
Так же я думаю, что если говорить о сериализации данных, то здесь изменение схемы данных логичнее поддерживать так, как это делается в ASN1: через extension points. В ObjESSty такую роль играют расширяемые типы. Если же говорить об изменении схемы данных БД, то здесь нужно поддерживать и модификацию списка атрибутов, и изменения типов атрибутов. А так же либо миграцию существующих данных на новую схему, либо преобразование данных на лету.
hth>И посоветовать, "в качестве обмена опытом", посмотреть на hth>то, как сериализация делается автоматически на основе hth>C++ reflection information discussed today at hth>http://rsdn.ru/Forum/Message.aspx?mid=1059505
Здесь я не нашел ничего принципиально нового для себя. Все же я сторонник того, чтобы сериализующий/десериализующий код генерировался автоматически. И автоматически отслеживались изменения схемы данных. В очень большом числе задач это возможно.
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[3]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, hth, Вы писали:
hth>>Здравствуйте, eao197, Вы писали:
E>>>Добрый день!
hth>>хотелось бы узнать у автора проeкта — hth>>"как на счет" scheema evolution?
E>Спасибо за интересный вопрос.
E>Прежде всего, давайте я опишу, как я понимаю термин scheme evolution. Под эволюцией схемы данных я понимаю такое изменение схемы данных, которое приводит к изменению сериализованного образа объекта. Под такие изменения попадают: E>- изменение иерархии наследования: добавление базового типа, изъятие базового типа, изменение типа наследования (например, обычный базовый тип становится виртуальным базовым типом или наоборот, виртуальный базовый тип становится обычным базовым типом); E>- изменение типов данных атрибутов; E>- изменение списка атрибутов: добавление атрибутов или удаление атрибутов.
E>Сразу оговорюсь, что scheme evolution в чистом виде в ObjESSty сейчас нет. В моей предыдущей попытке создать ООСУБД такая поддержка была и я хотел бы со временем добавить ее и в ObjESSty, но здесь сказывается недостаток времени.
E>Так же, по опыту предыдущей работы, обработку изменения схемы данных очень удобно делать на уровне списка атрибутов: для конкретного типа строится полный список атрибутов, как собственных, так и унаследованных. Таких списков получается два -- один для старого варианта схемы данных, второй -- для нового варианта. Пересечение таких списков как раз и показывает изменение схемы данных.
E>В ObjESSty отсутствие полноценной поддержки схемы данных не сказывалось критическим образом по следующим причинам:
E>1. Сериализация с помощью ObjESSty используется для организации обмена сообщения между процессами. Поскольку каждый процесс является самостоятельным проектом, который самостоятельно развивается, то спецификация (схема данных) сообщений не может быть просто так изменена. Т.е. схема данных определяет интерфейс. Который, будучи однажды зафиксированным, уже не может быть изменен. Такая ситуация, насколько я знаю, существует с интерфейсами и в CORBA, и в COM. Поэтому в ObjESSty особо и не требовалось изменять структуру существующих сообщений так, чтобы на другой стороне новая структура была адекватно понята.
E>2. ObjESSty поддерживает два механизма для расширения существующей схемы данных. Т.е. уже описанные атрибуты и базовые типы не изменяются, но можно добавить новые атрибуты, которые будут проигнорированы на стороне, которая использует старую схему данных. Один механизм -- это механизм "расширяющихся типов", т.е. список их атрибутов может быть просто расширен. Второй механизм -- т.н. subclassing by extension, позволяет передавать в сообщениях объекты полиморфных типов, про которые принимающая сторона просто ничего не знает. В двух словах эти механизмы не опишешь, а подробнее можно прочитать здесь, здесь и здесь.
E>Так же я думаю, что если говорить о сериализации данных, то здесь изменение схемы данных логичнее поддерживать так, как это делается в ASN1: через extension points. В ObjESSty такую роль играют расширяемые типы. Если же говорить об изменении схемы данных БД, то здесь нужно поддерживать и модификацию списка атрибутов, и изменения типов атрибутов. А так же либо миграцию существующих данных на новую схему, либо преобразование данных на лету.
hth>>И посоветовать, "в качестве обмена опытом", посмотреть на hth>>то, как сериализация делается автоматически на основе hth>>C++ reflection information discussed today at hth>>http://rsdn.ru/Forum/Message.aspx?mid=1059505
E>Я так же принимаю участие в этой ветке
hth>>в ROOTe http://root.cern.ch/root/HowtoWrite.html
E>Здесь я не нашел ничего принципиально нового для себя. Все же я сторонник того, чтобы сериализующий/десериализующий код генерировался автоматически. И автоматически отслеживались изменения схемы данных. В очень большом числе задач это возможно.
я хотел бы отметить, что в ROOTe serialisation делается автоматически,
т.е. Streamer method генерится на основе C++ metadata information.
C++ metadata information также спасается в файл вместе с обьектом.
Это позволяет реализовать поддержку scheema evolution —
даже если схема класса изменилась, все равно возможно прочитать
файлы обьектами имеющими "старую" схему.
Re[4]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, hth, Вы писали:
E>>Здесь я не нашел ничего принципиально нового для себя. Все же я сторонник того, чтобы сериализующий/десериализующий код генерировался автоматически. И автоматически отслеживались изменения схемы данных. В очень большом числе задач это возможно.
hth>я хотел бы отметить, что в ROOTe serialisation делается автоматически, hth>т.е. Streamer method генерится на основе C++ metadata information. hth>C++ metadata information также спасается в файл вместе с обьектом. hth>Это позволяет реализовать поддержку scheema evolution - hth>даже если схема класса изменилась, все равно возможно прочитать hth>файлы обьектами имеющими "старую" схему.
А ROOT работает еще на чем-нибудь, кроме CInt?
А ROOT позволяет сериализовать только часть атрибутов класса?
А сериализовать только те атрибуты, значение которых отличается от значения по-умолчанию?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Добрый день.
E>Нужен совет по возможным способам реализации индексов. В БД обычно применяют индексы на основе B+ деревьев. Но, как я понимаю, в B+ дереве должны храниться только уникальные ключи. В ObjESSty зачастую хранятся объекты, у которых ключи не уникальны. Например, если в качестве ключа используется время создания объекта, в виде time_t (в одну секунду может быть создано несколько объектов). Сейчас при работе с такими объектами в памяти строится std::multimap по времени создания. Затем с помощью lower_bound выбираются все объекты, время создания которых больше нужного значения.
E>Есть необходимость поддержки таких multimap прямо на уровне ObjESSty, чтобы не приходилось вручную строить std::multimap при открытии БД. Если бы можно было использовать обычный map, то я бы просто взял B+ дерево. Но вот по поводу multimap у меня заминка.
Пока удалось придумать два решения:
1. Использовать обычное B+ дерево, но в листовых страницах хранить элементы такого псевдотипа:
struct leaf_node_item_t
{
// Значение ключа.
key_t m_key;
// Ссылка на элемент с таким значением ключа.
// Эта ссылка является пустой, если таких элементов несколько.
item_t * m_item;
// Общее количество элементов с таким значением ключа.unsigned int m_items_count;
// Первая страница списка указателей на элементы с одинаковым значением ключа.
ref_list_page_t< item_t * > * m_first_list_page;
// Последняя страница списка указателей на элементы с одинаковым значением ключа.
ref_list_page_t< item_t * > * m_last_list_page;
};
Т.е. идея в том, что когда элемент с указанным значением ключа один, то на него ссылается leaf_node_item_t::m_item. Если же элементов с таким значением ключа несколько, то ссылки на них находятся в односвязном списке страниц ref_list_page_t:
В таком варианте для извлечения всех элементов с одинаковым значением ключа нужно просто найти этот ключ в B+ дереве, а затем пройти по списку страниц с ссылками.
2. Использовать обычное B+ дерево, но на уровне индекса подменять тип ключа. Например, на вот такой тип:
template< class Key >
struct index_key_t
{
// Оригинальный ключ.
Key m_key;
// А вот в этом поле весь фокус и состоит.
// Это автоинкрементное поле, которое автоматически выставляется
// самим индексом при обработке нового элемента.unsigned int m_uid;
// Нужен специальный оператор сравнения.
// Приоритет при сравнении отдается оригинальному ключу, но если
// ключи совпадают, то сравниваются m_uid-ы.bool
operator<( const index_key_t< Key > & o ) const
{
if( m_key < o.m_key )
return true;
else if( o.m_key < m_key )
return false;
else
return ( m_uid < o.m_uid );
}
};
Тогда, операцию lower_bound(k) можно выразить через lower_bound(index_key_t(k, 0)). А операцию upper_bound(k) -- через upper_bound(index_key_t(k, MAX_UINT)).
А все элементы, которые имеют одинаковый ключ берутся из диапазона [lower_bound(index_key_t(k,0)), upper_bound(index_key_t(k,MAX_UINT))).
Мне больше нравится второе решение.
Может я где-то ошибся?
... << RSDN@Home 1.1.4 beta 3 rev. 185>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re: Реализация паттерна Async Completion Token
От:
Аноним
Дата:
20.05.05 16:21
Оценка:
Здравствуйте, eao197, Вы писали:
E>Вот здесь профессор Дуглас Шмидт описывает паттерн Asynchronous Completion Token. Суть патерна в том, что клиент, выполняя запрос к серверу, передает на сервер специальный объект (Asynchronous Completion Token -- ACT). Сервер возвращает этот объект клиенту в ответе. Благодоря ACT клиент понимает, на какой именно из его запросов ответил сервер. Особенно это удобно при асинхронном взаимодействии клиента и сервера, когда по одному каналу связи идут потоки запросов и ответов. Ключевым моментом в паттерне Asynchronous Completion Token является то, что объект ACT, в общем случае, является непрозрачным для сервера (т.е. сервер совершенно не знает, что именно находится в ACT).
E>Забавно, что я наткнулся на описание этого паттерна вскоре после того, как реализовал с помощью ObjESSty подобный механизм. В моем случае требовалось организовать цепочку процессов (которые, возможно, работают на разных узлах сети) и которые в асинхронном режиме обслуживают запросы (транзакции) клиента, подключенного к одному из концов этой цепочки (эта цепочка выглядит для клиента как один сервер). Причем каждая транзакция состоит из нескольких сообщений. Например, одна из транзакций состоит из трех сообщений: E>1. send -- инициируется клиентом и содержит описание необходимых действий. Клиент повторяет его до тех пор, пока не получит send_result. E>2. send_result -- отсылается клиенту в ответ на send. Повторяется до тех пор, пока клиент не пришлет send_finish. Сделано это для того, чтобы в случае потери единичного send_result клиент не инициировал запрос send еще раз. E>3. send_finish -- отсылается клиентом в ответ на send_result. Это сообщение говорит серверу, что клиент полностью завершил транзакцию и что сервер может удалить у себя информацию о данной транзакции. E>Такая трехфазная схема позволяет организовать асинхронное взаимодействие между клиентом и сервером через один канал. Клиент может инициировать несколько send не дожидаясь ответа на предудущие send. Однако, эта схема требует, чтобы каждая транзакция имела уникальный идентификатор.
По-моему это называется "тройное рукопожатие" подобные вещи были уже реализованы еще в прошлом веке например в TCP-IP.
Здравствуйте, <Аноним>, Вы писали:
А>Здравствуйте, eao197, Вы писали:
А>>>По-моему это называется "тройное рукопожатие" подобные вещи были уже реализованы еще в прошлом веке например в TCP-IP.
E>>И что? TCP/IP -- это транспортный протокол, а не прикладной. Я же говорил о прикладном протоколе.
А>Я просто к тому, что такая схема взаимных подтверждений используется во многих местах. Не рассматривайте как наезд
Я и не расматриваю, просто речь шла не о том, что я придумал трехфазный протокол. Главная цель была -- показать реализацию ACT через средства ObjESSty. А трехфазный протокол -- это пример того, где подобные ACT удобно применять.
... << RSDN@Home 1.1.4 beta 6a rev. 436>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
E>>Но, как я понимаю, в B+ дереве должны храниться только уникальные ключи.
Откуда такие сведения? E>Может я где-то ошибся?
Почти нет. Если проблема еще не решена, то могу рассказать.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, eao197, Вы писали:
E>>И если есть возможность рассказать, то разскажи. Моя благодарность не будет знать границ в рамках доступных мне оценок GZ>Хе-хе. Это я люблю.
GZ>Вобщем система такая. Три главных свойства Б+ индекса за которые его любят базоведы: GZ>1. Логарифмический поиск, добавление и удаление GZ>2. Доступ к листьям как к сортированному списку GZ>3. Хранение в сегментах.
Вот здесь еще один повод для сомнений у меня есть. B+ деревья хорошо подходят для данных фиксированной длины (или имеющих разумные органичения по размеру). Если же ключи могут быть разной длины (строки, например), то нужно, чтобы ключ помещался на страницу. А вот если нет?
Я просто хотел бы в ObjESSty добавить индексы и использовать для задачи, в которой как раз ключами будут строки разной длины (она описана здесь: Реализация паттерна Async Completion Token
).
GZ>Мне как-то приходилось делать Б+ дерево. Но одной из задач мне нужно было находить количество элементов в заданном диапазоне. Поэтому ключи были неуникальными. В результате, я мог не доходя до листьев(а это дисковые операции) оценивать количество объектов в заданном диапазоне.
А как ты это делал? Что-то сразу не вьезжаю.
Вообще-то я сейчас курю по поводу libgist (GiST). Ее в PostgreSQL используют. Смущает то, что в GiST применяются непереносимые (платформно-зависимые) файлы для хранения индексов. И не понятно, как мне к своей транзакционности изменение этих индексных файлов пристегнуть.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Вот здесь еще один повод для сомнений у меня есть. B+ деревья хорошо подходят для данных фиксированной длины (или имеющих разумные органичения по размеру). Если же ключи могут быть разной длины (строки, например), то нужно, чтобы ключ помещался на страницу. А вот если нет?
А если нет, но это совсем...
Я просто хотел бы в ObjESSty добавить индексы и использовать для задачи, в которой как раз ключами будут строки разной длины (она описана здесь: Реализация паттерна Async Completion Token
).
Немного не понял зачем тебе там Б+. Ты хочешь получать по UID другой UID?
GZ>>Мне как-то приходилось делать Б+ дерево. Но одной из задач мне нужно было находить количество элементов в заданном диапазоне. Поэтому ключи были неуникальными. В результате, я мог не доходя до листьев(а это дисковые операции) оценивать количество объектов в заданном диапазоне.
E>А как ты это делал? Что-то сразу не вьезжаю.
Немного соврал. До листьев я добирался. Давно делал, только сейчас понял. Хотя в принципе можно было так и не делать. Абсолютная точность была не нужна (нужно было процентное отношение), и можно было просчитывать по средней балансировке. Балансировка была по золотому сечению, поэтому можно было предствить средний коэффициент заполнености, и по нему подсчитывать достаточно близкие значения к реальным.
E> E>Вообще-то я сейчас курю по поводу libgist (GiST). Ее в PostgreSQL используют. Смущает то, что в GiST применяются непереносимые (платформно-зависимые) файлы для хранения индексов. И не понятно, как мне к своей транзакционности изменение этих индексных файлов пристегнуть.
Это мои любимые велосипеды. Для меня такое сделать самый цимес.
Здравствуйте, GlebZ, Вы писали:
GZ>Здравствуйте, eao197, Вы писали:
E>>Вот здесь еще один повод для сомнений у меня есть. B+ деревья хорошо подходят для данных фиксированной длины (или имеющих разумные органичения по размеру). Если же ключи могут быть разной длины (строки, например), то нужно, чтобы ключ помещался на страницу. А вот если нет? GZ>А если нет, но это совсем...
Вот и я о том же сожалею. И думаю, а не использовать ли мне что-нибудь другое. Например AVL-деревья. Ведь все равно у меня объекты нарезаются на маленькие блоки и размазываются по хранилищу. Точно так же будут и элементы AVL-дерева по хранилищу размазываться, вне зависимости от длины ключа.
E>>Я просто хотел бы в ObjESSty добавить индексы и использовать для задачи, в которой как раз ключами будут строки разной длины (она описана здесь: Реализация паттерна Async Completion Token
).
GZ>Немного не понял зачем тебе там Б+. Ты хочешь получать по UID другой UID?
Не совсем. Мне нужно будет сохранить объект, описателем которого будет является сериализованный двоичный образ его идентификатора транзакции (поскольку я не знаю, что в этом идентификаторе содержится, а вот образ однозначно уникален). И затем по идентификатору транзакции поднимать этот объект.
В принципе, в качестве ключа можно будет использовать хеш двоичного образа. Но на хешах нельзя строить упорядоченные множества и коллизии как-то разрешать нужно. Хотя нужно ли в этом случае упорядочение -- еще большой вопрос.
Я просто еще не выбрал окончательного решения и обдумываю разные варианты.
GZ>>>Мне как-то приходилось делать Б+ дерево. Но одной из задач мне нужно было находить количество элементов в заданном диапазоне. Поэтому ключи были неуникальными. В результате, я мог не доходя до листьев(а это дисковые операции) оценивать количество объектов в заданном диапазоне.
E>>А как ты это делал? Что-то сразу не вьезжаю. GZ>Немного соврал. До листьев я добирался. Давно делал, только сейчас понял. Хотя в принципе можно было так и не делать. Абсолютная точность была не нужна (нужно было процентное отношение), и можно было просчитывать по средней балансировке. Балансировка была по золотому сечению, поэтому можно было предствить средний коэффициент заполнености, и по нему подсчитывать достаточно близкие значения к реальным.
Ба! Прочитал с открытым ртом
Если серьезно, то я не большой спец в алгоритмах.
E>> E>>Вообще-то я сейчас курю по поводу libgist (GiST). Ее в PostgreSQL используют. Смущает то, что в GiST применяются непереносимые (платформно-зависимые) файлы для хранения индексов. И не понятно, как мне к своей транзакционности изменение этих индексных файлов пристегнуть. GZ>Это мои любимые велосипеды. Для меня такое сделать самый цимес.
Любимые велосипеды -- это libgist что-ли?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
GZ>>Немного не понял зачем тебе там Б+. Ты хочешь получать по UID другой UID?
E>Не совсем. Мне нужно будет сохранить объект, описателем которого будет является сериализованный двоичный образ его идентификатора транзакции (поскольку я не знаю, что в этом идентификаторе содержится, а вот образ однозначно уникален). И затем по идентификатору транзакции поднимать этот объект.
E>В принципе, в качестве ключа можно будет использовать хеш двоичного образа. Но на хешах нельзя строить упорядоченные множества и коллизии как-то разрешать нужно. Хотя нужно ли в этом случае упорядочение -- еще большой вопрос. E>Я просто еще не выбрал окончательного решения и обдумываю разные варианты.
По моему тут как раз и есть лучшее решения именно хеширование. Притом замесить можно даже с помощью простейшей функции типа a|=((*i)<<1). Распределение будет достаточно приличное. Вопрос только в размерах таблицы. И доступ к таблице достаточно оптимальный. В сети решений для хешей до фига.
Хотя вопрос о том, не является ли это слишком избыточным решением остается. Просто, насколько большое кол-во данных тут присутствует. Может можно обойтись stl
E>Ба! Прочитал с открытым ртом E>Если серьезно, то я не большой спец в алгоритмах.
Удивлен. Хорошо знать ООБД и не знать алгоритмы как они работают.
E>>> E>>>Вообще-то я сейчас курю по поводу libgist (GiST). Ее в PostgreSQL используют. Смущает то, что в GiST применяются непереносимые (платформно-зависимые) файлы для хранения индексов. И не понятно, как мне к своей транзакционности изменение этих индексных файлов пристегнуть. GZ>>Это мои любимые велосипеды. Для меня такое сделать самый цимес.
E>Любимые велосипеды -- это libgist что-ли?
Нет, алгоритмы. Иногда очень чудные вещи получаются. Только в коммерции за это не платят. Только когда работал на государство.
Здравствуйте, GlebZ, Вы писали:
E>>Я просто еще не выбрал окончательного решения и обдумываю разные варианты. GZ>По моему тут как раз и есть лучшее решения именно хеширование. Притом замесить можно даже с помощью простейшей функции типа a|=((*i)<<1). Распределение будет достаточно приличное. Вопрос только в размерах таблицы. И доступ к таблице достаточно оптимальный. В сети решений для хешей до фига.
Да, для данного конкретного случая я тоже так думаю. Но вот если добавлять в ObjESSty функциональность по поддержке индексов, то хотелось бы сразу сделать максимально универсальное решение.
Объемы данных, я думаю будут порядка 1M-3M значений и хранить их нужно будет в течении двух-трех дней, после чего переодически удалять устаревшие объекты (для чего еще нужен будет индекс по timestamp-у).
E>>Ба! Прочитал с открытым ртом E>>Если серьезно, то я не большой спец в алгоритмах. GZ>Удивлен. Хорошо знать ООБД и не знать алгоритмы как они работают.
Открою секрет -- я знаю мало, просто поверхам но из разных областей. Именно это, имхо, и позволило сделать ObjESSty, т.к. там есть совершенно разные задачи -- начиная от парсинга DDL и заканчавая поддержкой восстанавливаемости. Если бы я был спецом в алгоритмах, то я бы, вероятно, занимался оптимизацией работы с кешем, но до релиза бы так и не добрался
E>>>> E>>>>Вообще-то я сейчас курю по поводу libgist (GiST). Ее в PostgreSQL используют. Смущает то, что в GiST применяются непереносимые (платформно-зависимые) файлы для хранения индексов. И не понятно, как мне к своей транзакционности изменение этих индексных файлов пристегнуть. GZ>>>Это мои любимые велосипеды. Для меня такое сделать самый цимес.
E>>Любимые велосипеды -- это libgist что-ли? GZ>Нет, алгоритмы. Иногда очень чудные вещи получаются. Только в коммерции за это не платят. Только когда работал на государство.
Ну прям как я
Только я бы хотел дойти и до того, чтобы и в коммерции мне за изобретение велосипедов платили... Вот тут: Re[7]: Методология дворника.
Гигантская работа вами проделана. Почти написана объектная СУБД.
Одного я не пойму. Зачем? Чем плохи существующие ООСУБД? Почему пришлось писать свою?
Ваш продукт мне кажется очень похожим на Versant FastObjects t7. Кстати, рекомендую посмотреть на то, как там реализованы B+ tree индексы.
Здравствуйте, Alexey Rovdo, Вы писали:
AR>Гигантская работа вами проделана. Почти написана объектная СУБД.
Я бы сказал, на четверть написанная объектная СУБД. Нет индексов, многопользовательского режима, клиент-серверной работы.
А языка запросов так и вообще не будет (вероятно).
AR>Одного я не пойму. Зачем? Чем плохи существующие ООСУБД? Почему пришлось писать свою?
Хороший вопрос. Сам на него ответа не знаю.
Началось все еще на пятом курсе университета. Я тогда уже работал в КБ системного программирования и мы там хотели замутить супер-пупер объектно-ориентированную SCADA-систему. А поскольку SCADA предполагает интерфейс пользователя в виде мнемосхем + сохранение где-то описанных пользователем источников данных и другой мути, то решили попробовать сохранить все это (т.е. описание объектов и их графическое представление и расположение на мнемосхемах) в объектной БД. А в 1994-1995 годах ситуация с ООСУБД была достаточно интересная -- все только начиналось, казалось, что можно сделать все своими руками Плюс к тому, с Интернетом у нас в Гомеле тогда были большие проблемы и информацию о ООСУБД приходилось добывать по крупицам (спасибо журналу СУБД (который сейчас только в рамках Открытых Систем существует)), не говоря уж про сами системы. А поскольку был молодой, да ранний, то и склепал со страху почти готовую СУБД, на которой мы свою SCADA все же сделали. И даже в одном реальном проекте применили. А затем все это направление по экономическим причинам сдохло, а вскоре и я из КБ ушел.
Кроме того, первую свою СУБД Dss я делал еще и в качестве своей кандидатской дисертации. Даже сам диссер написал, только приткнуть его не куда было. Так уж сложилась моя учеба в аспирантуре -- всяко ведь бывает. Хотя работа была сделана намного бОльшая, чем сейчас. Один набор различных утилит чего стоил!
Но оглядываясь назад, думаю, что главным двигателем было желание доказать всему миру, что я могу делать подобные вещи. Типа: сделал, показал, получил приглашение в IBM
Так уж получилось, что после увольнения из КБ я не мог заниматься Dss дальше и эта разработка сама по себе зачахла. Кроме того, в техническом плане она была, как бы это сказать, написана дилетантом. Например, я использовал TCP/IP для взаимодействия между клиентом и сервером, но толком TCP/IP канал не контролировал. Но и таких плюх, думаю, там много было
А затем получил приглашение в компанию, где уже работал мой коллега по разработке SCADA. Вот мы и решили реинкарнировать нашу систему. Получилось. Но к ней захотелось еще приделать восстанавливаемость после сбоев. Для чего нужно было объектные данные переодически на диск записывать. А тогда мы как раз делали проектик, в котором по условиям заказчика, на нашей стороне не должно было быть никакой РСУБД, хотя на собственные велосипеды ограничений не было. Вот меня, как рецедивиста, на старое и потянуло
Собственно тогда (имхо, как и сейчас) выбор был между покупкой коммерческой ООСУБД, либо использованием Goods Кости Книжника, либо в создании своего хранилища. Будучи паталогическим изобретателем велосипедов, я выбрал самый трудный путь По которому ковыляю по мере сил
Я отказался от развития предыдущего проекта Dss из-за того, что Dss была жестко ориентированна на объекты фиксированного размера. А нам нужно было именно эффективно обрабатывать объекты разных размеров. Еще одним минусом Dss было то, что там были явные операции Load и Free (я вообще больше интересуюсь явной стабильностью, чем неявной, как в большинстве ООСУБД). Да и техническая часть Dss так же меня уже не устраивала.
Вот так, наверное.
Если в кратце, то основная причина -- шило в одном месте. Плюс стоимость коммерческих аналогов. Плюс, хотя это не очень этично, пока мой велосипед используется, я не очень волнуюсь о своем рабочем месте
AR>Ваш продукт мне кажется очень похожим на Versant FastObjects t7. Кстати, рекомендую посмотреть на то, как там реализованы B+ tree индексы.
С интересом посмотрю, а где можно исходники глянуть?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
E>Началось все еще на пятом курсе университета...
Ну что тут скажешь? Внушает!
И хотя лично я являюсь ярым противником изобретения велосипедов, такой труд критиковть не решусь. Впрочем мне все равно трудно представить будущее ващей СУБД именно в связи с наличием более совершенных продуктов (разве только военные и ФАПСИшные нужды, аналогично Линтеру). А вот ваш SObjectizer мне понравился. Понравился именно своей новизной и относительной уникальностью. Возможно у него и есть сильные конкуренты, но это явно не велосипед. Впрочем, я затрудняюсь судить насколько сильна и перспективна данная технология в техническом плане. Во всяком случае любопытно, а там, глядишь, окажется, что и полезно ...
Здравствуйте, Alexey Rovdo, Вы писали:
AR>Здравствуйте, eao197, Вы писали:
E>>Началось все еще на пятом курсе университета...
AR>Ну что тут скажешь? Внушает! AR>И хотя лично я являюсь ярым противником изобретения велосипедов, такой труд критиковть не решусь. Впрочем мне все равно трудно представить будущее ващей СУБД именно в связи с наличием более совершенных продуктов (разве только военные и ФАПСИшные нужды, аналогично Линтеру).
Ну я бы хотел сделать объектно-ориентированный аналог BerkeleyDB (это в идеале, конечно). Ну и в дополнение там будет платформенно-независимый формат самой БД, чего нет в BerkeleyDB.
К тому же, главное -- это иметь готовый продукт, а уже его успешное приложение -- это сдело случая.
AR> А вот ваш SObjectizer мне понравился. Понравился именно своей новизной и относительной уникальностью. Возможно у него и есть сильные конкуренты, но это явно не велосипед. Впрочем, я затрудняюсь судить насколько сильна и перспективна данная технология в техническом плане. Во всяком случае любопытно, а там, глядишь, окажется, что и полезно ...
Спасибо за добрые слова.
У нас на SObjectizer-е все C++ продукты сделаны. Хотя из состояния велосипеда, я считаю, мы еще не вышли.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[2]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, aka50, Вы писали:
A>Здравствуйте, eao197, Вы писали:
E>>Буду признателен за любые конструктивные предложения и замечания, в том числе и за разгромную (но объективную) критику.
A>Небольшое замечание: в рахиве все файлы с x-битом установленным. ИМХО не очень удобно find напускать . Можно с чегонить A>не того бит снять.
Здравствуйте, eao197, Вы писали:
E>>>Спасибо! Исправил: http://eao197.narod.ru/objessty/oess.1.4.0-b2.tar.bz2 E>>>Впредь постараюсь дистрибутивы под Linux-ом собирать, а то потрированные под Win утилиты вот такие фокусы откалывают.
A>>хмм... может архив не закачал? (без прокси сливал, все равно тоже самое)
E>Закачал, а в форум не ту ссылку дал: http://eao197.narod.ru/objessty/oess.1.4.0-b2-20050704.tar.bz2
Исправилось.
E>CMake когда-то смотрел, мне не понравилось. E>Для scons-а мне бы пришлось доделывать поддержку платформы NonStop да и выбранную структуру проекта, вероятно, пришлось бы менять. А программировать на python-е мне не хотелось. Ruby больше понравился.
Понятно. Если соберусь использовать посмотрю, может можно будет поверх еще CMake прикрутить. Удобнее в проекты
будет включать. К тому же у меня уже ACE+TAO есть под CMake. В общем, если че, кину патчик. Чтоб было
A>>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
E>Для того, чтобы скомпилировать в Debug нужно было просто указать в командной строке --mxx-cpp-debug. Аналогично для Release: --mxx-cpp-release.
Хмм... но тогда былоб неполохо build.rb --help чтоб работал.
Re[6]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, aka50, Вы писали:
E>>CMake когда-то смотрел, мне не понравилось. E>>Для scons-а мне бы пришлось доделывать поддержку платформы NonStop да и выбранную структуру проекта, вероятно, пришлось бы менять. А программировать на python-е мне не хотелось. Ruby больше понравился. A>Понятно. Если соберусь использовать посмотрю, может можно будет поверх еще CMake прикрутить. Удобнее в проекты A>будет включать. К тому же у меня уже ACE+TAO есть под CMake. В общем, если че, кину патчик. Чтоб было
Ok.
А почему ты MPC из ACE не используешь?
A>>>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
E>>Для того, чтобы скомпилировать в Debug нужно было просто указать в командной строке --mxx-cpp-debug. Аналогично для Release: --mxx-cpp-release. A>Хмм... но тогда былоб неполохо build.rb --help чтоб работал.
Это в документации было написано
А вот в "build.rb --help" такую штуку сделать не просто. Ведь mxx_ru как бы не только на C++ расчитан. Код по обработке C++ проектов в mxx_ru можно рассматривать как plug-in. А каждый plug-in ищет в командной строке те аргументы, которые понимает, это не сложно. А вот заставить plug-in-ы выдавать help по ключу... Чтож, можно и над этим покурить. Спасибо за идею, правда не знаю, когда до этого руки дойдут.
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Re[7]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, aka50, Вы писали:
A>>Понятно. Если соберусь использовать посмотрю, может можно будет поверх еще CMake прикрутить. Удобнее в проекты A>>будет включать. К тому же у меня уже ACE+TAO есть под CMake. В общем, если че, кину патчик. Чтоб было
E>Ok. E>А почему ты MPC из ACE не используешь?
Причина одна:
1. Perl.
A>>>>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path.
E>>>Для того, чтобы скомпилировать в Debug нужно было просто указать в командной строке --mxx-cpp-debug. Аналогично для Release: --mxx-cpp-release. A>>Хмм... но тогда былоб неполохо build.rb --help чтоб работал.
E>Это в документации было написано
Не в документации, а в target.rb еще и в cp1251
Re[9]: [ANN] ObjESSty - еще один проект сериализации
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, aka50, Вы писали:
E>>>А почему ты MPC из ACE не используешь? A>>Причина одна: A>>1. Perl.
E>Понятно. Почти как моя причина не использовать SCons
E>Андрей, это ты со зла E>http://eao197.narod.ru/mxx_ru/sm_html/mxx_ru_smch5.html#x11-370005.1.5
честно на сайте не глядел. Искал в архиве.
Здравствуйте, aka50, Вы писали:
A>При сборке ругалось вот так:
A>
A>oess_1/defs/log/h/err.hpp:40:1: warning: "LOG_ERR" redefined
A>
FIXED
A>2. Распаковывал mxx_ru в каталог с проектом, все распаковалось туда, где стоял (был в <project_root>/dev). A> При этом в build.rb ссылки на mxx_ru/cpp и т.д. Неплохо былоб чтобы их архива все распаковывалось сразу в mxx_ru .
FIXED
A>3. Поправил скрипт (ибо не везде /usr/local/bin/ruby, в дебиане например просто в /usr/bin)
FIXED. Теперь нужно запускать просто ruby build.rb
A>4. Увидел, что править настройки проекта надобно в самом build.rb (например Debug/не Debug) при чем вместе с output path. A> Неплохо было бы сделать что-то вроде .settings или чего-то похожего чтобы не править скрипт. Сценарий: