사전 형식

이 문서는 gukhanmun-mkdict가 소비하는 정규화된 사전 입력 형식과, 그 입력에서 산출되는 FST/CDB 사전 파일 배치를 명세합니다. 이는 사전 추출기, 사용자가 유지하는 용어집, 백엔드 빌더 사이의 경계입니다.

정준 TSV 입력

주 입력 형식은 필수 헤더 행을 가진 UTF-8 TSV입니다. 각 파일은 적어도 다음 열을 포함해야 합니다:

필수의미
hanja찾기 키로 사용되는 출처 표기.
hangul그 키에 대해 내보내는 한글 독음.

다음 선택적 열이 인식됩니다:

기본의미
require_hanjafalse렌더러가 출처 한자를 보이게 유지하도록 강제.
require_hangulfalse렌더러가 한글 병기를 포함하도록 강제.

참거짓 값은 true, false, 1, 0입니다. 비어 있는 선택적 참거짓 셀은 false로 다뤄집니다.

category, source, note 같은 추가 열은 장래 확장 여지로 허용됩니다. 현재의 빌더는 그것들을 소비하지 않으며; 짧은 경고를 내고 그 값을 무시합니다.

예시:

hanja	hangul	require_hanja	require_hangul	category
天地	천지	false	false	basic
漢字	한자	true	false	basic
色깔論	색깔론	false	true	mixed

CSV와 JSONL 입력

gukhanmun-mkdict는 각 파일 확장자로부터 입력 파서를 고릅니다. .tsv는 정준 TSV 파서를, .csv는 CSV 파서를, .jsonl은 JSON Lines 파서를 사용하며, 알 수 없는 확장자는 호환성을 위해 TSV로 다뤄집니다.

CSV 파일은 TSV와 같은 헤더 이름을 사용합니다:

hanja,hangul,require_hanja,require_hangul
天地,천지,true,false

각 JSONL 줄은 하나의 객체입니다. 참거짓 필드는 snake_case나 camelCase 표기를 모두 받습니다:

{"hanja":"漢字","hangul":"한자","requireHanja":false,"requireHangul":true}

병합 정책

여러 입력 파일이 제공되거나 한 입력 파일이 hanja 키를 반복할 때, gukhanmun-mkdict는 설정된 병합 정책을 적용합니다:

  • error: 첫 중복 키에서 실패합니다. 이것이 기본입니다.
  • first-wins: 첫 항목을 유지하고 이후 중복을 무시합니다.
  • last-wins: 앞선 항목을 마지막 중복으로 치환합니다.

병합 후, 항목은 백엔드 인코딩 전에 UTF-8 키 바이트 순으로 정렬됩니다. 이로써 같은 정규화 입력과 메타데이터에 대해 생성되는 FST와 CDB 산출물이 결정적이 됩니다.

빌드 메타데이터

생성되는 모든 백엔드 파일은 CBOR 메타데이터를 내장합니다. 최소 키는 다음과 같습니다:

출처
source--metadata source=..., 또는 빈 문자열.
license--metadata license=..., 또는 빈 문자열.
build_date--metadata build_date=..., SOURCE_DATE_EPOCH, 또는 1970-01-01T00:00:00Z.
entry_count병합된 사전 항목 수.
version사전 파일 형식 판본.
max_word_chars유니코드 스칼라 값 단위의 최대 키 길이.
max_key_bytesUTF-8 바이트 단위의 최대 키 길이.
prefix_countCDB 전용: 접두 레코드 수.

entry_count, version, max_word_chars, max_key_bytes, prefix_count은 예약되어 있으며 --metadata로 제공할 수 없습니다. 다른 --metadata KEY=VAL 쌍은 문자열 값으로 보존됩니다.

재현 가능한 빌드를 위해, 빌더는 기본적으로 현재 시각을 사용하지 않습니다. build_date가 명시적으로 넘어오지 않고 SOURCE_DATE_EPOCH가 설정되어 있으면, 그 epoch이 UTC RFC 3339로 형식화됩니다. 두 값 모두 없으면 고정 날짜 1970-01-01T00:00:00Z가 사용됩니다.

