Как стать автором
Обновить
12
0
Карелин Павел @hkarel

Программист

Отправить сообщение

Мы приходим к тому, о чем как минимум уже пару раз говорилось в этом обсуждении: нужны дополнительные телодвижения для реализации этого функционала. А индивидуальная поддержка СУБД может стать отдельным приключением. Повторюсь: использование UUID-ов позволяет минимизировать эти издержки.

1) Данные могут быть связанными, так что ID-поля нужны;

2) И почему веб-сервис, мы, например, этой технологией почти не пользуемся, в основном TCP.

А если чтение из потока?

М-м-м, а если заинкрементить 100500 значений, а транзакция откатится, мы потеряем этот диапазон?
Так же полагаю, этот совет будет работать когда количество вставляемых данных изначально известно.

Действительно, в FB есть sequence, они еще странно называются: "генераторы". В принципе, все бы работало как Вы и описываете, если бы не одно "но". На 2003 год помимо FB мы уже поддерживали MSSQL и Oracle. Из соображений унификации было принято решение перейти на ODBC драйверы. А их функциональность по сравнению с родными драйверами достаточно ограниченна (обратная сторона универсальности). В дельфи-компонентах это тоже проявляется. Отсюда и конструкции вида select max(id). Я посчитал эту деталь недостаточно существенной, поэтому не упомянул ее в первой части статьи. Видимо зря. Исходил из тех соображений, что статься не о преимуществах или недостатках ODBC или дельфи-компонентов, а о Qt-драйверах способных работать с uuid-ами в нативном для базы формате.
Про канделябры: в 2003 году мы на самом деле были "студентами", много не знали, с другой стороны: а есть профессионалы, которые миновали эту стадию?! Решение о переходе на UUID-ы мы принимали коллегиально, командой, а не волей одного человека. Конечно, команды тоже могут ошибаться, впрочем, как и большинство ;)
P.S. По прошествии времени думаю: "Как классно, что мы тогда сделали такой выбор!". Пользуюсь им до сих пор!

В этом случае придется вести реестр заказчиков для того чтобы разные заказчики случайно не получили один и тот же начальный идентификатор. С UUID-ом мне об этом думать не надо.

В статье "Первичный ключ – GUID или автоинкремент?" упоминается "последовательный" GUID, возможно для innodb это будет решением.

что уже есть готовое решение

"Готовое решение" подходит для QGit, не факт, что оно подойдет для ваших задач. Но как базовое решение можно Sonnet или что-то подобное использовать.


Например, если человек по русски пишет хелоу – и мы определяли из этого английский язык с какой-то долей вероятности…

У меня это определится как 100%-но русское слово, так как есть только русскоязычные триграммы. Если бы в слове была последовательность из трех латинских символов, то появилась бы вероятность английского или немецкого, или другого языков.
Возможно, если создать отдельный словарь транслитерисованных триграмм, тогда вероятность появится. Думаю это должно сработать.
Или как вариант рассмотреть нейросетевые алгоритмы. Наш директор иногда берется за такие задачи, но это уже коммерческая история.


Как составляют триграммы?

"Война и мир" без французских слов.


… на каком основании им присуждается "вес".

Частота встречаемости в тексте


Не стану здесь описывать механизм принятия решения в Sonnet, или в моем механизме. Иначе получится отдельный (уже тематический) абзац к статье :)
Если есть потребность узнать как это работает — можем сконнектиться и обсудить.

В конфиге языки и так указываются, точнее словари. А вот языковые триграммы "зашиты" в код в виде ресурсов, это сделано для быстрой инициализации (прием взят из Sonnet). Сейчас есть RU, EN, но можно и расширить.
Про пример с немецкой опечаткой: методика определения языка по триграммам как раз устойчива к разовым опечаткам, позволяет корректно детектировать, например английский, даже если в слове случайно появился символ с умляутом из немецкого. Исключения могут составить слова из трех букв (размер одной триграммы), но в трех буквах вроде редко ошибаются.
Теперь про методику детектирования языков по словарям: допустим мы проверили слово по всем словарям и не нашли соответствия. Подсветили слово как ошибочное. Но на самом деле это не ошибка, а исключение. Нам нужно добавить слово в список исключений. В какой словарь будем добавлять? В этом случае в контекстном меню нужно будет сформировать субменю для каждого доступного словаря, и пусть пользователь сам принимает решение куда добавлять. Рабочий вариант?! Да, вполне рабочий. Но я решил сделать детекцию через триграммы, чтобы в контекстном меню сразу "направлять" пользователя в нужный словарь

