sqpack will reset BaseMsgNum to 1

0 views
Skip to first unread message

Nil Alexandrov

unread,
Mar 16, 2021, 5:37:43 PM3/16/21
to
* Originally in ru.husky
* Crossposted in ru.ftn.develop
Hello, All!

Чем обычно пользователи Husky пуржат (JAM) базы, sqpack?
А чем ещё можно пуржить под линуксом?

Под капотом sqpack, пользуясь smapi, открывает оригинальные файлы базы на
чтение, временные на запись, копирует сообщения до лимита по времени и/или
количество сообщений, и в конце замещает временные файлы на оригинальные файлы
базы.

API smapi при создании базы JAM не позволяет указать BaseMsgNum (Lowest message
number in index file) и всегда ставит там единицу.
Я считаю, что поведение sqpack, когда упакованная база начинает нумерацию
BaseMsgNum снова с 1цы не корректное.

Приведу пример, когда сброс BaseMsgNum в единицу ломает логигу других программ.
jamnntpd/smapinntpd для отображения по NNTP количества сообщений
всего/первое/последнее использует логику, что JAM .jdx файл - это записи по 8
байт на сообщение, соответственно можно сразу сказать сколько всего сообщений,
а из заголовка в .jhr, сколько активных.
Для NNTP клиентов важно, чтобы нумерация сообщений бала сквозной, тогда в
следующий раз при соединении, клиент может понять, что появились новые
сообщения. В случае с jamnntpd/smapinntpd всё работает до тех пор, пока базы не
будут упакованы и тогда нумерация "съедет".
Если бы в заголовке .jhr поле BaseMsgNum было минимальное значение сообщения,
ещё из предыдущей базы, тогда, складывая BaseMsgNum со смещением по 8 байт в
.jdx файле, можно было бы сохранить сквозную нумерацию.

Best Regards, Nil

Alexey Fayans

unread,
Mar 17, 2021, 1:52:44 AM3/17/21
to
Hello Nil!

On Wed, 17 Mar 2021 at 00:34 +0300, you wrote to All:

NA> API smapi при создании базы JAM не позволяет указать BaseMsgNum
NA> (Lowest message number in index file) и всегда ставит там единицу.

feutil purge делает точно так же.

NA> Я считаю, что поведение sqpack, когда упакованная база начинает
NA> нумерацию BaseMsgNum снова с 1цы не корректное.

Не согласен. Когда я работал с движком skMHL, помню, были проблемы с базами, в
которых BaseMsgNum после пуржинга не сбрасывался.

=== Start of Windows Clipboard ===
function TJamMessageBase.GetHighest: Longint;
begin
GetHighest:=JamBaseHeader.BaseMsgNum + JamBaseHeader.ActiveMsgs;
end;
=== End of Windows Clipboard ===

Например, вот эта функция будет возвращать бред. Возможно, это проблема skMHL.
Хорошо бы посмотреть, что говорит стандарт JAM по этому поводу.


... Music Station BBS | https://bbs.bsrealm.net | telnet://bbs.bsrealm.net

Michael Dukelsky

unread,
Mar 17, 2021, 2:42:43 AM3/17/21
to
Привет, Alexey!

17 March 2021 08:25, Alexey Fayans послал(а) письмо к Nil Alexandrov:

NA>> API smapi при создании базы JAM не позволяет указать BaseMsgNum
NA>> (Lowest message number in index file) и всегда ставит там
NA>> единицу.

AF> feutil purge делает точно так же.

NA>> Я считаю, что поведение sqpack, когда упакованная база начинает
NA>> нумерацию BaseMsgNum снова с 1цы не корректное.

AF> Не согласен. Когда я работал с движком skMHL, помню, были проблемы с
AF> базами, в которых BaseMsgNum после пуржинга не сбрасывался.

AF> === Start of Windows Clipboard ===
AF> function TJamMessageBase.GetHighest: Longint;
AF> begin
AF> GetHighest:=JamBaseHeader.BaseMsgNum + JamBaseHeader.ActiveMsgs;
AF> end;
AF> === End of Windows Clipboard ===

AF> Например, вот эта функция будет возвращать бред. Возможно, это
AF> проблема skMHL. Хорошо бы посмотреть, что говорит стандарт JAM по
AF> этому поводу.

---------------------------------------------------------------------
BaseMsgNum Lowest message number in index file
---------------------------------------------------------------------
This field determines the lowest message number in the index file.
The value for this field is one (1) when a message area is first
created. By using this field, a message area can be packed (deleted
messages are removed) without renumbering it. If BaseMsgNum contains
500, the first index record points to message number 500.

BaseMsgNum has to be taken into account when an application
calculates the next available message number (for creating new
messages) as well as the highest and lowest message number in a
message area.

