Относительно подхода 2:
Ваш второй подход заключается в том, как работает NAT. Каждый TCP / UDP-клиент в локальной сети имеет до 65535 используемых портов (кроме порта 0) и частный IP-адрес. Маршрутизатор знает только один публичный IP-адрес. Поскольку оба клиента могут иметь исходный порт 300, он не может просто заменить частный IP общедоступным, что может привести к возникновению коллизий. Таким образом он заменяет IP и «переводит» порт (NAT: сетевой адрес трансляция ). По возвращении он переводит порт обратно и снова заменяет общедоступный IP-адрес частным, прежде чем пересылать пакет обратно. Вы не будете делать ничего другого, кроме этого. Тем не менее, маршрутизаторы хранят эту информацию в памяти - и они не слишком медленны при выполнении NAT (компании с сотнями компьютеров иногда подключаются к Интернету, и в большинстве случаев замедление едва ли заметно). Вы говорите, что хотите до тысячи транзакций в секунду, но сколько будет клиентов? Поскольку это в основном будет определять размер памяти, необходимый для резервного копирования сопоставлений. Если клиентов не слишком много, вы можете сохранить отображение с отсортированной таблицей в памяти, в этом случае скорость будет наименьшей проблемой (размер таблицы увеличивается, а на сервере не хватает памяти).
Что мне немного неясно, так это то, что вы однажды сказали
К счастью, клиент имеет только около
20 или около того случаев с
эти идентификаторы - давайте назовем их пакеты -
в любой момент времени, и это нужно только
они уникальны среди местных
братья и сестры.
но тогда вы говорите
Некоторые идентификаторы меньше 65535 все еще могут быть
в игре на данном клиенте в любое время
из-за не истечения срока действия.
Полагаю, что вы, вероятно, подразумевали под вторым утверждением, что если клиент запрашивает идентификатор 65536, он все равно может иметь идентификаторы ниже 65535, и они могут быть столь же низкими, как (скажем) 20. Клиент не обрабатывает Идентификаторы в прямом порядке, верно? Таким образом, вы не можете сказать, просто потому, что он теперь запросил 65536, он может иметь некоторые меньшие значения, но, конечно, не в диапазоне 1-1000, правильно? Это может на самом деле сохранить ссылку на 20, 90, 2005 и 41238 и все же перейти на 65535, это то, что вы имели в виду?
Мне лично ваш второй подход больше, чем третий, так как в любом случае легче избежать столкновения, а перевод числа назад - простая и простая операция. Хотя я сомневаюсь, что ваш третий подход может работать в долгосрочной перспективе. Хорошо, у вас может быть байт для хранения того, как часто вы вычитаете 2 ^ 16 из числа. Однако вы можете только вычесть 117 * 2 ^ 16 как наибольшее число. Что вы будете делать, если цифры превысят это? Используя другой алгоритм, это не вычитает, но что делает? Делить? Биты сдвига? В этом случае вы теряете гранулярность, это означает, что этот алгоритм больше не может поражать любое возможное число (оно будет делать большие скачки). Если бы было так просто просто применить магическую функцию перевода к 32-битной системе, чтобы получить из нее 16-битную (+ один дополнительный байт), а затем просто преобразовать ее обратно, думаю, что каждый метод сжатия в этом мире будет использовать ее, как мог бы, нет Независимо от того, каким было 32-битное число, всегда сжимайте его до 24-битного (16 бит + один байт). Это было бы волшебно. Невозможно упаковать 32 бит в 24 бит, а также упаковать всю логику, как преобразовать его обратно в него. Вам понадобится некоторое внешнее хранилище, которое возвращает нас к вашему второму подходу. Это единственный подход, который будет работать, и он будет работать для каждого числа в диапазоне 32-битных чисел.