diff --git a/CGDB.h b/CGDB.h index 1458731..0cbcd88 100644 --- a/CGDB.h +++ b/CGDB.h @@ -25,7 +25,6 @@ extern const char* DATA_FILE; extern const char* MAP_FILE; // Add new function declarations -void init_core_mapping(void); int get_core_position(int node_index); int load_node_to_core(int node_index); void unload_node_from_core(int node_index); diff --git a/binary-data/data.bin b/binary-data/data.bin index 8719a4a..3400035 100644 Binary files a/binary-data/data.bin and b/binary-data/data.bin differ diff --git a/binary-data/free_space.bin b/binary-data/free_space.bin index 87e4275..8a2681c 100644 Binary files a/binary-data/free_space.bin and b/binary-data/free_space.bin differ diff --git a/binary-data/map.bin b/binary-data/map.bin index 09028cd..4f8c81f 100644 Binary files a/binary-data/map.bin and b/binary-data/map.bin differ diff --git a/cgdb b/cgdb index 71c426f..6a87feb 100755 Binary files a/cgdb and b/cgdb differ diff --git a/src/axis.c b/src/axis.c index de998b9..6fc5706 100644 --- a/src/axis.c +++ b/src/axis.c @@ -6,9 +6,7 @@ #include int get_axis_count(uchar* node, ushort channel_index) { - int offset = get_channel_offset(node, channel_index); - if (offset < 0) return -1; - + uint offset = get_channel_offset(node, channel_index); return *(ushort*)(node + offset); // First 2 bytes contain axis count } @@ -56,8 +54,7 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { uint channel_offset = get_channel_offset(node, channel_index); // Get current axis count - ushort* axis_count = (ushort*)(node + channel_offset); - ushort current_count = *axis_count; + ushort current_count = *(ushort*)(node + channel_offset); // Check if axis already exists if (has_axis(node, channel_offset, axis_number)) { @@ -65,25 +62,21 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { return AXIS_ERROR; } - // Calculate required space + // Calculate new axis table size uint axis_table_size = (current_count + 1) * 6; // Including new axis entry - uint last_axis_offset = 0; - uint last_axis_data_size = 0; - if (current_count > 0) { + // Calculate required size + uint required_size; + if (current_count == 0) { + required_size = channel_offset + axis_table_size + 4; // +2 for axis count, +2 for link count + } else { // Get last axis's offset and data size uint* last_offset_ptr = (uint*)(node + channel_offset + 2 + ((current_count - 1) * 6) + 2); - last_axis_offset = *last_offset_ptr; + uint last_axis_offset = *last_offset_ptr; ushort* last_link_count = (ushort*)(node + channel_offset + last_axis_offset); - last_axis_data_size = 2 + (*last_link_count * sizeof(Link)); // 2 for link count - } - - // Calculate total required size - uint required_size = channel_offset + axis_table_size; // Channel header + axis table - if (current_count > 0) { + uint last_axis_data_size = 2 + (*last_link_count * sizeof(Link)); + required_size = channel_offset + last_axis_offset + last_axis_data_size + 6 + 2; - } else { - required_size += 2; // Just need space for new axis's link count } // Check if we need more space @@ -96,18 +89,17 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { return AXIS_ERROR; } Core[node_index] = node; - channel_offset = get_channel_offset(node, channel_index); - axis_count = (ushort*)(node + channel_offset); + // channel_offset remains the same, no need to recalculate } // Move existing axis data forward if (current_count > 0) { uint data_start = channel_offset + 2 + (current_count * 6); - uint data_size = last_axis_offset + last_axis_data_size - (current_count * 6); + uint data_size = current_node_size - data_start - 6; // Entire remaining data - // Move data forward by 6 bytes - memmove(node + data_start + 6, - node + data_start, + // Move all axis data forward by 6 bytes + memmove(node + data_start + 6, + node + data_start, data_size); // Update all existing axis offsets @@ -118,9 +110,13 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { } // Add new axis entry - uint new_axis_offset = (current_count > 0) ? - last_axis_offset + last_axis_data_size + 6 : - 2 + axis_table_size; + uint new_axis_offset; + if (current_count == 0) { + new_axis_offset = 8; // Fixed offset: axis count(2) + first axis table entry(6) + } else { + // Use already calculated required_size + new_axis_offset = required_size - channel_offset - 2; // -2 for new link count + } ushort* new_axis_number = (ushort*)(node + channel_offset + 2 + (current_count * 6)); uint* new_axis_offset_ptr = (uint*)(node + channel_offset + 2 + (current_count * 6) + 2); @@ -133,7 +129,7 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { *new_link_count = 0; // Update axis count - (*axis_count)++; + (*(ushort*)(node + channel_offset))++; // Save changes to data.bin FILE* data_file = fopen(DATA_FILE, "r+b"); @@ -146,9 +142,6 @@ int create_axis(uint node_index, ushort channel_index, ushort axis_number) { return AXIS_ERROR; } - printf("Created axis %d in node %d, channel %d\n", - axis_number, node_index, channel_index); - return AXIS_SUCCESS; } @@ -168,26 +161,56 @@ int delete_axis(uint node_index, ushort channel_index, ushort axis_number) { return AXIS_ERROR; } - // Get current axis count + // Get current axis count and find target axis position ushort* axis_count = (ushort*)(node + channel_offset); - ushort current_axis_count = *axis_count; - - // Find the axis position - int axis_data_offset = channel_offset + 2; // Skip axis count int axis_position = -1; + uint axis_data_offset = channel_offset + 2; // Skip axis count - for (int i = 0; i < current_axis_count; i++) { + for (int i = 0; i < *axis_count; i++) { if (*(ushort*)(node + axis_data_offset + (i * 6)) == axis_number) { axis_position = i; break; } } - // Shift remaining axes to fill the gap - if (axis_position < current_axis_count - 1) { + // Calculate size to remove + uint target_axis_offset = *(uint*)(node + axis_data_offset + (axis_position * 6) + 2); + ushort* target_link_count = (ushort*)(node + channel_offset + target_axis_offset); + uint bytes_to_remove = 6 + 2 + (*target_link_count * 6); // axis entry + link count + links + + // If not the last axis, move later axis data forward + if (axis_position < *axis_count - 1) { + // Calculate start of next axis + uint next_axis_start = channel_offset + target_axis_offset + 2 + (*target_link_count * 6); + uint data_to_move_size; + + if (axis_position == *axis_count - 2) { + // Moving last axis + uint last_axis_offset = *(uint*)(node + axis_data_offset + ((*axis_count - 1) * 6) + 2); + ushort* last_link_count = (ushort*)(node + channel_offset + last_axis_offset); + data_to_move_size = 2 + (*last_link_count * 6); // link count + links + } else { + // Moving multiple axes + uint last_axis_offset = *(uint*)(node + axis_data_offset + ((*axis_count - 1) * 6) + 2); + ushort* last_link_count = (ushort*)(node + channel_offset + last_axis_offset); + data_to_move_size = (channel_offset + last_axis_offset + 2 + (*last_link_count * 6)) - next_axis_start; + } + + // Move data forward + memmove(node + channel_offset + target_axis_offset, + node + next_axis_start, + data_to_move_size); + + // Update offsets for remaining axes + for (int i = axis_position + 1; i < *axis_count; i++) { + uint* offset_ptr = (uint*)(node + axis_data_offset + (i * 6) + 2); + *offset_ptr -= bytes_to_remove; + } + + // Remove axis entry memmove(node + axis_data_offset + (axis_position * 6), node + axis_data_offset + ((axis_position + 1) * 6), - (current_axis_count - axis_position - 1) * 6); + (*axis_count - axis_position - 1) * 6); } // Update axis count @@ -199,9 +222,9 @@ int delete_axis(uint node_index, ushort channel_index, ushort axis_number) { fseek(data_file, CoreMap[node_index].file_offset, SEEK_SET); fwrite(node, 1, 1 << (*(ushort*)node), data_file); fclose(data_file); + return AXIS_SUCCESS; } - printf("Deleted axis %d from node %d, channel %d\n", - axis_number, node_index, channel_index); - return AXIS_SUCCESS; + printf("Error: Failed to update data.bin\n"); + return AXIS_ERROR; } \ No newline at end of file diff --git a/src/cli/command_handler.c b/src/cli/command_handler.c index 6ade713..fd3c161 100644 --- a/src/cli/command_handler.c +++ b/src/cli/command_handler.c @@ -3,6 +3,7 @@ #include "../channel.h" #include "../link.h" #include "../free_space.h" +#include "../tests/axis_tests.h" #include #include #include @@ -353,6 +354,35 @@ int handle_print_free_space(char* args) { return CMD_SUCCESS; } +int handle_run_tests(char* args) { + if (args) { + print_argument_error("run-tests", "", false); + return CMD_ERROR; + } + + printf("\nRunning all tests...\n"); + int failed = 0; + + // Run axis creation tests + failed += test_axis_creation(); + + // Run resize node space tests + failed += test_resize_node_space(); + + printf("\nAll tests completed. Total failed tests: %d\n", failed); + return (failed == 0) ? CMD_SUCCESS : CMD_ERROR; +} + +int handle_test_resize(char* args) { + if (args) { + print_argument_error("test-resize", "", false); + return CMD_ERROR; + } + + int failed = test_resize_node_space(); + return (failed == 0) ? CMD_SUCCESS : CMD_ERROR; +} + void print_help() { printf("\nAvailable commands:\n"); printf(" create-axis Create a new axis\n"); @@ -363,6 +393,8 @@ void print_help() { printf(" delete-link Delete a link\n"); printf(" print-node Print node data in hexadecimal format\n"); printf(" print-free-space Print free space information\n"); + printf(" run-tests Run all test cases\n"); + printf(" test-resize Run resize node space tests\n"); printf(" help Show this help message\n"); printf(" exit Exit the program\n"); printf("\nAxis types:\n"); @@ -379,7 +411,8 @@ int handle_command(char* command) { // Common argument validation if (strcmp(cmd, "help") == 0 || strcmp(cmd, "exit") == 0 || - strcmp(cmd, "print-free-space") == 0) { + strcmp(cmd, "print-free-space") == 0 || strcmp(cmd, "run-tests") == 0 || + strcmp(cmd, "test-resize") == 0) { // These commands don't need arguments if (strcmp(cmd, "help") == 0) { print_help(); @@ -388,6 +421,12 @@ int handle_command(char* command) { else if (strcmp(cmd, "print-free-space") == 0) { return handle_print_free_space(args); } + else if (strcmp(cmd, "run-tests") == 0) { + return handle_run_tests(args); + } + else if (strcmp(cmd, "test-resize") == 0) { + return handle_test_resize(args); + } return CMD_EXIT; } diff --git a/src/cli/command_handler.h b/src/cli/command_handler.h index b5dcbe1..1431ff8 100644 --- a/src/cli/command_handler.h +++ b/src/cli/command_handler.h @@ -20,6 +20,8 @@ int handle_create_link(char* args); int handle_print_node(char* args); int handle_print_free_space(char* args); int handle_delete_link(char* args); +int handle_run_tests(char* args); +int handle_test_resize(char* args); void print_help(void); // Error handling utilities diff --git a/src/database.c b/src/database.c index 583df3b..b1f5ea7 100644 --- a/src/database.c +++ b/src/database.c @@ -1,4 +1,5 @@ #include "database.h" +#include "init.h" #include #ifdef _WIN32 diff --git a/src/free_space.c b/src/free_space.c index dacf551..514f4f5 100644 --- a/src/free_space.c +++ b/src/free_space.c @@ -163,7 +163,7 @@ uchar* resize_node_space(uchar* node, ushort required_size, uint node_index, uin *new_size = 1 << node_size_power; // Allocate new space - FreeBlock* free_block = find_free_block(*new_size); + FreeBlock* free_block = find_and_get_free_block(*new_size); uchar* new_node = NULL; if (free_block) { @@ -171,11 +171,14 @@ uchar* resize_node_space(uchar* node, ushort required_size, uint node_index, uin new_node = (uchar*)malloc(*new_size); memcpy(new_node, node, current_size); - // Update CoreMap with new location + // Store old offset before updating CoreMap + long old_offset = CoreMap[node_index].file_offset; CoreMap[node_index].file_offset = free_block->offset; - // Add old space to free space - add_free_block(current_size, CoreMap[node_index].file_offset); + // Add old space to free space using stored old_offset + add_free_block(current_size, old_offset); + + free(free_block); // Don't forget to free the block } else { // No suitable free block found, allocate at end of file new_node = (uchar*)malloc(*new_size); @@ -205,4 +208,46 @@ uchar* resize_node_space(uchar* node, ushort required_size, uint node_index, uin printf("Warning: Failed to update map.bin\n"); } return new_node; +} + +FreeBlock* find_and_get_free_block(uint size) { + // Find suitable block + FreeBlock* found = NULL; + uint block_position = -1; + + for (uint i = 0; i < free_space->count; i++) { + if (free_space->blocks[i].size == size) { + found = &free_space->blocks[i]; + block_position = i; + break; + } + } + + if (found) { + // Create return block + FreeBlock* result = (FreeBlock*)malloc(sizeof(FreeBlock)); + result->size = found->size; + result->offset = found->offset; + + // Remove block from free space list + if (block_position < free_space->count - 1) { + memmove(&free_space->blocks[block_position], + &free_space->blocks[block_position + 1], + (free_space->count - block_position - 1) * sizeof(FreeBlock)); + } + + // Update free space + free_space->count--; + if (free_space->count > 0) { + free_space->blocks = (FreeBlock*)realloc(free_space->blocks, + free_space->count * sizeof(FreeBlock)); + } else { + free(free_space->blocks); + free_space->blocks = NULL; + } + + return result; + } + + return NULL; } \ No newline at end of file diff --git a/src/free_space.h b/src/free_space.h index 5f7648a..dadaee2 100644 --- a/src/free_space.h +++ b/src/free_space.h @@ -28,6 +28,7 @@ extern FreeSpace* free_space; int init_free_space(void); void save_free_space(void); FreeBlock* find_free_block(uint size); +FreeBlock* find_and_get_free_block(uint size); void add_free_block(uint size, long offset); int get_free_index(void); void add_free_index(uint index); diff --git a/src/tests/axis_tests.c b/src/tests/axis_tests.c index 02af63b..141abca 100644 --- a/src/tests/axis_tests.c +++ b/src/tests/axis_tests.c @@ -1,4 +1,5 @@ #include "../axis.h" +#include "../free_space.h" #include int test_axis_creation() { @@ -57,4 +58,65 @@ int test_axis_creation() { printf("\nAxis creation tests completed: %d failed\n", failed_tests); return failed_tests; +} + +int test_resize_node_space() { + printf("\nTesting resize_node_space functionality...\n"); + int failed_tests = 0; + + // Test 1: Create initial axes to generate free blocks + printf("Setting up test environment...\n"); + int result = create_axis(0, 0, 1); + result &= create_axis(0, 0, 2); + result &= create_axis(0, 0, 3); + + if (result != AXIS_SUCCESS) { + printf("✗ Failed to set up test environment\n"); + return 1; + } + + // Verify initial free space state + printf("\nChecking initial free space state...\n"); + if (free_space->count != 2) { + printf("✗ Expected 2 free blocks, got %d\n", free_space->count); + failed_tests++; + } else { + printf("✓ Correct number of initial free blocks\n"); + } + + // Test 2: Create axis in node 1 to trigger resize + printf("\nTesting node resize with free block reuse...\n"); + result = create_axis(1, 0, 1); + + if (result != AXIS_SUCCESS) { + printf("✗ Failed to create axis for resize test\n"); + failed_tests++; + } else { + printf("✓ Successfully created axis triggering resize\n"); + } + + // Verify final free space state + printf("\nChecking final free space state...\n"); + if (free_space->count != 2) { + printf("✗ Expected 2 free blocks after resize, got %d\n", free_space->count); + failed_tests++; + } else { + // Verify block sizes + int found_16byte_blocks = 0; + for (uint i = 0; i < free_space->count; i++) { + if (free_space->blocks[i].size == 16) { + found_16byte_blocks++; + } + } + + if (found_16byte_blocks != 2) { + printf("✗ Expected 2 16-byte blocks, found %d\n", found_16byte_blocks); + failed_tests++; + } else { + printf("✓ Correct free block sizes after resize\n"); + } + } + + printf("\nResize node space tests completed: %d failed\n", failed_tests); + return failed_tests; } \ No newline at end of file diff --git a/src/tests/axis_tests.h b/src/tests/axis_tests.h index ed90360..b1dd1e9 100644 --- a/src/tests/axis_tests.h +++ b/src/tests/axis_tests.h @@ -3,5 +3,6 @@ // Test function declarations int test_axis_creation(void); +int test_resize_node_space(void); #endif // AXIS_TESTS_H \ No newline at end of file diff --git a/system-documents/axis-management.md b/system-documents/axis-management.md index b15d3cd..c8da73b 100644 --- a/system-documents/axis-management.md +++ b/system-documents/axis-management.md @@ -213,4 +213,184 @@ Channel Start 3. 데이터 이동 - 새로운 위치로 데이터 복사 - CoreMap 업데이트 - - 파일 offset 조정 \ No newline at end of file + - 파일 offset 조정 + +### Axis Creation Process Details + +#### Channel Offset 계산 +1. Channel 위치 찾기 + ```c + uint channel_offset = get_channel_offset(node, channel_index); + ``` + +2. Axis Count 확인 + ```c + ushort current_count = *(ushort*)(node + channel_offset); + ``` + +#### Required Size 계산 +1. Axis Table Size + ```c + uint axis_table_size = (current_count + 1) * 6; + ``` + +2. 필요 공간 계산 + - 첫 번째 axis 생성 시: + ```c + required_size = channel_offset + axis_table_size + 4; + // +2 for axis count + // +2 for initial link count + ``` + + - 기존 axis가 있는 경우: + ```c + required_size = channel_offset + last_axis_offset + + last_axis_data_size + 6 + 2; + ``` + +#### Offset 계산 +1. Channel 기준 상대 offset + - 첫 번째 axis: + ```c + new_axis_offset = 2 + 6; // After axis count and its table entry + ``` + + - 추가 axis: + ```c + new_axis_offset = 2 + axis_table_size; // After all table entries + ``` + +2. 데이터 이동 + - 기존 데이터를 6바이트 뒤로 이동 + - 모든 axis offset 값 6바이트 증가 + +#### 메모리 구조 +``` +[Channel Start] ++0: Axis Count (2) ++2: Axis Table (6 * N) + - Axis Number (2) + - Relative Offset (4) ++2+6N: Axis Data + - Link Count (2) + - Link Data (...) +``` + +### Data Movement Strategy + +#### Axis Data Movement +1. 단순화된 이동 방식 + ```c + uint data_start = channel_offset + 2 + (current_count * 6); // Axis data 시작점 + uint data_size = current_node_size - data_start - 6; // 전체 남은 데이터 + ``` + +2. 이동 과정 + - Axis table 뒤의 모든 데이터를 6바이트 뒤로 이동 + - 메모리 이동은 한 번의 memmove로 처리 + - 복잡한 크기 계산 불필요 + +3. Offset 업데이트 + - 모든 axis의 offset을 6바이트씩 증가 + - Table entry 순서대로 순차 처리 + +#### 장점 +1. 단순성 + - 복잡한 크기 계산 제거 + - 전체 데이터를 한 번에 이동 + - 실수 가능성 감소 + +2. 효율성 + - 메모리 접근 최소화 + - 불필요한 계산 제거 + - 코드 가독성 향상 + +#### 메모리 레이아웃 +``` +[Channel Start] ++0: Axis Count (2) ++2: Axis Table (6 * N) ++2+6N: All Axis Data (moved as one block) +``` + +### Axis Offset 계산 + +#### 첫 번째 Axis (axis_count = 0) +``` +new_axis_offset = 8 +``` +- axis count (2 bytes) +- first axis table entry (6 bytes) +- 첫 번째 axis는 항상 고정된 위치에 생성 + +#### 추가 Axis (axis_count > 0) +``` +new_axis_offset = required_size - channel_offset - 2 +``` +구성: +1. required_size: 전체 필요한 공간 +2. channel_offset: 채널 시작 위치 +3. -2: 새로운 axis의 link count 공간 + +#### 계산 장점 +1. 단순성 + - 이미 계산된 required_size 활용 + - 복잡한 link count 계산 불필요 + - 실수 가능성 감소 + +2. 효율성 + - 중복 계산 제거 + - 코드 가독성 향상 + - 유지보수 용이 + +### Axis 삭제 프로세스 + +#### 기본 검증 +1. 노드 유효성 검사 +2. Axis 존재 여부 확인 +3. Axis 위치 찾기 + +#### 삭제할 데이터 계산 +```c +uint bytes_to_remove = 6 + 2 + (link_count * 6); +``` +구성: +- Axis entry (6 bytes) +- Link count (2 bytes) +- Link data (6 bytes * link_count) + +#### 데이터 이동 처리 +1. 마지막 Axis인 경우 + - Axis entry만 제거 + - Axis count 감소 + +2. 중간 Axis 삭제 + - 뒤쪽 Axis 데이터를 앞으로 이동 + - 남은 Axis들의 offset 업데이트 + - Axis entry 제거 + - Axis count 감소 + +#### 최적화 포인트 +1. 메모리 관리 + - Resize 불필요 (데이터 감소) + - 한 번의 memmove로 데이터 이동 + - 불필요한 메모리 할당 없음 + +2. 데이터 이동 + - 정확한 이동 크기 계산 + - 효율적인 데이터 이동 + - Offset 정확한 업데이트 + +3. 파일 동기화 + - 변경된 데이터만 저장 + - 단일 파일 쓰기 작업 + +#### 에러 처리 +1. 입력 검증 + - 유효하지 않은 노드 + - 존재하지 않는 Axis + - 파일 I/O 오류 + +2. 반환 값 + - AXIS_SUCCESS: 삭제 성공 + - AXIS_ERROR: 삭제 실패 \ No newline at end of file diff --git a/system-documents/cli-interface.md b/system-documents/cli-interface.md index ebf0bbe..868e28a 100644 --- a/system-documents/cli-interface.md +++ b/system-documents/cli-interface.md @@ -261,6 +261,51 @@ Error: Node indices must be between 0 and 255 Error: Link not found ``` +### Test Commands + +#### Run All Tests +``` +run-tests +``` +Executes all available test cases in the system. + +Parameters: None + +Example: +``` +> run-tests +Running all tests... +Testing axis creation... +✓ Successfully created forward axis +... +All tests completed. Total failed tests: 0 +``` + +#### Test Resize Functionality +``` +test-resize +``` +Runs specific tests for resize_node_space functionality. + +Parameters: None + +Example: +``` +> test-resize +Testing resize_node_space functionality... +✓ Correct number of initial free blocks +... +Resize node space tests completed: 0 failed +``` + +Error handling: +``` +> test-resize something +Error: Invalid arguments +Usage: test-resize +Example: test-resize +``` + ## Error Handling ### Missing Arguments diff --git a/system-documents/free-space-management.md b/system-documents/free-space-management.md index cf001b2..46d1fb8 100644 --- a/system-documents/free-space-management.md +++ b/system-documents/free-space-management.md @@ -32,8 +32,17 @@ uchar* resize_node_space(uchar* node, uint required_size, int node_index, uint* 2. Free Space에서 적절한 블록 검색 3. 새로운 메모리 할당 4. 데이터 복사 -5. 이전 공간 Free Space에 반환 -6. CoreMap 업데이트 +5. 오프셋 관리 + ```c + // 올바른 순서 + long old_offset = CoreMap[node_index].file_offset; // 기존 오프셋 저장 + CoreMap[node_index].file_offset = free_block->offset; // 새 오프셋 설정 + add_free_block(current_size, old_offset); // 기존 공간 반환 + ``` + +6. 메모리 정리 + - 할당된 FreeBlock 해제 + - 이전 노드 메모리 해제 #### Parameters - node: 현재 노드 데이터 @@ -45,12 +54,72 @@ uchar* resize_node_space(uchar* node, uint required_size, int node_index, uint* - 성공: 새로운 노드 데이터 포인터 - 실패: NULL +#### 주의사항 +1. 오프셋 관리 + - CoreMap 업데이트 전 기존 오프셋 저장 + - 올바른 오프셋으로 free space 추가 + - 데이터 일관성 유지 + +2. 메모리 관리 + - FreeBlock 메모리 누수 방지 + - 적절한 시점의 메모리 해제 + ### Free Block Management ```c FreeBlock* find_free_block(uint size); void add_free_block(uint size, long offset); ``` +#### Find and Get Free Block +```c +FreeBlock* find_and_get_free_block(uint size); +``` + +##### Process +1. Block 검색 + - 요청된 크기와 일치하는 block 찾기 + - blocks 배열 순차 검색 + +2. Block 반환 및 제거 + - 찾은 block 정보 복사 + - free space list에서 제거 + - 메모리 재할당 + +##### 반환 값 +- 성공: 할당된 FreeBlock 포인터 +- 실패: NULL + +##### 메모리 관리 +1. 반환 Block + - 새로운 메모리 할당 + - block 정보 복사 + - 호출자가 메모리 해제 책임 + +2. Free Space 관리 + - blocks 배열 크기 조정 + - 빈 공간 제거 + - 메모리 최적화 + +##### 사용 예시 +```c +FreeBlock* block = find_and_get_free_block(required_size); +if (block) { + // Use the block + // ... + free(block); // Don't forget to free +} +``` + +##### 주의사항 +1. 메모리 관리 + - 반환된 block은 사용 후 반드시 해제 + - free space 메모리 관리 + - 메모리 누수 방지 + +2. 동기화 + - free space 정보 갱신 + - 파일 저장 고려 + ### Free Index Management ```c int get_free_index(); @@ -120,4 +189,65 @@ Free Node Indices: - Monitor available space - Debug memory allocation - Track node deletion -- Verify space reclamation \ No newline at end of file +- Verify space reclamation + +## Testing + +### Resize Node Space Testing +The resize_node_space functionality is tested through a series of operations that verify proper free space management: + +#### Test Setup +1. Create multiple axes in node 0 + ```shell + create-axis 0 0 1 + create-axis 0 0 2 + create-axis 0 0 3 + ``` + This generates initial free blocks: + - 16 bytes at offset 0x00000000 + - 32 bytes at offset 0x00001000 + +#### Test Scenario +1. Initial State Verification + - Confirms presence of two free blocks + - Verifies correct block sizes + +2. Resize Trigger + - Creates axis in node 1 + - Forces node resize using 32-byte free block + - Original 16-byte node space returns to free space + +3. Final State Verification + - Checks for two 16-byte free blocks + - Verifies proper reuse of free blocks + - Confirms correct free space management + +#### Expected Results +Initial Free Space: +``` +Free Blocks: +Size (bytes) Offset +------------ ------ +16 0x00000000 +32 0x00001000 +``` + +Final Free Space: +``` +Free Blocks: +Size (bytes) Offset +------------ ------ +16 0x00000000 +16 0x00000010 +``` + +#### Test Implementation +```c +int test_resize_node_space(void); +``` +- Verifies free block allocation +- Checks free space reclamation +- Validates block size tracking +- Confirms offset management + +[Rest of the document remains unchanged...] \ No newline at end of file diff --git a/system-documents/initialization.md b/system-documents/initialization.md index 3c2bfee..eea4806 100644 --- a/system-documents/initialization.md +++ b/system-documents/initialization.md @@ -89,6 +89,59 @@ int main() { } ``` +## Testing + +### Test Commands +The following commands are available for testing: + +1. Run All Tests +```shell +run-tests +``` +Executes all available test cases including: +- Axis creation tests +- Resize node space tests +- Reports total number of failed tests + +2. Test Resize Functionality +```shell +test-resize +``` +Specifically tests the resize_node_space functionality: +- Creates initial test conditions +- Verifies free space management +- Checks block allocation and reuse +- Reports test results + +### Test Output Format +Tests provide detailed feedback: +``` +Running test: [test name] +✓ Passed: [success description] +✗ Failed: [failure description] +``` + +### Example Usage +```shell +> run-tests +Running all tests... +Testing axis creation... +✓ Successfully created forward axis +✓ Successfully created backward axis +... +Testing resize_node_space functionality... +✓ Correct number of initial free blocks +... +All tests completed. Total failed tests: 0 + +> test-resize +Testing resize_node_space functionality... +✓ Correct number of initial free blocks +✓ Successfully created axis triggering resize +... +Resize node space tests completed: 0 failed +``` + ## Implementation Details ### Key Functions