Да ничем не плох. Если он Вам подходит — берёте и работаете…
Один мой коллега использует "ГитКракен", а мне говорит: "Как ты этой штукой пользуешься?! Айда на 'мой' Кракен...". И ничего, работаем, делаем совместные проекты :)

Думаю, что разочарую Вас. В "моем" QGit концептуально все так же, как и в "классическом".
Касательно работы с субмодулями, то там все примитивно: заходим в директорию субмодуля, запускаем QGit, работаем с этим субмодулем. Поднимаемся на директорию выше — уже работаем с основным проектом.
Я запускаю QGit из Krusader-а по F1, по 'Q' — выход, и "побежал" в другую директорию. QGit с открытым деревом проекта у меня весь день не "висит".

Посмотрел по диагонали код GitQlient. Действительно, можно найти кодовые элементы от QGit. По тому что я увидел на форк это не тянет, может на прообраз. Это скорее похоже на новое, и как мне показалось, добротно проработанное решение, но никак не на форк.
По поводу нового названия для моего форка: несморя на доработки — основной объем кодовой базы все еще остается оригинальным. Да и по духу, и по названию — QGit мне нравится :) Поэтому я наверное пока воздержусь от переименований.

Это был один из рабочих вариантов. Но потом решил, что "третий уровень Sonnet" — это не мой путь. Поэтому постарался сделать добротное, в моем понимании, решение.


Вставить проверку синтаксиса в QT на базе hunspell — это около 100 строчек кода

Так я и не говорил, что hunspell — это сложно, примерно 100 строк и получилось ;) Ну может еще 100 на загрузку/сохранение пользовательских словарей.
Основная заморочка была с детектом языка.

Частично ответ на этот вопрос уже есть в статье. Попробую ответить более развернуто. Первоначально я отправлял свой доработки мантейнеру (Cristian Tibirna). Самые первые предложения отправлялись в виде diff-ов по почте (тогда QGit еще не было на GitHub). Они рассматривались, обсуждались, и принимались. Если Вы когда нибудь занимались такой деятельностью, то должны знать, что процесс этот не быстрый. Например, сейчас я отправляю мелкие фиксы в Krusader, процесс их принятия занимает 4-5 недель. С QGit по срокам было примерно так же. Нужно понимать, что Кристиан не автор проекта QGit, то есть код проекта для него в некоторой степени чужероден. Поэтому рассмотрение сторонних правок требует больше времени, чем если бы это делал автор. И не забывайте, что мантейнеры в таких проектах это добровольцы, они выполняют работу по поддержке в свое личное время.
Как уже было написано, мы не сошлись с Кристаном по вопросу внедрения C++11. Что мне нужно было делать в этой ситуации? Ждать когда мантейнер примет решение, что уже пора внедрять?! Или смириться и писать код на C++98/2003?
Я использую QGit в своей работе, и мне хотелось иметь удобный, эффективный (в моем понимании) инструмент, и у меня была возможность сделать QGit таковым. Поэтому я перестал тратить время на создание PR, обсуждения, ожидания что их примут, а просто пошел вперед. Я делал инструментария для себя, при этом долгое время старался сохранить совместимость с основным проектом. Со временем это становилось делать все труднее, потому что помимо разных полезностей в проект попадает и рефакторинг.
Публично решил рассказать о своей работе только после того, как сделал механизм проверки орфографии, посчитал, что это может быть полезно не только мне. Но перед тем как это сделать — я написал информ-письмо Кристиану, кратко рассказал про проверку орфографии, о том что совместимость с основным проектом потеряна, и о том, что в перспективе собираюсь рассказать о своей работе публично. Реакции от мантейнера не последовало. Через две недели я начал писать данную заметку.
P.S.
Выложить свое решение — это здорово, но недостаточно. Если вы не занимаетесь сборкой проектов каждый день — процесс может оказаться нетривиальным. Именно поэтому я подготовил DEB-пакеты, что бы можно было просто попробовать мое решение, а не тратить время на разбирательство с системой сборки.

