TCB v103 — presence 비트맵
상태: 구현 완료 · 대상 버전: 103 (102를 대체) · 102는 0.1.0으로 배포되었으므로 그 형식의 파일이 실재합니다 — 호환 경로는 없습니다(§5)
옵셔널 컬럼이 「어느 로우에 값이 있는지」를 파일에 담습니다. 와이어 바이트의 비트 6이 그 사실을 선언하고, 컬럼 블록 앞에 로우당 1비트의 비트맵이 붙습니다. 값 블록과 인코딩 9종은 그대로입니다.
이 문서의 범위는 형식으로 한정합니다. 시트 표기·모델·모든 언어의 Has{필드} 액세서와 그
선택의 근거는 옵셔널 필드에 있습니다.
1. 변경 근거 — 값이 없는 것과 0의 구별
v102까지 파일에는 「없음」을 적을 자리가 없었습니다. int?의 빈 칸은 0으로 기록되었고, 읽는
쪽은 비어 있던 칸과 0이라고 적은 칸을 구별할 수 없었습니다. 0이 뜻을 갖는 컬럼에서는 그
구별이 필요한 것의 전부입니다.
string과 bool이 그 사정을 가장 분명하게 보여줍니다 — 빈 칸이 각각 ""와 false로 읽히므로
값만으로는 두 로우가 같습니다. 두 로우를 가르는 것은 presence뿐입니다.
2. 와이어 바이트 — 비트 6
7 6 5 4 3 2 1 0
[ ? ] [ kind ] [ element ]
↑
v103이 쓰기 시작한 비트
| 마스크 | 의미 |
|---|---|
0x0F | 엘리먼트 타입 |
0x30 | kind (스칼라 · 고정 배열 · 가변 배열) |
0x40 | 옵셔널 — 블록 앞에 presence 비트맵이 있음 (TcbFormat.WireNullable) |
0x80 | 예약. 0 |
kind 마스크는 0x03입니다((wire >> 4) & 0x03). 롤아웃 기간에 아직 지원하지 않는 리더들이
이것을 0x07로 넓혀 두었던 것은, 그러지 않으면 비트 6을 무시하고 presence 비트맵을 값으로 읽기
때문입니다. 전부가 비트 6을 nullability로 읽는 지금은 다시 0x03입니다.
kind 값을 쓰지 않은 이유. kind는 2비트이고 남은 값이 3 하나뿐입니다. 옵셔널은 kind와
직교합니다 — 스칼라도, 고정 배열도, 가변 배열도 옵셔널일 수 있습니다. 직교하는 것을 kind에
넣으면 마지막 한 자리를 쓰고도 조합을 표현하지 못합니다. 남은 kind 값은 진짜 새로운 종류를 위해
유지합니다.