Snusmumriken
Ну ничо, так имхо чуть понятнее.
А то я успел понаписать кучу читалок файлов, размером в сотню гигабайт, там этих seek - завались (чтение чанками, с откатом "назад" дабы найти заголовок внутрифайловой структуры, который может быть распилен). Привычка.
mva
mva
ы?
Snusmumriken
Ой, глюк. Удалил.
Basil
а почему расово неверно намутить диспетчер, который будет жить отдельно и разруливать обращения к файлу. чтобы не было разрыва в чанках при записи?
Snusmumriken
Ну допустим тебе надо прочитать огромный XML на пятьдесят гигов, и залить его в бд.
В этом файле, например, полностью отсутствуют переходы на следующую строку, или они организованы случайно, за них не зацепишься.
Регулярками по нему целиком не пробежишься, в целом, учитываем что программа не должна отжирать больше сотни мегабайт (и то, это уже довольно много).
К счастью, сам XML имеет стандартную списковую структуру, с отдельными сущностями вида:
<bla-bla>
... несколько десятков мегабайт данных ...
</bla-bla>
И нам, для начала, стоит хотя бы выдрать содержимое этих <bla-bla>(.-)</bla-bla>, потому что они кажется точно помещаются в оперативку (ну слава богу).
При этом, если считывать чанками по фиксированному количеству байт, мы сталкиваемся с тем что в одном чанке регулярно может быть конец старого <bla-bla> и начало нового, поэтому мы должны искать эти </bla-bla> и цепляться за них. А ещё, бывают случаи когда мы считываем чанк, а он прям заканчивается на </bl, и этот заголовок оказывается распилен, и мы его не найдём простой регуляркой. Поэтому при чтении, приходится сдвигаться назад на размер этого <bla-bla>-заголовка, и читать следующий чанк дальше, открамсывая обработанные куски от считанного буфера и приклеивая туда следующие считанные куски.
Вот и пиши диспетчер, исходя из таких условий.
Basil
я только начинаю постигать луа-дзен, и, возможно, мыслю привычными категориями.
Snusmumriken
Ну, это относится не только к луа. В питоне/сишке/плюсах или любом другом языке, у тебя будут примерно те же проблемы (но в сишке - чуть больше, там нет регулярок, хе).
Snusmumriken
Так что скорее это не луа-дзен, а дзен потокового io.
mva
mva
паттерны, всё же, не регулярки :D
Snusmumriken
Да фигня там различий между этими паттернами и регулярками. У регулярок чуть больше операторов (&, |), и \w вместо %w. Хотя у паттернов есть .-, который в регулярках на целый один символ длиннее: .*?
Mikhail
Не стал ждать внешнюю библиотеку с ренулярками. И от партнеров уже не раз ловил багет. Хочу скорости и автономности где это не требовалось.
mva
mva
lpeg уже миллион лет существует
mva
(а в resty доступны NginX'овые)
Mikhail
Не библиотеку. У меня идет постоянный анализ текста на партнеры определенные. Куча параллельных процессов
Mikhail
Дык я не с рести.
Snusmumriken
Ну тады https://luarocks.org/modules/rrt/lrexlib-pcre
Или что-то похожее.
Basil
я 100 лет назад писал на сях грамматику, умеющую в потоке выделять ноды по паттернам, строя КА.
Ilya
Mikhail
однокласснице фриланс очень заходит - она полгода на горнолыжных курортах...
но пашет как бешеная. я так не смогу )
Ilya
Mikhail
Ilya
Snusmumriken
Хех, в целом, я слышал такое определение, что "человек - профессионал, когда определёнными умениями зарабатывает деньги". Но так-то любая макака которую взяли на работу будет профессионалом : )
Ilya
Да, просто я тоже видел, как люди пытались определить понятие "профессионал". Но не помню, к чему пришли в итоге.
Ilya
Ну допустим тебе надо прочитать огромный XML на пятьдесят гигов, и залить его в бд.
В этом файле, например, полностью отсутствуют переходы на следующую строку, или они организованы случайно, за них не зацепишься.
Регулярками по нему целиком не пробежишься, в целом, учитываем что программа не должна отжирать больше сотни мегабайт (и то, это уже довольно много).
К счастью, сам XML имеет стандартную списковую структуру, с отдельными сущностями вида:
<bla-bla>
... несколько десятков мегабайт данных ...
</bla-bla>
И нам, для начала, стоит хотя бы выдрать содержимое этих <bla-bla>(.-)</bla-bla>, потому что они кажется точно помещаются в оперативку (ну слава богу).
При этом, если считывать чанками по фиксированному количеству байт, мы сталкиваемся с тем что в одном чанке регулярно может быть конец старого <bla-bla> и начало нового, поэтому мы должны искать эти </bla-bla> и цепляться за них. А ещё, бывают случаи когда мы считываем чанк, а он прям заканчивается на </bl, и этот заголовок оказывается распилен, и мы его не найдём простой регуляркой. Поэтому при чтении, приходится сдвигаться назад на размер этого <bla-bla>-заголовка, и читать следующий чанк дальше, открамсывая обработанные куски от считанного буфера и приклеивая туда следующие считанные куски.
Вот и пиши диспетчер, исходя из таких условий.
Конкретно для потоковой обработки XML есть SAX. (Интересно, как они это читают? "Сэкс"? ))
Snusmumriken
Ilya
(или sucks :D)
Даниил
ну типа "сакс", но не sucks
Ilya
Да-да. И обертку над реализацией SAX на Луа написал сам Святой Роберто: https://github.com/LuaDist/luaexpat. Так что всем юзать 😃
Ilya
(м, точней сдизайнил)
Snusmumriken
И чего, оно прям огромные потоки фигачит?
P.S. Я на работе работаю в скриптуемых луями базах данных, где надо долго упрашивать разрабов баз встроить какую-нибудь сишную либу.
Ilya
Ну по идее да, там event-API. Где event - это начало / конец тэга и т.д.
Snusmumriken
И накатят её через пару-тройку недель, не на все машины, а надо быстро заполнить базу ))
Ilya
(понимаю про боль с сишными либами)
Snusmumriken
Плюс, кто бы мог подумать, в следующей задаче может быть такой же неимоверно огромный CSV/JSON, которые точно так же надо куда-то загнать : )
К счастью, такие задачи довольно давно перекладывают на кого-то ещё. Но зато эти "кто-то" меня донимают вопросами "а как с этим вообще работать?".
Ilya
Ну CSV-то можно и построчно обрабатывать, а вот насчет JSON надо гуглить :-/
Ilya
"streaming json parser c" выдает кучку результатов.
Snusmumriken
mva
json от xml в плане "битости" из-за кривого парсинга не отличается
Snusmumriken
Да пофигу на битость, мы не парсим в таблицу, мы хардкодно выдираем текст из строкового представления. Это быстрее в миллиард раз.
Никто не хочет ждать трое суток пока база таки заполнится.
mva
но да, cjson, емнип, самый быстрый (но на С). Но есть и pure-lua имплементации
mva
Snusmumriken
Карочи, обработка данных которые не влезают в память - это весело и поучительно. Всем советую. Это не шутка : )
mva
особенно на luajit :D
Snusmumriken
Да на чём угодно. Хочешь - на сишке : )
Snusmumriken
Самое весёлое - когда сами заголовки, за которые ты цепляешься - могут внезапно не поместиться в память.
mva
вот меня, кстати, периодически мучает вопрос
mva
почему у table в дефолтной метатаблице нету объектных методов, как у string.
И вроде я даже помнил ответ когда-то, но опять забыл :)
mva
я имею в виду
local t={}
t:insert(moo);
local z=t:concat(",")
и в таком духе
mva
а то я устал уже в каждую свою поделку таскать класс для таблиц "на батарейках" (и инициализировать их костыльным local t=T{}) 😃
Snusmumriken
Потому что сделал ты таблицу, записал в неё
t.insert = 10, и сломались все твои метатаблицы.
mva
ну так нефиг криворучить и вместо : писать .
Snusmumriken
Нет.
mva
тут я как бы сам был бы виноват
Snusmumriken
Тебе нужен в таблице пара ключ-значение insert или remove. И на этом сломались методы.
Snusmumriken
Если хочется табличек вида "чисто массив с методом" - это делается в полторы строчки:
table.__index = table
t1 = setmetatable({}, table)
t2 = setmetatable({}, table)
t1:insert(t2)
mva
mva
ну, точнее, у меня это вот так: https://gist.github.com/43fae7a428dde588be4841e7af81b536 (модулем)
mva
хм
mva
только сейчас заметил что со времён когда но было модулем (а-ля 5.0) верхние дефайны более не нужны :)
Snusmumriken
Хе. Твой вариант тоже оставляет хвосты в стандартной table, но при этом на каждую таблицу-массив создаёт две таблицы: исходную и содержащую {__index = table}.
Snusmumriken
Так что имхо, ещё более экономный/быстрый/безопасный вариант - вот такой:
local arr_mt = {__index = table}
function Array(t)
return setmetatable(t or {}, arr_mt)
end
t1 = Array()
t2 = Array{1, 2, 3}
Переиспользование, все дела.
Snusmumriken
Когда я делал векторную библиотеку на метатаблицах, всякие операции типа:
self.pos = self.pos + self.vec * dt - создавали и удаляли сразу кучу таблиц в одной строке.
Ну, вот тут вот, например - self.vec * dt создаёт вектор, который нафиг не нужен, ибо тут же создастся новый вектор с суммой. Да и self.pos тоже выкинется. Две таблицы просто создались и уничтожились ни за что. А в игрушках такие векторные операции, время от времени, выполняются сотнями тысяч в секунду.
А если бы я ещё мутил для каждого вектора свою метатаблицу (как у тебя, хе), то создавалось/удалялось бы в два раза больше таблиц. Грусть.
Snusmumriken
Поэтому я быстро напихал методов операций "над собой" в векторную библиотеку, и она разрослась на полторы тыщи строк : )
Но она сейчас тянет режимы "ручной кпп" и "автомата".
Snusmumriken
Но на самом деле, зависимость только в том, сколько таких "массивов" тебе нужно. Если немного - можно и забить.
vitaly
добрый день страна
mva
Снус, нужно ещё немного твоего мозга :)
mva
у меня что-то ночной (UTC+7) тупинг включился
mva
local types={
string=function(s) return ("%s"):format(s) end,
number=function(n) return ("%+0#-15.9f"):format(n) end,
table=function(t) return "[table]" end,
userdata=function(u) return "[userdata]" end,
}
for _,a in ipairs({...}) do
table.insert(res,types[type(a)](a))
end
mva
мне не нравится ...(a)](a), хочу оптимизировать
mva
но все попытки в конце концов в то же самое и утыкаются :)
mva
у тебя большой опыт "обООПшивания процедурщины". Есть идеи? :)
mva
вообще, будь в луне switch/case (или хотя бы шелловый вариант case) - было бы в разы проще это написать нормально 😢
Yuriy
Yuriy
Yuriy
А самое главное - расширяемее