Холодный старт


28.03.2021 20:34:28 INFO    LWP19694 [qgit.cpp:102] QGit is running (version: 3.0.1; gitrev: b9ba2e3)
28.03.2021 20:34:29 ERROR   LWP19694 [cache.cpp:105] Unable to load file-cache
28.03.2021 20:34:41 DEBUG   LWP19694 [dataloader.cpp:126] Exited while parsing
...
Первые два экрана построены, далее нажата 'Q'
28.03.2021 20:35:51 INFO    LWP19694 [cache.cpp:45] Saving cache. Please wait...
28.03.2021 20:35:51 INFO    LWP19694 [cache.cpp:80] Compressing data...
28.03.2021 20:35:53 INFO    LWP19694 [cache.cpp:95] Cache saved
28.03.2021 20:35:56 INFO    LWP19694 [qgit.cpp:136] QGit is stopped

Кэшированный старт


28.03.2021 20:38:00 INFO    LWP19961 [qgit.cpp:102] QGit is running (version: 3.0.1; gitrev: b9ba2e3)
28.03.2021 20:38:13 DEBUG   LWP19961 [dataloader.cpp:126] Exited while parsing
...
28.03.2021 20:38:17 DEBUG   LWP19961 [dataloader.cpp:126] Exited while parsing
Первые два экрана построены, далее нажата 'Q'
28.03.2021 20:38:27 INFO    LWP19961 [qgit.cpp:136] QGit is stopped

Просто для информации: при отображении первый двух экранов потребляет ~2.2 Гига, если проскролить дерево до конца вниз — будет больше 6-ти.

Это что называется "на любителя". Я как раз ценю QGit, за то, что там нет всего Вами перечисленного.
На самом деле в QGit есть механизм "Actions", он позволяет самостоятельно создавать не очень сложные команды "на каждый день": push, pop, fetch, stash, и т.д. В моем списке таких команд 11. Часто я эти команды юзаю из консоли, но иногда и из QGit.

Для YAML есть наработки (врапперы), для TOML — нет, вот и вся причина. Использую yaml-cpp библиотеку (спецификация 1.2).
А недостатки наверное можно найти у любого формата. Если апеллировать к вашей ссылке, то мысль о том, что в yaml можно sql-запрос засунуть меня никогда не посещала — теперь буду знать, что так тоже можно ;)

260000 — что ж это за реп такой?! Заинтриговали :) Я к сожалению с такими объемами не встречался. Максимум, что я видел это 54000 (субмодуль qtbase).
QGit (оригинальный, не мой) кэширует дерево коммитов, и хранит этот кеш в бинарном виде. Это существенно ускоряет повторный старт QGit. Кеш живет одни сутки, на следующий день он будет пересоздан. Видимо это сделано для того чтобы кэш не протухал. Но для больших репов этого все равно недостаточно, т.к. в этом случае уже начинает тормозить Qt-шная отрисовка. Я немного изменил порядок отрисовки: вначале явно рисуется только ~1.5 экрана. Все остальное рисуется фоном. Поэтому у пользователя возникает ощущение, что все построилось быстро. И пока пользователь тянется мышкой что бы что-нибудь нажать или проскролить — дерево, скорее всего, уже будет достроено.
Было бы интересно погонять ваши 260000 коммитов.

Я вообще не понимаю, зачем там выделять память.
Оператор << доопределите самостоятельно.

Доопределил. Ветка distortneo-format
Boost-решение немного отстает от исходного, всего на 3-5%. Однако, с увеличением длины формат-строки отставание так же увеличивается. При длине строки в 100 символов разница составляет уже 20%.

Уточнение: тест для ноутбука выполнялся на аккумуляторе. Ниже тест "от сети"


Core i5-8300H 2.30GHz (Ноутбук, от сети)
ALog: 1.49/2.62
P7: 5.19/5.91
Spdlog: 3.06/3.06

1

Информация

В рейтинге
Не участвует
Откуда
Ярославль, Ярославская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Application Developer, Software Architect
Lead
C++
Software development
Multiple thread
Code Optimization
Qt
OpenCV
C++ STL
Object-oriented design