Желаю успехов, Alexey!
За сим откланиваюсь, Michael.

... node (at) f1042 (dot) ru

Nil Alexandrov

unread,
Mar 17, 2021, 2:57:43 AM3/17/21
to
Hello, Alexey!

Wednesday March 17 2021 08:25, from Alexey Fayans -> Nil Alexandrov:

NA>> Я считаю, что поведение sqpack, когда упакованная база начинает
NA>> нумерацию BaseMsgNum снова с 1цы не корректное.
AF> Не согласен.

Хорошо, а объясни тогда зачем нужен BaseMsgNum?

AF> Когда я работал с движком skMHL, помню, были проблемы с
AF> базами, в которых BaseMsgNum после пуржинга не
AF> сбрасывался.[...skipped...]
AF> GetHighest:=JamBaseHeader.BaseMsgNum + JamBaseHeader.ActiveMsgs;

Ну и нижний порог будет как раз BaseMsgNum.

Вот, например, NNTP для ньюсгруппы показывает 3 числа - *всего*, *первое*,
*последнее*.
Если из *последнего* вычесть *первое*, то иногда это будет *всего*, а может и
чуть больше, на количество удалённых сообщений.
Я бы вычислил эти цифры вот так:
Всего сообщений = JamBaseHeader.ActiveMsgs
Первое сообщение = BaseMsgNum
Последнее сообщение = BaseMsgNum + (размер_файла(.jdx) / 8) --
sizeof(s_JamIndex)==8

Предположим у нас BaseMsgNum был 1, и было 1000 сообщений. Нам надо удалить
первые 500.
После пуржинга BaseMsgNum должен быть 500, и в базе последние 500 сообщений.
В следующий раз клиент подключится и запросит, а дай все сообщения начиная с
1000го, и мы ему, так 1000ое и есть последние, тогда клиент понимает, новых
нет.
А если бы BaseMsgNum каждый раз сбрасывался в 1, то клиент говорит дай с
1000го, а ему в отвер, чувак, у меня вообщето всего-то 500.

AF> Хорошо бы посмотреть, что говорит стандарт JAM по этому поводу.

Стандарта прям в FTSC понятии нет, но есть JAM-001 писулька от 93-07-01.

BaseMsgNum Lowest message number in index file
---------------------------------------------------------------------
This field determines the lowest message number in the index file.
The value for this field is one (1) when a message area is first
created. By using this field, a message area can be packed (deleted
messages are removed) without renumbering it. If BaseMsgNum contains
500, the first index record points to message number 500.

BaseMsgNum has to be taken into account when an application
calculates the next available message number (for creating new
messages) as well as the highest and lowest message number in a
message area.

Я прочитал и у меня всё сходится.

Best Regards, Nil

Alexey Fayans

unread,
Mar 17, 2021, 3:52:44 AM3/17/21
to
Hello Michael!

On Wed, 17 Mar 2021 at 09:37 +0300, you wrote to me:

MD> This field determines the lowest message number in the index file.
MD> The value for this field is one (1) when a message area is first
MD> created. By using this field, a message area can be packed
MD> (deleted
MD> messages are removed) without renumbering it. If BaseMsgNum
MD> contains
MD> 500, the first index record points to message number 500.

Ага, то есть либо в процессе пуржинга абсолютные номера сообщений остаются как
есть и BaseMsgNum не сбрасывается, либо всё перенумеровывается и BaseMsgNum
сбрасывается. Подозреваю, в случае с sqpack (как и feutil purge) всё идёт по
второму сценарию, и если просто не сбрасывать BaseMsgNum, получится лажа, с
которой я и сталкивался.

Alexey Fayans

unread,
Mar 17, 2021, 3:52:44 AM3/17/21
to
Hello Nil!

On Wed, 17 Mar 2021 at 09:31 +0300, you wrote to me:

NA>>> Я считаю, что поведение sqpack, когда упакованная база начинает
NA>>> нумерацию BaseMsgNum снова с 1цы не корректное.
AF>> Не согласен.
NA> Хорошо, а объясни тогда зачем нужен BaseMsgNum?

Ты сам ответил на этот вопрос ниже.

AF>> Когда я работал с движком skMHL, помню, были проблемы с
AF>> базами, в которых BaseMsgNum после пуржинга не
AF>> сбрасывался.[...skipped...]
AF>> GetHighest:=JamBaseHeader.BaseMsgNum +
AF>> JamBaseHeader.ActiveMsgs;
NA> Ну и нижний порог будет как раз BaseMsgNum.

Если в процессе пуржинга (и упаковки) у нас сбросились абсолютные номера
сообщений, а BaseMsgNum останется как был, получится лажа.

