Pull to refresh
8
0
Никита Ко. @utrack

User

Send message

Если нужно потестить индексы в Postgres — используйте


set local enable_seqscan=off;

который поднимет стоимость seqscan до 100млн, а планировщик будет использовать его, как last resort.

Всё дело в пуле байт, хранимом sql для снижения нагрузки на GC и алгоритме, применяемом db.Scan():

If an argument has type *[]byte, Scan saves in that argument a copy of the corresponding data. The copy is owned by the caller and can be modified and held indefinitely. The copy can be avoided by using an argument of type *RawBytes instead; see the documentation for RawBytes for restrictions on its use.

If an argument has type *interface{}, Scan copies the value provided by the underlying driver without conversion. If the value is of type []byte, a copy is made and the caller owns the result.


Дело в том, что при передаче в Scan() что-нибудь вроде *json.RawMessage он не видит его как *[]byte, и в итоге поинтер указывает (насколько я понял) на копию слайса, который в свою очередь указывает на массив, который одновременно принадлежит пулу самой *sql.DB.

Тут небольшое отступление на всякий пожарный: в Го то, что обычно все называют массивом — это слайс, который является чем-то вроде «окна» в массив любой длины (len(slice) <= len(array)). При этом копия слайса всё ещё отображает исходный массив.

В итоге получается, что в первом вызове Scan() данные опускаются в пустой слайс, который наполняется, помещается в пул и его копия возвращается вам; а при втором вызове sql берёт тот самый грязный слайс из пула и заполняет его новыми данными. Если len(datanew) < len(dataold), то перезаписывается только часть слайса, но возвращается он целиком.

В итоге, если в БД есть две строки: «12345» и «678», которые вы сосканите друг за другом, то вы получите сперва «12345», а потом «67845». Притом после второго скана первый массив(слайс!) будет хранить тоже «67845».
Автор (и все остальные), раз уж ты играешь с json и sql одновременно — недавно словил хитрую граблю по этому поводу.

Если в структуре есть любой тип, наследующий []byte, например json.RawMessage — то пакет sql это не увидит и будет обращаться с ним в пуле объектов как обычно, из-за чего данные в нём иногда будут ломаться (т.к. границы слайса не обнуляются).

Фикс — использовать только []byte или sqlx + sqlx.JSONText (который может быть потенциально опасен).
Только не WeeChat, а WeChat. Я успел удивиться, когда это IRC успел продвинуться :)
Рекурсия это здорово и удобно, но при поиске иерархичных структур на больших объёмах данных\большой вложенности очень быстро проседает производительность — в таких случаях удобней создавать суррогатное поле-массив айдишников с путём элемента от корня и изменять его триггерами. Если интересно — могу написать статью.
Правда, такой подход должен плохо работать при mods > reads из-за постоянного переписывания индексов. Тут остаётся только сесть в угол и бояться :)
Опечатка, да. Спасибо)
Размер bool зависит от платформы, да, обычно, это не тот случай, когда следует беспокоиться о размере. Но всё же существует способ ничего не отправлять, а если точнее — то отправлять ничего (если быть ещё точнее, то речь о пустой структуре).

done := make(chan struct{})
// [...]
done < — struct{}{}


Можно сделать ещё «легче»:
    done := make(chan interface{})
    //
    done <- nil


Или не посылать ничего:
 done := make(chan interface{})
    //
    close(done)
    // в родителе
    select {
      case _,ok := <- done:
      if !ok {
        // канал закрыт
      }
    }


А для неблокирующего чтения также можно использовать select:
ch := make(chan int)
// ...
select {
  val, ok := <- ch:
    // обработка значения
    // если канал пуст - управление возвращается коду
    // если канал закрыт - val == nil, ok == false
}

Ну и зачем такой движок нужен? Даже на сантиметр с места не сдвинулся :)
Кроме быстрее — не нужен node, вот пожалуй и всё. Это уже очень много
Можете считать меня ретроградом, но писать что-то не в браузере на JS не поднимается рука, и вся тенденция с аппликухами на серверах на JS на node не то, чтобы вызывает рвотные позывы, но очень глубокое недопонимание имеется, да. :>
Для обучения программированию подойдёт C#, подойдёт Питон, подойдёт и Паскаль. А вопросы про GUI, айфоны, etc — это не про обучение программированию, это про выбор языка для конкретной цели. :)

Да, можно научиться JS, написать игрушку, написать сервер, написать что угодно — но всё равно JSON удобней (и быстрее) отдавать Питоном или Перлом, на десктопе пока правит балом C# или что-нибудьQt, а на Айфоне — Swift.
Да, Arch Linux, раньше использовал dzen2 для бара но перешёл на b-a-r, dzen2 остался только для вот таких уведомлений
Ну, в основном man и чужие конфиги :) Если интересно — могу написать пост немного позже.
Нигде не встретил в комментариях, но ещё очень здорово работает связка bspwm+sxhkd+(dzen2 || bar), где можно делать вот такие вещи
Зачем ставить live-build, если он почти не используется?

Вместо всего этого можно использовать lb config и lb build, а они всё создадут сами и будут изменять при необходимости:
мануал
По ссылке краткий пример, а вообще l-b умеет много интересного.

P.S.: такие билды очень удобны для копирования на USB.
Как альтернативу можно использовать вот этот инструмент, умеет почти все популярные дистрибутивы и Windows, может попробовать добавить неподдерживаемый + есть бета под Linux.
23ba9f2d105a0758a2dddc62eb40d352
Скорее всего, всё-таки это связано с траекторией полёта.
Но что это, и зачем оно нам нужно?

P.S.: неймспейсовый разрыв, отказавшись от мержа перед ретурном шины — ну суббота же. :^)

Он и так есть: Меню -> Мои приложения

Information

Rating
Does not participate
Location
Пенза, Пензенская обл., Россия
Date of birth
Registered
Activity