FST 백엔드 파일

처음 구현된 백엔드 형식은 fst입니다. 파일은 다음을 담습니다:

  1. 고정된 64바이트 리틀 엔디언 헤더.
  2. CBOR 메타데이터 맵.
  3. fst::Map 바이트.
  4. 연속된 UTF-8 독음 문자열 테이블.

고정 헤더 필드는 다음과 같습니다:

필드크기의미
magic8GUKHMFST.
version4파일 형식 판본, 현재 1.
header length4고정 헤더 길이, 현재 64.
metadata offset8CBOR 메타데이터의 바이트 오프셋.
metadata length8CBOR 메타데이터의 바이트 길이.
FST offset8fst::Map 바이트의 바이트 오프셋.
FST length8fst::Map 바이트의 바이트 길이.
readings offset8독음 문자열 테이블의 바이트 오프셋.
readings length8독음 문자열 테이블의 바이트 길이.

각 FST 키는 hanja 열의 UTF-8 바이트입니다. 각 FST 값은 64비트 정수입니다:

비트필드
0-15UTF-8 바이트 단위의 독음 길이.
16-23표지 비트필드: 비트 0은 require_hanja, 비트 1은 require_hangul.
24-63독음 문자열 테이블 안의 오프셋.

독음 바이트는 FST 값이 아니라 독음 문자열 테이블에 저장되는데, 이는 FST 값이 고정 폭 정수이기 때문입니다.

런타임에 gukhanmun-fst는 고정 헤더와 CBOR 메타데이터를 즉시 디코딩합니다. 그러면 FST 맵 바이트와 연속된 독음 테이블은 하나의 바이트 배후 저장소를 공유합니다: FstDictionary::open()FstDictionary::from_bytes()에는 소유된 힙 바이트, FstDictionary::from_static_bytes()에는 정적 바이트입니다. 이 크레이트는 안전한 파일 기반 mmap 로더를 일부러 노출하지 않는데, 이는 사전이 살아 있는 동안 다른 파일 기술자나 프로세스가 사상된 파일을 불변으로 유지할 것임을 Rust가 강제할 수 없기 때문입니다. entries()has_homophone()은 FST를 열거하므로 전체 사전 스캔으로 남습니다; 반복되는 동음이의 검사가 필요한 호출자는 core의 동음이의 미들웨어의 일괄 인덱스를 사용해야 합니다.

CDB 백엔드 파일

CDB 백엔드 형식은 cdb입니다. 이는 CDB 키 공간에 내장된 트라이를 사용합니다: 각 사전 키의 각 접두사가 CDB 키로 쓰입니다. 완전한 사전 항목인 접두 레코드는 독음과 표지 비트를 싣고; 더 긴 항목으로 이어지기만 하는 접두 레코드는 독음을 싣지 않습니다.

오프셋크기필드
01is_complete (이 접두사 자체가 항목이면 1).
11표지 비트필드: 비트 0은 require_hanja, 비트 1은 require_hangul.
22UTF-8 바이트 단위의 독음 길이, 리틀 엔디언; 비완전이면 0.
4reading_len독음 바이트.

메타데이터 CBOR 맵은 예약 키 __gukhanmun_meta__ 아래에 저장됩니다.

런타임 CDB 백엔드는 cdb 크레이트의 파일 기반 리더를 사용하고 백엔드를 HanjaDictionary 뒤에 불투명하게 유지합니다. 이는 안전하지 않은 mmap 표면을 더하지 않고도 전체 CDB 파일을 Gukhanmun 소유 버퍼로 불러오는 것을 이미 피합니다.

검증

--validate를 쓰면 gukhanmun-mkdict는 출력을 쓴 뒤 선택된 백엔드로 다시 열어, 병합된 모든 항목이 같은 독음과 표지 비트로 복원될 수 있는지 검사합니다. 검증 실패는 치명적입니다.