Re[4]: Опциональные типы
От: vdimas Россия  
Дата: 23.02.17 04:01
Оценка:
Здравствуйте, meadow_meal, Вы писали:

_>Так предложи альтернативу.


Если речь об IDL, то проблемно-ориентированное кодирование всей твоей матрешки идёт вот так:
enum ClanUpdate { NoUpdate, EnterClan, ExitClan };

union ClanEvent switch (ClanUpdate) { 
       case NoUpdate: ; 
       case EnterClan: int ClanId; 
       case ExitClan: ; 
};


Если разновидность IDL с автоопределением типа дискриминанта, то будет даже проще:
union ClanEvent { 
       case NoUpdate: ; 
       case EnterClan: int ClanId; 
       case ExitClan: ; 
};

(не надо явно вводить `enum ClanUpdate`)

Итого, для случая выхода из клана тоже достаточно одного байта, а не два, как у тебя сейчас.

Но можно еще проще.
Считаем, что "игрок больше не состоит в клане" — это тоже клан такой. Эдакий клан бесклановых игроков.
Выдели для него некий отдельный ID.
И далее можно унифицировано обновлять поля в плоском сообщении без геммороя со вложенными Nullable в другие Nullable.


_>Задача: имеется сущность Xxx, содержащая следующие свойства:


Задача тривиальная.


_>Решение в лоб:

_>
_>record XxxUpdate
_>{
_>    Optional<T1> value1;
_>    Optional<T2> value2;
_>    ...
_>}
_>

_>и если T это какой-нибудь Optional<int>, то так тому и быть. Вот здесь и образуется Optional<Optional<int>>.

А вот решение так себе.
Ты в сетку как передаёшь?
По байту на признак наличия каждого поля? Если брать IDL, то меньше байта не выйдет, верно? А если не проконтроллировать размер дискриминанта в union, то может легко быть и 2 байта и 4 байта. ))

В общем, использовать IDL в 2017-м (CORBA IDL небось?) — это вообще признак оторванности от реальности.

А полей сколько? Предположим, что у тебя 30 полей, а в среднем за раз передаются 2-3 поля?
И ты на каждое обновление пробегаешься по всем 30-ти полям, что ле, вот в этой манере:
void Update(XxxUpdate update)
{
    if (update.Field1.HasValue)
        this.Field1 = update.Field1.Value; 
    if (update.Field2.HasValue)
        this.Field2 = update.Field2.Value;
...

Очевидно же, что стратегий упаковки обновлений может быть несколько.
Когда полей пересылается мало, то можно применить альтернативную кодировку — вначале прогнать номера полей (тут 5 бит на номер хватит), а потом их значения.

Когда полей посылается много, то можно вначале прогнать битовую маску. Сетевые драйвера баз данных, кста, зачастую делают точно так же: для каждой передаваемой записи, если в ней встречаются Nullable-поля, передаётся сначала битовая маска. И да, в этой битовой маске участвуют только Nullable поля. Например, если полей 16, но Nullable из них всего два, то обе стороны знают, что на маску будет выделен 1 байт в потоке.

Ну или можно взять какой-нить ASN.1 с хорошим профилём упаковки.
Но можно и самому набросать сериализатор. А еще лучше самому набросать утилиту генерации сериализатора по метаинформации, раз уж речь о дотнете, благо по состоянию на 2017-й год инфраструктура развита сильно (можно брать BLToolkit как маппер), там трудоемкости, скорее всего, будет меньше, чем возни с сопряжением c каким-нить IDL-фреймворком.

Через BLToolkit можно сделать так, чтобы код обновления полей вообще ручками писать не надо было.
Отредактировано 23.02.2017 5:00 vdimas . Предыдущая версия .
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.