ClickHouse JS RowBinary Codec Generator pour Node.js
Cette skill génère les deux directions du format réseau : des lecteurs (décoder bytes → valeurs) et des writers (encoder valeurs → bytes, le miroir). Une tâche donnée n'a normalement besoin que d'un seul côté. Ce fichier est le point d'entrée partagé — la porte du format plus les principes communs aux deux directions ; les décisions par direction, les orientations et les tableaux de référence par type se trouvent dans deux fichiers frères.
Choisissez votre côté — lisez uniquement celui dont vous avez besoin :
- *Décoder une réponse `RowBinary` de ClickHouse en valeurs JS → reader.md**. Streaming vs buffer entier, objets ligne vs colonnes, schéma fixe vs runtime, et la référence lecteur par type.
- Encoder des valeurs JS en payload
RowBinaryà envoyer à ClickHouse → writer.md. Les blocs de constructionSink/writeX, le streamingwriteRows, et la référence writer par type.
Le code par type est réel, divisé par direction sous src/readers/ et
src/writers/.
D'abord : RowBinary est-il vraiment le bon format ?
RowBinary existe pour le débit, mais ce n'est pas automatiquement le chemin le plus rapide — adaptez le format à la forme des données avant de vous engager dans un parseur sur mesure.
*Préférez un format `JSON(par ex.JSONEachRow) quand** le résultat est surtout des chaînes / valeurs ressemblant à du JSON que vous consommez en bloc — accès aléatoire à essentiellement tous les champs, exécution de méthodes string/regexp sur eux, traitement des valeurs comme du texte. Le natifJSON.parsede V8 est du C++ fortement optimisé et construit des chaînes et objets JS plus vite qu'un décodeur RowBinary au niveau JS ; associez-le à la compression de réponse HTTP (gzip/zstd`, qui écrase les clés répétitives du JSON) et le coût réseau rétrécit aussi.
RowBinary gagne clairement quand le résultat est dominé par :
- Numériques larges —
Int128/Int256/UInt128/UInt256,Decimal128/Decimal256. - Blobs binaires / largeur fixe —
IPv4,IPv6,UUID,FixedString. - Colonnes numériques largeur fixe haut volume en général, où chaque valeur est une
seule lecture
DataView.
Préférez le format Native quand le chargement colonnaire et l'analytique côté client sont
l'objectif principal (plier/scanner/filtrer les colonnes, alimenter les typed arrays à un Worker ou WASM).
Native est column-major, donc se charge directement dans un typed array par colonne sans transposition.
Pour de l'aide sur le choix et la consommation d'un format JSON* (ou CSV / TSV) à la place, utilisez la
skill clickhouse-js-node-coding.
Orientation centrale (deux directions)
Ces principes s'appliquent que vous génériez un lecteur ou un writer ; l'orientation opérationnelle spécifique à chaque côté se trouve dans reader.md / writer.md.
-
Little-endian uniquement. RowBinary est little-endian ; ciblez x86/ARM. Lisez et écrivez chaque nombre multi-byte avec des accesseurs
DataViewen passant un littéraltruepour le flaglittleEndian. -
Correctness d'abord, puis optimisation. Émettez d'abord un codec correct construit à partir de l'API par type simple. Seulement une fois qu'il est correct (et testé) spécialisez-le. Ne bâchez pas les assomptions de performance avant la correctness.
-
Monomorphisez les types génériques/composites. Émettez du code spécialisé, inliné par combinaison de types au lieu de passer des fonctions en arguments où le type est connu à l'avance.
-
Inlinez les opérations feuilles. Les fonctions
readX/writeXpar type sont la référence correcte et composable ; le codec généré doit INLINER leurs corps, pas les appeler, afin que la boucle ligne soit straight-line sans indirection par champ (et afin que la coalescing largeur fixe puisse plier l'arithmétique offset ensemble). -
Annotez le type par colonne. L'inlining efface la structure de type, donc mettez un court commentaire au-dessus du bloc encode/decode de chaque colonne nommant le type ClickHouse qu'il gère.
-
Le scratch partagé n'est pas rénentrant. Certaines méthodes hot réutilisent un buffer scratch au niveau module comme paire write-then-read — correct seulement parce que l'accès est entièrement synchrone. Une limite
async/yieldentre le remplissage et la lecture le corrompt. -
TypeScript par défaut. Générez du code TypeScript et des helpers sauf si l'utilisateur demande explicitement du JavaScript pur.
Exemples travaillés
Six exemples end-to-end avec vrai speedup sont catalogués dans EXAMPLES.md.
Hors du périmètre
- Parsing JSON / CSV / TSV / Parquet → utilisez
clickhouse-js-node-coding. - Erreurs de connexion, blocages, incompatibilités de type → utilisez
clickhouse-js-node-troubleshooting. - Browser / Web Worker / Edge →
@clickhouse/client-web.