|
|
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Давайте отложим в сторону юридические моменты. Это не интересно для sql.ru. Лучше обсужить способы storage и оперативный доступ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 16:24 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima TmaytonСпасибо. А сколько времени (мс)у тебя занимает поиск 1 паспорта по этому файлу? ИМХУ если правильно бинарный поиск реализовать будет быстрее дерева, медленнее биткарты. По сути это 10-20 чтений с диска по 4 байта. Причем Последние 10 чтений из 1-2 соседних кластеров (если кластер 4 Кб). Т.е. время поиска не больше времени рандомного чтения 10 кластеров. 2 Дима. ИМХО. 10-20 чтений с диска (random seek, они-же IOPs) это очень много и очень дорого. Если-бы эти 96 млн записей лежали в B+Tree дереве на диске то нам понадобилось-бы 2-3 уровневое дерево или 2-3 операции чтения блоков. Но автор топика уже слышал советы бывалых БД-шников и для себя определил что своя кастомная структура лучше. Ну что-ж. Пускай так. 2 All По поводу биткарт. Я возможно иногда не совсем ясно выражаю свою мысль. Когда я говорю "биткарта Блума" я имею в виду фильтр Блума (ФБ). И это не есть биткарта в общем понимании этого слова. И ее размер не определяется количеством элементов. (Я на всякий случай уточняю). Вообще по последнему пункту я экспериментировал. Я искал некое золотое соотношение качества и количества элементов которо позволяет сериализовать все паспорта и причём без ложно-положительных срабатываний. Это сделать можно но для счётного числа ключей вообще. Для нашей-же задачи фильтр можно наполнить (метафорически это ближе к обучению НС) обучающей выборкой в 96 млн ключей. При этом теоретическая верхняя граница это Десять в десятой это десять миллиардов потенциально возможных числовых ключей. Буквенные я пока для простоты отбросил. Ограниченную кардинальность номеров серий я тоже пока отбросил. Корреляции между сериями и номерами в сериях я тоже отбросил. Исхожу из предположения что номер и серия - соврешенно произвольные. Я решаю (для себя) общую задачу. Исходя из того что обучающая выборка состоит из почти 100 млн ключей а всего возможно 10 млрд необходимо эти 100 млн как-то хранить и быстро доступаться. При этот ответ на проверку паспортов из множества 10 млрд - 100 млн = 9 900 000 000 должен быть отрицательный. Тоесть паспорт должен быть действителен для всех тех номеров которые еще не внесены в обучающую выборку. И в этом есть проблема. ФБ не гарантирует точного ответа. И как захардкодить или как задать "номера исключения" из этого множества я еще не придумал. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 17:32 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Я про обычное бинарное дерево. Почитал про B+Tree, оптимизировано под страничное хранение, согласен что быстрее. В моем смешанном способе хранения проблема снимается: если номеров много: биткарта, т.е. 2 чтения. Если мало: максимум 15 чтений, из которых 10 с одной страницы. Хотя и тут можно добавить в начало списка номеров индекс из 32 диапазонов, тогда будет чтение 3х страниц. Подумаю. Про фильтр Блума: ИМХУ тут он не в тему. Его применение облегчить промахи в выборках, когда сама выборка достаточно тяжелая операция. Тут выборка не тяжелая. Для блума тебе надо какой-то хэш придумать, чтобы равномерно все значения распределил, иначе при 100 млн. бит он просто выродится в биткарту. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 18:14 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima TДля блума тебе надо какой-то хэш придумать, чтобы равномерно все значения распределил, иначе при 100 млн. бит он просто выродится в биткарту. С этого предложения я не понял. Имплементации которые я брал уже содержат готовый набор API вместе с хешфункциями и ничего мне придумывать не надо уже. И почему при 100 млн бит он должен во что-то вырождаться? Я не знаю такого ограничения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 18:18 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Если битовая карта (та, которая в общепринятом смысле) целиком лежит в ОП, то плохой номер паспорта определяется мгновенно без обращения к диску вызовом функции вроде MapTest(Map, Serial, No). В этом случае на диске карта может храниться как угодно: или непосредственно, или в виде дельт. Если в ОП находится только карта серий, то форматом хранения данных является непосредственно битовая карта. В этом случае для получения результата необходимо одно чтение с диска одного байта данных. Формат данных, предназначенный для передачи, может быть каким угодно. Удобно передавать ту же карту в сжатом виде из-за небольшого размера (26M). Если нежелательно использовать архиватор, то подойдет файл с дельтами. Небольшое изменение формата позволяет уменьшить его размер до 43M. Как было сказано чуть выше, этот же файл может использоваться и в работе, если вся битовая карта из него будет грузиться в ОП. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 18:29 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
В моём варианте с com.google.common.hash.BloomFilter и fpp (desired false positive probability) = 0.00001 я получил следующие цифры Код: plaintext 1. 2. 3. Формат карты внутри - достаточно плотен. Вот его шапка (на глаз чтоб оценить энтропию). Код: sql 1. 2. 3. 4. 5. Как видно... никаких длинных областей нулей и единиц там не прослеживается. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 19:23 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Сжимать ее вобщем-то бесполезно. Практически 7z с дефолтными настройками ничего не может сделать. Код: sql 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 19:25 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
maytonИ почему при 100 млн бит он должен во что-то вырождаться? Я не знаю такого ограничения. Извиняюсь. Перепутал, 10 млрд. бит. Биткарта которая покроет все значения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 19:33 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima TmaytonИ почему при 100 млн бит он должен во что-то вырождаться? Я не знаю такого ограничения. Извиняюсь. Перепутал, 10 млрд. бит. Биткарта которая покроет все значения. Простая битовая карта размером в 12 гигабайт? Я-бы такое никому не предложил. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 19:36 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
maytonDima Tпропущено... Извиняюсь. Перепутал, 10 млрд. бит. Биткарта которая покроет все значения. Простая битовая карта размером в 12 гигабайт? Я-бы такое никому не предложил. 1,25 Гб. Всего 4 твоих Блума. PS Сегодня не я один цифры путаю ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 20:13 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima T, а точно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 20:16 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima T1,25 Гб. Всего 4 твоих Блума.Более того, можно вынести третью и четвертую цифры вперед, добавить кольцевой сдвиг (чтобы счет начинался с нуля). Тогда у битовой карты будет использована только первая четверть, а оставшиеся три четверти можно будет просто обрезать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 20:38 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
mayton__Avenger__пропущено... Прочитай сообщение 18742992 . Все номера паспортов выровнены на границу 4 байта. Серии хранятся в массиве серий от [0..10000]. Спасибо. А сколько времени (мс)у тебя занимает поиск 1 паспорта по этому файлу? Если мерить GetTickCount-ом, то получается так: Код: plaintext 1. 2. 3. 4. 5. В среднем 15 ms на паспорт. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 22:28 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Dima T__Avenger__Мощно, какое-то слишком сложное кодирование исходящего буффера. Там все элементарно: допустим S это номер первого байта биткарты в файле, N номер паспорта. Дальше читаем из файла байт (S+N/8) работаем с битом N % 8 чтобы не делать деление и получения остатка (это тяжелые операции) можно их заменить: деление на 8 - это битовый сдвиг вправо на 3 бита (>> 3) остаток от деления на 8 - это получение последних трех бит (&7) Смотря на чем пишешь, на С/С++ можно не менять, компилятор за тебя поменяет. Для работы с нужным битом: пусть К номер бита (0-7). Получаем маску M = 1 << K. т.е. битовый сдвиг влево 1 на К разрядов. Математически M = 2^K. Например: при К = 4, M будет 16 или в двоичной 00010000 B - текущее содержимое байта. Проверка текущего значения бита: (B & M) != 0 (true - установлен) Установка бита: B = B | M Сброс бита: B = B & (~M) &, |, ~ побитовые операции И, ИЛИ, НЕ При генерации с нуля, для ускорения, лучше сначала все посчитать в памяти, затем результат сбросить на диск. Спасибо, тут все понятно. Непонятно назначение SavePassportPacket и LoadPassportPacket. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 22:43 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
__Avenger__Непонятно назначение SavePassportPacket и LoadPassportPacket. Они нужны для сохранения-загрузки всей битовой карты или карты изменений в формате дельта-кодов. В этом формате значительно экономится место на диске. Добавил новые версии "2 в 1" процедур SavePassportPacket2 и LoadPassportPacket2, которые в 2 раза экономнее используют внешнюю память. Удобно для рассылок изменений. свежий исходник {$WARN UNSAFE_CODE OFF} unit ExpiredPassports; interface type TPassportMap= array of array of byte; procedure MapInvert(var Map: TPassportMap; Serial, No: integer); //инвертировать один бит карты procedure MapInclude(var Map: TPassportMap; Serial, No: integer); //установить один бит карты procedure MapExclude(var Map: TPassportMap; Serial, No: integer); //сбросить один бит карты function MapTest(var Map: TPassportMap; Serial, No: integer): boolean; //получить состояние одного бита карты procedure LoadPassportList(var Map: TPassportMap; const FileName: string); //загрузить карту, используя файл ФМС procedure SavePassportMap(var Map: TPassportMap; const FileName: string); //сохранить карту в формате без сжатия procedure LoadPassportMap(var Map: TPassportMap; const FileName: string); //загрузить карту в формате без сжатия procedure SavePassportPacket(var Map: TPassportMap; const FileName: string); //сохранить карту в формате дельта-кодов procedure LoadPassportPacket(var Map: TPassportMap; const FileName: string); //загрузить карту в формате дельта-кодов procedure SavePassportPacket2(var Map: TPassportMap; const FileName: string); //сохранить карту в формате дельта-кодов 2 в 1 procedure LoadPassportPacket2(var Map: TPassportMap; const FileName: string); //загрузить карту в формате дельта-кодов 2 в 1 implementation type TBuffer= array[0..999999] of byte; procedure MapInvert(var Map: TPassportMap; Serial, No: integer); begin; if (Serial<0) or (Serial>9999) or (No<0) or (No>999999) then exit; if Length(Map)=0 then SetLength(Map, 10000); if Length(Map[Serial])=0 then begin; SetLength(Map[Serial], 125000); FillChar(Map[Serial,0], 125000, 0); end; Map[Serial, No shr 3]:=1 shl (No and 7) xor Map[Serial, No shr 3]; end; procedure MapInclude(var Map: TPassportMap; Serial, No: integer); begin; if (Serial<0) or (Serial>9999) or (No<0) or (No>999999) then exit; if Length(Map)=0 then SetLength(Map, 10000); if Length(Map[Serial])=0 then begin; SetLength(Map[Serial], 125000); FillChar(Map[Serial,0], 125000, 0); end; Map[Serial, No shr 3]:=1 shl (No and 7) or Map[Serial, No shr 3]; end; procedure MapExclude(var Map: TPassportMap; Serial, No: integer); begin; if (Serial<0) or (Serial>9999) or (No<0) or (No>999999) then exit; if Length(Map)=0 then exit; if Length(Map[Serial])=0 then exit; Map[Serial, No shr 3]:=(not (1 shl (No and 7))) and Map[Serial, No shr 3]; end; function MapTest(var Map: TPassportMap; Serial, No: integer): boolean; begin; Result:=false; if (Serial<0) or (Serial>9999) or (No<0) or (No>999999) then exit; if Length(Map)=0 then exit; if Length(Map[Serial])=0 then exit; Result:=1 shl (No and 7) and Map[Serial, No shr 3]<>0; end; function SubstrToInt(const s: string; i1, i2: integer): integer; var i, c: integer; begin; Result:=0; for i:=i1 to i2 do begin; c:=ord(s[i])-ord('0'); if cardinal(c)>9 then begin; Result:=-1; exit; end; Result:=Result*10+c; end; end; procedure LoadPassportList(var Map: TPassportMap; const FileName: string); var Fi: Text; s: string; begin; Map:=nil; Assign(Fi, Filename); Reset(Fi); while not EOF(Fi) do begin; ReadLn(Fi, s); if (Length(s)=11) and (s[5]=',') then MapInclude(Map, SubstrToInt(s,1,4), SubstrToInt(s,6,11)); end; CloseFile(Fi); end; procedure SavePassportMap(var Map: TPassportMap; const FileName: string); var Fi: file; Serial: integer; begin; Assign(Fi, Filename); Rewrite(Fi,1); for Serial:=0 to Length(Map)-1 do if Length(Map[Serial])=125000 then begin; BlockWrite(Fi, Serial, 4); BlockWrite(Fi, Map[Serial,0], 125000); end; CloseFile(Fi); end; procedure LoadPassportMap(var Map: TPassportMap; const FileName: string); var Fi: file; Serial, Count: integer; begin; Map:=nil; SetLength(Map, 10000); Assign(Fi, Filename); Reset(Fi,1); while true do begin; BlockRead(Fi, Serial, 4, Count); if Count=0 then break; if (Count<>4) or (Serial<0) or (Serial>9999) then begin; Map:=nil; break; end; SetLength(Map[Serial], 125000); BlockRead(Fi, Map[Serial,0], 125000, Count); if Count<>125000 then begin; Map:=nil; break; end; end; CloseFile(Fi); end; procedure EncodeDelta(var Buf: TBuffer; var BufPos: integer; Delta: integer); begin; if Delta<=$7F then begin; Buf[BufPos]:=Delta; inc(BufPos); end else if Delta<=$3FFF then begin; Buf[BufPos]:=Delta and $3F or $80; Buf[BufPos+1]:=Delta shr 6; inc(BufPos, 2); end else begin; Buf[BufPos]:=Delta and $3F or $C0; Buf[BufPos+1]:=Delta shr 6; Buf[BufPos+2]:=Delta shr 14; inc(BufPos, 3); end; end; function DecodeDelta(var Buf: TBuffer; var BufPos: integer): integer; begin; Result:=Buf[BufPos]; if Result<=$7F then begin; inc(BufPos); end else if Result<=$BF then begin; Result:=integer(Buf[BufPos+1]) shl 6 or Result and $3F; inc(BufPos, 2); end else begin; Result:=integer(Buf[BufPos+2]) shl 14 or integer(Buf[BufPos+1]) shl 6 or Result and $3F; inc(BufPos, 3); end; end; procedure SavePassportPacket(var Map: TPassportMap; const FileName: string); var Fi: file; Serial, No, OldNo, Val, Bit, BufPos, i, j: integer; Buf: TBuffer; begin; Assign(Fi, Filename); Rewrite(Fi,1); for Serial:=0 to Length(Map)-1 do if Length(Map[Serial])=125000 then begin; BlockWrite(Fi, Serial, 4); Bit:=Map[Serial,0] and 1; BlockWrite(Fi, Bit, 1); No:=0; OldNo:=0; BufPos:=0; for i:=0 to 125000-1 do begin; Val:=Map[Serial,i]; if (Val=0) and (Bit=0) or (Val=255) and (Bit<>0) then begin; inc(No, 8); end else for j:=0 to 7 do begin; if Val and 1<>Bit then begin; EncodeDelta(Buf, BufPos, No-OldNo-1); OldNo:=No; Bit:=Bit xor 1; end; inc(No); Val:=Val shr 1; end end; EncodeDelta(Buf, BufPos, No-OldNo-1); BlockWrite(Fi, BufPos, 4); BlockWrite(Fi, Buf[0], BufPos); end; CloseFile(Fi); end; procedure LoadPassportPacket(var Map: TPassportMap; const FileName: string); var Fi: file; Serial, No, OldNo, Bit, BufLen, BufPos: integer; Buf: TBuffer; var Count: integer; begin; Map:=nil; SetLength(Map, 10000); Assign(Fi, Filename); Reset(Fi,1); while true do begin; BlockRead(Fi, Serial, 4, Count); if Count=0 then break; if (Count<>4) or (Serial<0) or (Serial>9999) then begin; Map:=nil; break; end; Bit:=0; BlockRead(Fi, Bit, 1, Count); Bit:=Bit xor 1; if (Count<>1) or (Bit and -2<>0) then begin; Map:=nil; break; end; BlockRead(Fi, BufLen, 4, Count); if (Count<>4) or (BufLen<=0) or (BufLen>SizeOf(Buf)) then begin; Map:=nil; break; end; BlockRead(Fi, Buf[0], BufLen, Count); if Count<>BufLen then begin; Map:=nil; break; end; SetLength(Map[Serial], 125000); No:=0; OldNo:=0; BufPos:=0; while BufPos<BufLen do begin; No:=DecodeDelta(Buf, BufPos)+1+No; Bit:=Bit xor 1; if (BufPos>BufLen) or (No>999999+1) then break; if Bit=0 then while OldNo<No do begin; if (OldNo and 7=0) and (OldNo+7<No) then begin; Map[Serial, OldNo shr 3]:=0; inc(OldNo, 8); end else begin; Map[Serial, OldNo shr 3]:=(not (1 shl (OldNo and 7))) and Map[Serial, OldNo shr 3]; inc(OldNo); end; end else while OldNo<No do begin; if (OldNo and 7=0) and (OldNo+7<No) then begin; Map[Serial,OldNo shr 3]:=$FF; inc(OldNo, 8); end else begin; Map[Serial, OldNo shr 3]:=1 shl (OldNo and 7) or Map[Serial, OldNo shr 3]; inc(OldNo); end; end; end; if (BufPos<>BufLen) or (No<>999999+1) then begin; Map:=nil; break; end; end; CloseFile(Fi); end; procedure EncodeDelta2(var Buf: TBuffer; var BufPos, CodeLen: integer; Delta: integer); begin; if (CodeLen>0) and (Delta<=8) then begin; //пробуем запихнуть маленькую дельту в предыдущий код if Delta=0 then begin; //используем $40 как флаг нулевой дельты if CodeLen=1 then Buf[BufPos-1]:=$40 or Buf[BufPos-1] else Buf[BufPos+1-CodeLen]:=$40 or Buf[BufPos+1-CodeLen]; CodeLen:=0; //чтобы больше не пихать, место занято exit; end else if (CodeLen=1) and (Buf[BufPos-1]<=7) then begin; //если предыдущий код был маленький, то пихаем в него ненулевую дельту Buf[BufPos-1]:=(Delta-1) shl 3 or $80 or Buf[BufPos-1]; CodeLen:=0; //чтобы больше не пихать, место занято exit; end; end; if Delta<=$3F then begin; Buf[BufPos]:=Delta; inc(BufPos); CodeLen:=1; end else if Delta<=$FFF then begin; Buf[BufPos]:=Delta and $3F or $C0; Buf[BufPos+1]:=Delta shr 6; inc(BufPos, 2); CodeLen:=2; end else begin; Buf[BufPos]:=Delta and $3F or $C0; Buf[BufPos+1]:=Delta shr 6 and $3F or $80; Buf[BufPos+2]:=Delta shr 12; inc(BufPos, 3); CodeLen:=3; end; end; function DecodeDelta2(var Buf: TBuffer; var BufPos, NextDelta: integer): integer; begin; if NextDelta>=0 then begin; Result:=NextDelta; NextDelta:=-1; exit; end; Result:=Buf[BufPos]; if Result<=$3F then begin; inc(BufPos); end else if Result<=$7F then begin; NextDelta:=0; Result:=Result and $3F; inc(BufPos); end else if Result<=$BF then begin; NextDelta:=Result shr 3 and $7 + 1; Result:=Result and 7; inc(BufPos); end else begin; if Buf[BufPos+1] and $40<>0 then NextDelta:=0; Result:=integer(Buf[BufPos+1]) and $3F shl 6 or Result and $3F; if Buf[BufPos+1] and $80=0 then inc(BufPos, 2) else begin; Result:=integer(Buf[BufPos+2]) shl 12 or Result; inc(BufPos, 3); end; end; end; procedure SavePassportPacket2(var Map: TPassportMap; const FileName: string); var Fi: file; Serial, No, OldNo, Val, Bit, BufPos, CodeLen, i, j: integer; Buf: TBuffer; begin; Assign(Fi, Filename); Rewrite(Fi,1); for Serial:=0 to Length(Map)-1 do if Length(Map[Serial])=125000 then begin; BlockWrite(Fi, Serial, 4); Bit:=Map[Serial,0] and 1; BlockWrite(Fi, Bit, 1); No:=0; OldNo:=0; BufPos:=0; CodeLen:=0; for i:=0 to 125000-1 do begin; Val:=Map[Serial,i]; if (Val=0) and (Bit=0) or (Val=255) and (Bit<>0) then begin; inc(No, 8); end else for j:=0 to 7 do begin; if Val and 1<>Bit then begin; EncodeDelta2(Buf, BufPos, CodeLen, No-OldNo-1); OldNo:=No; Bit:=Bit xor 1; end; inc(No); Val:=Val shr 1; end end; EncodeDelta2(Buf, BufPos, CodeLen, No-OldNo-1); BlockWrite(Fi, BufPos, 4); BlockWrite(Fi, Buf[0], BufPos); end; CloseFile(Fi); end; procedure LoadPassportPacket2(var Map: TPassportMap; const FileName: string); var Fi: file; Serial, No, OldNo, Bit, BufLen, BufPos, NextDelta: integer; Buf: TBuffer; var Count: integer; begin; Map:=nil; SetLength(Map, 10000); Assign(Fi, Filename); Reset(Fi,1); while true do begin; BlockRead(Fi, Serial, 4, Count); if Count=0 then break; if (Count<>4) or (Serial<0) or (Serial>9999) then begin; Map:=nil; break; end; Bit:=0; BlockRead(Fi, Bit, 1, Count); Bit:=Bit xor 1; if (Count<>1) or (Bit and -2<>0) then begin; Map:=nil; break; end; BlockRead(Fi, BufLen, 4, Count); if (Count<>4) or (BufLen<=0) or (BufLen>SizeOf(Buf)) then begin; Map:=nil; break; end; BlockRead(Fi, Buf[0], BufLen, Count); if Count<>BufLen then begin; Map:=nil; break; end; SetLength(Map[Serial], 125000); No:=0; OldNo:=0; BufPos:=0; NextDelta:=-1; while (BufPos<BufLen) or (NextDelta>=0) do begin; No:=DecodeDelta2(Buf, BufPos, NextDelta)+1+No; Bit:=Bit xor 1; if (BufPos>BufLen) or (No>999999+1) then break; if Bit=0 then while OldNo<No do begin; if (OldNo and 7=0) and (OldNo+7<No) then begin; Map[Serial, OldNo shr 3]:=0; inc(OldNo, 8); end else begin; Map[Serial, OldNo shr 3]:=(not (1 shl (OldNo and 7))) and Map[Serial, OldNo shr 3]; inc(OldNo); end; end else while OldNo<No do begin; if (OldNo and 7=0) and (OldNo+7<No) then begin; Map[Serial,OldNo shr 3]:=$FF; inc(OldNo, 8); end else begin; Map[Serial, OldNo shr 3]:=1 shl (OldNo and 7) or Map[Serial, OldNo shr 3]; inc(OldNo); end; end; end; if (BufPos<>BufLen) or (NextDelta>=0) or (No<>999999+1) then begin; Map:=nil; break; end; end; CloseFile(Fi); end; end. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 23:04 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Aleksandr Sharahov, эх, жаль, забыл исходнику тег добавить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 31.01.2016, 23:06 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
maytonДавайте отложим в сторону юридические моменты. Это не интересно для sql.ru. Лучше обсужить способы storage и оперативный доступ. программирование несколько, шире чем кодирование ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 00:02 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
__Avenger__Если мерить GetTickCount-ом, то получается так: Код: plaintext 1. 2. 3. 4. 5. В среднем 15 ms на паспорт. Тут что-то неправильно мерялось. Откуда эти нули? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 00:14 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
miksoftDima T1,25 Гб. Всего 4 твоих Блума.Более того, можно вынести третью и четвертую цифры вперед, добавить кольцевой сдвиг (чтобы счет начинался с нуля). Тогда у битовой карты будет использована только первая четверть, а оставшиеся три четверти можно будет просто обрезать. У меня была мысль оценить распределение паспортных пространств во всём универсуме. Для этого визуализировать диапазоны и серии на картинке в виде полосок. Как я это планировал сделать. Например - представить номер паспорта в формате AAAA,BBBBBB как точку с координатами (AAAAB,BBBBB) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 00:19 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
mayton, Да тут особо нечего оценивать. Неравномерностей я вижу всего две: - 3 и 4 цифры, т.к. система работает порядка 25 лет. - старшие цифры номера, т.к. далеко не каждый регион израсходовал весь диапазон номеров в конкретный год. (Кстати, это входит в этот файл или нет?) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 00:33 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
Вобщем как-то вот так. Белым пикселам соответствуют использованные паспортнные номера из нашего списка. Грубо 0000,000000 должен соотвествовать пикселу с координатами (0,0). Правому нижнему - 9999,999999 - (511,511). Есть предположение что горизонтальные белые полосы на самом деле не сплошные. В них должны быть дырки. Просто из за уменьшения масштаба эти дырки размером менее 1 пиксела я должен был учитывать в виде антиалиазинга (несколько номеров попадают в 1 пиксел) но алгоритм - грубый и оценочный, и я просто на это забил. Если я где-то ошибся то прошу меня поправить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 01:38 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
1) Немножко переделал. 0000,000000 должен соотвествовать пикселу с координатами (0,0). Да. Координаты - наоборот. Строкам соотвествуют серии. Столбцам - номера. Так более правильно. 2) В картинке появились полу-тона. Просто рендерю в 1024х1024 а потом уменьшаю в два раза чтоб в форуме значить как-то красивее смотрелось. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 02:20 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
mayton, А если 3 и 4 цифры серии вынести вперед, то какая картина получится? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 02:26 |
|
||
|
Два число в одно и обратно
|
|||
|---|---|---|---|
|
#18+
miksoftmayton, А если 3 и 4 цифры серии вынести вперед, то какая картина получится? Завтра, бро. Меня одолевает древне-греческий бог Гипнос. Осоловело тру глазищи... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2016, 02:40 |
|
||
|
|

start [/forum/topic.php?fid=16&msg=39159531&tid=1340797]: |
0ms |
get settings: |
8ms |
get forum list: |
12ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
142ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
61ms |
get tp. blocked users: |
1ms |
| others: | 213ms |
| total: | 452ms |

| 0 / 0 |