NA> Предположим у нас BaseMsgNum был 1, и было 1000 сообщений. Нам надо
NA> удалить первые 500. После пуржинга BaseMsgNum должен быть 500,

Только если в процессе пуржинга будут именно удалены первые 500 сообщений, а не
собрана новая база из последующих 500 сообщений, как делает sqpack.

NA> Я прочитал и у меня всё сходится.

Странно.

Alexey Fayans

unread,
Mar 17, 2021, 4:32:44 AM3/17/21
to
Hello Nil!

On Wed, 17 Mar 2021 at 10:36 +0300, I wrote to you:

NA>>>> Я считаю, что поведение sqpack, когда упакованная база начинает
NA>>>> нумерацию BaseMsgNum снова с 1цы не корректное.
AF>>> Не согласен.
NA>> Хорошо, а объясни тогда зачем нужен BaseMsgNum?
AF> Ты сам ответил на этот вопрос ниже.

Ради интереса провёл эксперимент. Сделал тестовую базу с некоторым количеством
сообщений. Встал на первое сообщение, посмотрел заголовки:

MessageNumber: 1
BaseMsgNum: 1

Удалил первое сообщение, посмотрел заголовки:

MessageNumber: 2
BaseMsgNum: 1

Это потому что физически удалённое сообщение ещё в базе.

Сделал feutil pack -quick, встал на первое сообщение, посмотрел заголовки:

MessageNumver: 2
BaseMsgNum: 2

Как и ожидалось, физически первое сообщение было удалено, а BaseMsgNum стал 2.

Снова удалил первое сообщение, сделал feutil pack -quick -renumbeer, посмотрел
заголовки:

MessageNumber: 1
BaseMsgNum: 1

Теперь удаляю второе сообщение, встаю на первое, смотрю заголовки:

MessageNumber: 1
BaseMsgNum: 1

Смотрю заголовки второго сообщения:

MessageNumber: 3
BaseMsgNum: 1

Таким образом у нас получилась дырка, и если физически удалить второе сообщение
в процессе упаковки, вся логика сломается к чертям. Ради интереса пакую feutil
pack -quick (без -renumber), встаю на второе сообщение, смотрю заголовки:

MessageNumber: 2
BaseMsgNum: 1

Перенумерация всё равно случилась, что, в общем, было ожидаемо.

Так что всё работает именно так, как я и понял из стандарта. BaseMsgNum всегда
равен наименьшему абсолютному номеру сообщения в базе, а абсолютные номера
сообщений не могут быть не последовательными. И если в sqpack отключить сброс
BaseMsgNum не меняя остальной логики, получится лажа.

Alexey Vissarionov

unread,
Mar 17, 2021, 9:37:44 AM3/17/21
to
Доброго времени суток, Nil!
17 Mar 2021 00:34:12, ты -> All:

NA> Чем обычно пользователи Husky пуржат (JAM) базы, sqpack?

А зачем вообще это делать? Почти 10-летний архив супола (трафик все
представляют?) - меньше гигабайта. 14-летний архив отхеров :-) меньше
полугигабайта. Остальное совсем мелочь.

NA> А чем ещё можно пуржить под линуксом?

Да хоть /bin/rm :-)

NA> Под капотом sqpack, пользуясь smapi, открывает оригинальные файлы
NA> базы на чтение, временные на запись, копирует сообщения до лимита
NA> по времени и/или количество сообщений, и в конце замещает временные
NA> файлы на оригинальные файлы базы.
NA> API smapi при создании базы JAM не позволяет указать BaseMsgNum
NA> (Lowest message number in index file) и всегда ставит там единицу.
NA> Я считаю, что поведение sqpack, когда упакованная база начинает
NA> нумерацию BaseMsgNum снова с 1цы не корректное.

С чего бы это вдруг? В свежесозданной базе BMN по определению будет 1.

NA> Приведу пример, когда сброс BaseMsgNum в единицу ломает логигу
NA> других программ. jamnntpd/smapinntpd для отображения по NNTP
NA> количества сообщений всего/первое/последнее использует логику,
NA> что JAM .jdx файл - это записи по 8 байт на сообщение,
NA> соответственно можно сразу сказать сколько всего сообщений, а из
NA> заголовка в .jhr, сколько активных.

Игого: авторы этих поделий не удосужились изучить документацию и что-то
накосорылили. Программисты обычно называют это словом "баг" и стараются
исправить.

NA> Для NNTP клиентов важно, чтобы нумерация сообщений бала сквозной,

Могу ошибаться, но вроде бы достаточно монотонности.

NA> тогда в следующий раз при соединении, клиент может понять, что
NA> появились новые сообщения.

