Skip to content

Commit

Permalink
Refactor axis management and enhance testing capabilities
Browse files Browse the repository at this point in the history
- Removed obsolete function declarations and improved memory handling in `create_axis` and `delete_axis` functions.
- Introduced new test commands in the CLI for running all tests and specifically testing the `resize_node_space` functionality.
- Updated `find_free_block` to `find_and_get_free_block` for better clarity and functionality in memory management.
- Enhanced documentation to include detailed testing procedures and command usage examples, ensuring better user guidance.
- Improved error handling and validation across command handlers to streamline user interactions.
  • Loading branch information
YongHwan2161 committed Jan 8, 2025
1 parent 2071da2 commit c5bea8a
Show file tree
Hide file tree
Showing 17 changed files with 634 additions and 53 deletions.
1 change: 0 additions & 1 deletion CGDB.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Binary file modified binary-data/data.bin
Binary file not shown.
Binary file modified binary-data/free_space.bin
Binary file not shown.
Binary file modified binary-data/map.bin
Binary file not shown.
Binary file modified cgdb
Binary file not shown.
109 changes: 66 additions & 43 deletions src/axis.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
#include <stdbool.h>

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
}

Expand Down Expand Up @@ -56,34 +54,29 @@ 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)) {
printf("Error: Axis %d already exists\n", 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
Expand All @@ -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
Expand All @@ -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);
Expand All @@ -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");
Expand All @@ -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;
}

Expand All @@ -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
Expand All @@ -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;
}
41 changes: 40 additions & 1 deletion src/cli/command_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "../channel.h"
#include "../link.h"
#include "../free_space.h"
#include "../tests/axis_tests.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
Expand Down Expand Up @@ -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 <node> <channel> <axis> Create a new axis\n");
Expand All @@ -363,6 +393,8 @@ void print_help() {
printf(" delete-link <src_node> <src_ch> <dst_node> <dst_ch> <axis> Delete a link\n");
printf(" print-node <node_index> 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");
Expand All @@ -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();
Expand All @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/cli/command_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions src/database.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "database.h"
#include "init.h"
#include <string.h>

#ifdef _WIN32
Expand Down
53 changes: 49 additions & 4 deletions src/free_space.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,22 @@ 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) {
// Use found free block
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);
Expand Down Expand Up @@ -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;
}
1 change: 1 addition & 0 deletions src/free_space.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Loading

0 comments on commit c5bea8a

Please sign in to comment.