Skip to content

INTERNAL: Use C99 flexible array members and remove btree_elem_item_fixed#968

Merged
jhpark816 merged 1 commit intonaver:developfrom
zhy2on:internal/c99-flexible-array-member
Apr 9, 2026
Merged

INTERNAL: Use C99 flexible array members and remove btree_elem_item_fixed#968
jhpark816 merged 1 commit intonaver:developfrom
zhy2on:internal/c99-flexible-array-member

Conversation

@zhy2on
Copy link
Copy Markdown

@zhy2on zhy2on commented Apr 9, 2026

🔗 Related Issue

⌨️ What I did

  • 컬렉션 elem 구조체(list_elem_item, set_elem_item, map_elem_item, btree_elem_item),
    커맨드 로그 레코드 구조체(cmdlogrec.h), 로그 waiter 구조체(cmdlogmgr.c)에서
    C89의 struct hack(arr[1])을
    C99 flexible array member(arr[])로 변경하였습니다.

  • 이를 통해 불필요해진 btree_elem_item_fixed 타입을 제거하고,
    ntotal 계산에서 sizeof(btree_elem_item)을 직접 사용하도록 수정하였습니다.

…ixed

Replace C89-style trailing array members (arr[1]) with C99 flexible
array members (arr[]) across all collection elem items, log record
structs, and log waiter chunk. Also remove the now-redundant
btree_elem_item_fixed type and update ntotal calculations accordingly.
@jhpark816 jhpark816 requested a review from namsic April 9, 2026 03:44
@jhpark816
Copy link
Copy Markdown
Collaborator

@zhy2on @namsic
cmdlog structure가 사용되는 곳을 확인해 보지 않았는 데, 문제가 없겠죠?

@zhy2on
Copy link
Copy Markdown
Author

zhy2on commented Apr 9, 2026

*Data 구조체 14개 (cmdlogrec.h → cmdlogrec.c)

구조: 각 XxxDataXxxLog 구조체의 body 필드로 embed됨

// cmdlogrec.h:145
typedef struct _IT_link_log {
    LogHdr      header;
    ITLinkData  body;    // ← data[] 있는 XxxData가 여기 embed
    char        *keyptr;
    ...
} ITLinkLog;

쓰이는 두 패턴:

① 쓰기 (_write 함수) — offsetof 로 크기 계산

// cmdlogrec.c:283, 385, 424, 519, 566, 654, 699, 785, 835, 924, 972, 1074, 1125, 1289
int offset = sizeof(LogHdr) + offsetof(ITLinkData, data);
memcpy(bufptr + offset, log->keyptr, log->body.keylen);
// cmdlogrec.c:1491, 1505, 1524, 1563, 1633, 1653, 1674, 1692, 1713, 1731, 1754, 1772, 1808
log->header.body_length = GET_8_ALIGN_SIZE(offsetof(ITLinkData, data) + ...);

sizeof(XxxData) 를 쓰지 않고 offsetof(XxxData, data) 를 씁니다. offsetof은 data 필드 자체의 크기를 포함하지 않고 그 앞까지의 고정 헤더 크기를 반환하므로, data[1] 이든 data[] 이든 반환값이 동일합니다.

② 읽기 (_redo 함수) — body.data 를 포인터로 사용

// cmdlogrec.c:409, 481, 498, 553, 630, 687, 763, 820, 899, 959, 1039, 1110, 1209, 1830
char *keyptr = log->body.data;

로그 버퍼를 *Log 구조체로 overlay해서 읽는 방식입니다. body.data는 고정 헤더 직후의 주소를 가리키는 포인터로만 사용됩니다. data[1] → data[] 로 바꿔도 data 필드의 offset은 동일하므로 같은 주소를 가리킵니다.

log_waiter_chunk (cmdlogmgr.c)

// cmdlogmgr.c:62~66
typedef struct _waiter_chunk {
    struct _waiter_chunk *next;
    log_waiter_t          waiters[];
} log_waiter_chunk;

할당 (cmdlogmgr.c:119):

log_waiter_chunk *chunk = (log_waiter_chunk *)malloc(LOG_WAITER_CHUNK_SIZE);

고정 상수만큼 할당

개수 계산 (cmdlogmgr.c:405):

info->waiter_pchk = (LOG_WAITER_CHUNK_SIZE - sizeof(void*)) / sizeof(log_waiter_t);

sizeof 계산을 sizeof(log_waiter_chunk)가 아닌 sizeof(void*)로 직접 하고 있기 때문에 FAM 방식으로 바꿔도 영향이 없습니다.

Note

waiters[1]로 선언하였을 때, sizeof(log_waiter_chunk)을 쓰면 waiter 1개분이 오버헤드로 빠져 개수가 1 적게 계산되어 sizeof(void*)로 직접 명시했던 것으로 보입니다. sizeof(void*)를 사용한 공식이기에, FAM 변경 전후 모두 동일하게 유효합니다.

결론: 모든 사용처에서 sizeof(XxxData) / sizeof(XxxLog) / sizeof(log_waiter_chunk) 를 할당이나 크기 계산에 쓰지 않습니다. 오직 offsetof() 와 고정 상수만 사용하므로, struct hack(arr[1]) → FAM(arr[]) 변경은 안전합니다.

@jhpark816 jhpark816 merged commit 58ae7c3 into naver:develop Apr 9, 2026
1 check passed
@zhy2on zhy2on deleted the internal/c99-flexible-array-member branch April 10, 2026 07:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants