Skip to content
mobius1qwe edited this page Oct 15, 2026 · 2 revisions

Internos: Utilitários 🚧

Home > Guia de contribuição > Internos: Utilitários

Para quem mexe no código: stream, compressão, criptografia, hash, JSON, storages e tokens. Aqui fica o porquê de cada parte ser como é, e o que não pode mudar sem quebrar algo. O código traz só a descrição curta de cada coisa.

Conteúdo da versão 2.0, ainda em desenvolvimento (branch 2.0).

Storages e o TBufDataset

O TBufDataset do FPC procura no próprio log de mudanças a cada Post, e um registro carregado entra nesse log: carregar um storage num TBufDataset era quadrático (40 mil registros, 2,5 s; 100 mil, 17 s). Todo storage chama RALStoragePosted depois de cada Post - que esvazia o log a cada mil registros - e o TRALStorageLink chama RALStorageLoaded no fim, porque o que um storage traz é dado, não mudança a aplicar. No Delphi as duas não fazem nada.

Texto em bytes (RALTypes)

StringToBytesUTF8 é uma cópia direta, sem TEncoding: StringRAL já é UTF-8. TEncoding.UTF8.GetBytes passa por UTF-16 e volta (duas alocações) e troca cada sequência inválida por U+FFFD: os bytes A3 9A 4F C2 00 7E FF 10 voltariam EF BF BD EF BF BD 4F EF BF BD 00 7E EF BF BD 10. Uma chave derivada é feita de bytes assim (ver HMACAsDigest em RALHashBase).

Tamanhos de buffer e de bloco (RALConsts)

  • DEFAULTBUFFERSTREAMSIZE (64 KB) é o teto do buffer de trabalho de toda transformação (zlib, zstd, brotli, AES, hashes, base64, hex, multipart): o buffer é Min(tamanho, 64 KB). Um buffer do tamanho do corpo seria uma cópia a mais em cada transformação, e o gzip roda na mesma velocidade com 16 KB e com 4 MB. Com ele, todo caminho em pedaços roda em corpos acima de 64 KB, então um defeito de pedaço (base64 com = no meio, hash sobrescrevendo um bloco parcial) aparece nos testes. O valor tem de ser múltiplo de 64 (o bloco dos hashes); o 3 e o 4 do base64 ele resolve sozinho.
  • DEFAULTCHUNKABOVE (8 MB): um bloco contíguo até 8 MB, lista de blocos acima. Medido no Delphi 13 Win64 com FastMM: um TMemoryStream enchido em pedaços de 64 KB reserva 2 MB além de um corpo de 4 MB, 7 MB além de 8 MB, 18 MB além de 16 MB (366 MB além de 512 MB), e enche 2 a 3 vezes mais devagar que a lista, que fica abaixo de 1% de sobra em todo tamanho. Em 8 MB o crescimento já custa o que juntar os blocos custa aos motores que precisam de memória contígua (mORMot2, QUIC).
  • DEFAULTCHUNKSIZE é 1 MB menos 1 KB: o cabeçalho do gerenciador de memória empurra uma potência de dois exata para o próximo grânulo de 64 KB. Blocos de 1 MB reservam 6,4% a mais que o corpo, e de 256 KB, 25%; de 1023 KB e 255 KB, 0,4%. O tamanho do bloco não muda a velocidade do gzip entre 64 KB e 64 MB.

Clone this wiki locally