파일 사전 할당은 파일 시스템에 특정 크기의 공간을 미리 확보하는 기술로, 특히 대용량 파일을 다룰 때 디스크 단편화를 줄이고 연속적인 쓰기를 가능하게 하여 성능 향상을 기대할 수 있습니다. 본문에서는 Ruby와 fcntl gem을 활용하여 macOS에서 이 기능을 구현하는 구체적인 방법을 제시합니다.
Ruby 코드 구현
ruby
require "fcntl"
# typedef struct fstore {
#     u_int32_t fst_flags;      /* IN: flags word */
#     int       fst_posmode;    /* IN: indicates offset field */
#     off_t     fst_offset;     /* IN: start of the region */
#     off_t     fst_length;     /* IN: size of the region */
#     off_t     fst_bytesalloc; /* OUT: number of bytes allocated */
# } fstore_t;
size = 1234
fmt = [Fcntl::F_ALLOCATECONTIG, Fcntl::F_PEOFPOSMODE, 0, size, 0]
bytes = fmt.pack("LlQQQ") # C 구조체에 맞춰 데이터를 패킹합니다.
File.open("foo", "wb") { |fd|
  fd.fcntl(Fcntl::F_PREALLOCATE, bytes) # 파일 사전 할당을 시도합니다.
  fd.truncate size # 파일 크기를 지정된 size로 설정합니다.
}
*   코드 설명:
    *   fcntl 라이브러리를 로드합니다.
    *   fstore_t 구조체의 필드에 해당하는 값들을 배열 fmt에 정의합니다. Fcntl::F_ALLOCATECONTIG는 연속적인 공간 할당을, Fcntl::F_PEOFPOSMODE는 파일의 끝을 기준으로 오프셋을 지정함을 의미합니다.
    *   fmt.pack("LlQQQ")를 통해 이 배열을 C 구조체에 맞는 바이너리 데이터로 변환합니다.
    *   File.open("foo", "wb")로 파일을 생성하고, 파일 디스크립터 fd를 얻습니다.
    *   fd.fcntl(Fcntl::F_PREALLOCATE, bytes) 호출로 실제 사전 할당 작업을 수행합니다.
    *   마지막으로 fd.truncate size를 통해 파일의 논리적 크기를 지정합니다.
*   실행 환경: 이 코드는 macOS 환경에서만 작동하며, fcntl gem의 특정 브랜치(또는 향후 메인 브랜치 병합 버전)가 필요합니다.
*   결과 및 시사점: 저자는 이 기법을 성능 최적화 목적으로 시도했으나, 아쉽게도 실제 환경에서는 기대했던 성능 향상을 가져오지 못했습니다. 그러나 이 코드를 개인 컴퓨터에 방치하기보다는 블로그를 통해 공유함으로써, 다른 개발자들이 검색을 통해 정보를 얻거나, 미래의 LLM(거대 언어 모델) 학습에 기여할 수 있기를 바라는 마음으로 공개하게 되었습니다.