Эту нумерацию должен обеспечивать NNTP-сервер. К базе сообщений это
непосредственного отношения не имеет (точнее, иметь не должно).

NA> В случае с jamnntpd/smapinntpd всё работает до тех пор, пока базы
NA> не будут упакованы и тогда нумерация "съедет". Если бы в заголовке
NA> .jhr поле BaseMsgNum было минимальное значение сообщения, ещё из
NA> предыдущей базы, тогда, складывая BaseMsgNum со смещением по 8 байт
NA> в .jdx файле, можно было бы сохранить сквозную нумерацию.

Вот есть софтина. Она создает базу сообщений (например, посредством их
копирования откуда-то). С нуля. Вопрос: какого рожна она будет начинать
нумерацию не с единицы?


--
Alexey V. Vissarionov aka Gremlin from Kremlin
gremlin ПРИ gremlin ТЧК ru; +vii-cmiii-ccxxix-lxxix-xlii

... Существует два уровня защиты: high и нэхай

Nil Alexandrov

unread,
Mar 17, 2021, 10:47:44 AM3/17/21
to
Hello, Alexey!

Wednesday March 17 2021 16:08, from Alexey Vissarionov -> Nil Alexandrov:

AV> С чего бы это вдруг? В свежесозданной базе BMN по определению будет 1.

sqpack "перепаковывает" старую, а не создаёт новую.

NA>> Для NNTP клиентов важно, чтобы нумерация сообщений бала сквозной,
AV> Могу ошибаться, но вроде бы достаточно монотонности.

верно

AV> Вот есть софтина. Она создает базу сообщений (например, посредством их
AV> копирования откуда-то). С нуля. Вопрос: какого рожна она будет
AV> начинать нумерацию не с единицы?

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

Кстати, все ли BBS софтины хранят ластриды именно в базах, или могут хранить в
своих файлах, тогда пуржилки когеретность ломают?

Best Regards, Nil

Nil Alexandrov

unread,
Mar 17, 2021, 12:22:44 PM3/17/21
to
Hello, Alexey!

Wednesday March 17 2021 11:21, from Alexey Fayans -> Nil Alexandrov:

AF> Сделал feutil pack -quick, встал на первое сообщение, посмотрел
AF> Снова удалил первое сообщение, сделал feutil pack -quick -renumbeer,

Хорошая идея - в sqpack добавить разных параметров, чтобы удовлетворить
пуржинг-стратегию самых изысканных. :-)

Например, дефолт будет работать как сейчас - начинать BaseMsgNum с 1 с полной
перенумерацией (как feutil pack -renumbeer)
sqpack -rollover (или любое другое понятное название), тогда новый BaseMsgNum
будет скорректирован так, чтобы "логический" номер сообщения рос непрерывно.

AF> Так что всё работает именно так, как я и понял из стандарта.
AF> BaseMsgNum всегда равен наименьшему абсолютному номеру сообщения базе,

Про терминологию, JAM стандарт говорит, что

> Message # The physical record number within the index file is used as a
> message number. The lowest message number is one (1) and the highest
> message number is 4294967295 (ffffffffH).

Окей, номер сообщения - это позиция в файле индекса .jdx с шагом 8 байт.

> basemsgnum; // Lowest message number in index file

Вот тут, IMHO, формулировка не очень, отсюда многие интерпретируют не
корректно.
Считаю, что basemsgnum - это именно базовое значение, которое если прибавить к
номеру сообщения (физический номер записи), то получится "логический" номер
сообщения.

> ????????.JHR Message headers
> ...
> ulong MessageNumber;// Message number (1-based)

А вот тут интереснее, в заголовочном файле хранится номер сообщения (я называю
логический номер) именно последовательный номер.
-renumbeer видимо должна эти все номера привести к базе 1 во время пуржинга. А
если не перенумеровывать, то можно оставить все номера как есть, но подкрутить
basemsgnum в зависимости от количества выкинутых сообщений.

AF> а абсолютные номера сообщений не могут быть не
AF> последовательными.

Абсолютные номера всегда последовательные, но можно делать "дырки", причём
спецом для этого придумали в индексе .jdx забивать значения -1.

int JAM_DeleteMessage( s_JamBase* Base_PS,
ulong MsgNo_I )
...
Index_S.HdrOffset = 0xffffffff;
Index_S.UserCRC = 0xffffffff;


AF> И если в sqpack отключить сброс BaseMsgNum не
AF> меня остальной логики, получится лажа.

Естественно, надо делать вариант с перенумерацией с сброса в 1цу, или вариант с
сохранением логических номеров сообщений с подкручиванием базы на нужное
значение.

Best Regards, Nil
Reply all
Reply to author
Forward
0 new messages