Skip to content

Commit 2450001

Browse files
authored
Merge pull request #20 from rxdu/enhancement-code_refactoring
Enhancement code refactoring
2 parents 4a8b86d + 8ad8547 commit 2450001

File tree

94 files changed

+18990
-1795
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+18990
-1795
lines changed

.github/workflows/ci.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ jobs:
1616
# The type of runner that the job will run on
1717
strategy:
1818
matrix:
19-
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
19+
os: [ubuntu-24.04, ubuntu-22.04]
2020
runs-on: ${{ matrix.os }}
2121
steps:
2222
# Checks-out your repository under $GITHUB_WORKSPACE
@@ -31,7 +31,7 @@ jobs:
3131
# The type of runner that the job will run on
3232
strategy:
3333
matrix:
34-
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
34+
os: [ubuntu-24.04, ubuntu-22.04]
3535
runs-on: ${{ matrix.os }}
3636
steps:
3737
# Checks-out your repository under $GITHUB_WORKSPACE
@@ -48,7 +48,7 @@ jobs:
4848
if: matrix.os == 'ubuntu-24.04'
4949
run: |
5050
/usr/bin/lcov --directory ./build --capture --output-file ./build/coverage.info \
51-
--rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch
51+
--rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch,negative
5252
/usr/bin/lcov --ignore-errors unused -remove ./build/coverage.info \
5353
"/usr/*" \
5454
"*/tests/*" \

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
performance_results
2+
13
# Temp files
24
*/Debug
35
build/

CLAUDE.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Project Overview
6+
7+
libgraph is a modern, header-only C++11 library for graph construction and pathfinding algorithms. It provides high-performance graph operations with thread-safe concurrent searches and support for generic cost types. The library implements a Graph class using an adjacency list representation with O(m+n) space complexity and provides a unified search framework with A*, Dijkstra, BFS, and DFS algorithms.
8+
9+
## Build Commands
10+
11+
### Basic Build
12+
```bash
13+
mkdir build && cd build
14+
cmake ..
15+
cmake --build .
16+
```
17+
18+
### Build with Tests
19+
```bash
20+
mkdir build && cd build
21+
cmake -DBUILD_TESTING=ON ..
22+
cmake --build .
23+
```
24+
25+
### Build with Coverage
26+
```bash
27+
mkdir build && cd build
28+
cmake -DBUILD_TESTING=ON -DCOVERAGE_CHECK=ON ..
29+
cmake --build .
30+
```
31+
32+
### Run Tests
33+
```bash
34+
cd build
35+
make test
36+
# or run directly
37+
./bin/utests
38+
```
39+
40+
### Generate Documentation
41+
```bash
42+
cd docs
43+
doxygen doxygen/Doxyfile
44+
```
45+
46+
### Create Installation Package
47+
```bash
48+
cd build
49+
cpack # Creates .deb package
50+
```
51+
52+
## Code Architecture
53+
54+
### Core Components
55+
56+
The library is organized around three main template classes in the `xmotion` namespace:
57+
58+
1. **Graph<State, Transition, StateIndexer>** (`src/include/graph/graph.hpp`)
59+
- Main graph class using adjacency list representation
60+
- Uses `std::unordered_map<int64_t, Vertex*>` for vertex storage
61+
- Each vertex contains `std::list<Edge>` for edges
62+
- Supports directed and undirected graphs
63+
- Provides vertex/edge iterators for traversal
64+
65+
2. **Tree<State, Transition, StateIndexer>** (`src/include/graph/tree.hpp`)
66+
- Specialized graph structure for tree representations
67+
- Enforces tree properties (single parent, no cycles)
68+
69+
3. **Search Algorithms** (`src/include/graph/search/`)
70+
- `AStar`: A* pathfinding with custom heuristics
71+
- `Dijkstra`: Shortest path algorithm for weighted graphs
72+
- `BFS`: Breadth-first search for unweighted shortest paths
73+
- `DFS`: Depth-first search for graph traversal
74+
- All algorithms use unified framework with `SearchContext` for thread-safe concurrent searches
75+
- Dynamic priority queue implementation for efficient priority updates
76+
77+
### State Indexing System
78+
79+
The library uses a StateIndexer functor to generate unique indices for graph vertices:
80+
- **DefaultIndexer** (`src/include/graph/impl/default_indexer.hpp`): Automatically works with states that have `GetId()`, `id_`, or `id`
81+
- Custom indexers can be defined by implementing `operator()(State)` returning `int64_t`
82+
83+
### Priority Queue Implementation
84+
85+
The search algorithms rely on specialized priority queues:
86+
- **PriorityQueue** (`src/include/graph/impl/priority_queue.hpp`): Basic priority queue
87+
- **DynamicPriorityQueue** (`src/include/graph/impl/dynamic_priority_queue.hpp`): Supports priority updates, crucial for efficient graph searches
88+
89+
## Testing Structure
90+
91+
- **Unit Tests** (`tests/unit_test/`): Core functionality tests using Google Test
92+
- Graph construction, modification, iteration
93+
- Search algorithm correctness
94+
- Priority queue operations
95+
- Tree operations
96+
- **Development Tests** (`tests/devel_test/`): Performance and specialized tests
97+
98+
## Important Implementation Details
99+
100+
- The library is header-only; all implementation is in `.hpp` files
101+
- Graph vertices are stored as pointers in an unordered_map for O(1) average access
102+
- Edge lists use std::list for O(1) insertion
103+
- The library exports as `xmotion::graph` when installed via CMake
104+
- Namespace `xmotion` is used throughout to avoid naming conflicts
105+
- Thread-safe concurrent searches using external `SearchContext`
106+
- Support for custom cost types with `CostTraits` specialization
107+
- RAII memory management with `std::unique_ptr` for exception safety
108+
- Modern C++ design patterns including CRTP for zero-overhead polymorphism
109+
110+
## Documentation Structure
111+
112+
### Core Documentation (docs/)
113+
- **getting_started.md**: 20-minute tutorial from installation to first working graph
114+
- **api.md**: Complete API reference covering all 21 header files
115+
- **architecture.md**: In-depth system design, template patterns, and implementation details
116+
- **advanced_features.md**: Custom costs, thread safety, performance optimization
117+
- **search_algorithms.md**: Comprehensive guide to A*, Dijkstra, BFS, DFS with examples
118+
- **real_world_examples.md**: Industry applications across gaming, robotics, GPS, networks
119+
120+
### Tutorial Series (docs/tutorials/)
121+
- Progressive learning path from basic to advanced usage
122+
- Hands-on examples with complete working code
123+
- **01-basic-graph.md**: Fundamental operations
124+
- **02-pathfinding.md**: Search algorithms
125+
- **03-state-types.md**: Custom states and indexing
126+
127+
### Supporting Documentation
128+
- **README.md**: Professional project overview with quick start
129+
- **index.md**: Documentation homepage for Doxygen integration
130+
- **doxygen/mainpage.md**: Main page for API documentation
131+
132+
## Documentation Standards
133+
134+
### File Naming Convention
135+
- Use **underscores** for documentation files (e.g., `getting_started.md`, `advanced_features.md`)
136+
- Maintain consistency across all documentation links
137+
138+
### Content Guidelines
139+
- **Professional tone**: No emojis or casual language in technical documentation
140+
- **Complete code examples**: All code snippets must be compilable and working
141+
- **Progressive complexity**: Start simple, build to advanced concepts
142+
- **Real-world focus**: Emphasize practical applications and use cases
143+
- **Performance awareness**: Include complexity analysis and optimization guidance
144+
145+
### Cross-Reference Standards
146+
- Link to related sections using relative paths
147+
- Maintain up-to-date cross-references between documentation files
148+
- Include file:line_number references for code locations when relevant
149+
150+
## Sample Code Structure
151+
152+
### Working Examples (sample/)
153+
- **simple_graph_demo.cpp**: Basic graph construction and pathfinding
154+
- **thread_safe_search_demo.cpp**: Concurrent search demonstrations
155+
- **lexicographic_cost_demo.cpp**: Multi-criteria optimization with custom cost types
156+
- **tuple_cost_demo.cpp**: std::tuple-based automatic lexicographic comparison
157+
- **incremental_search_demo.cpp**: Dynamic pathfinding scenarios
158+
159+
### Code Quality Standards
160+
- All sample code must compile and run successfully
161+
- Include comprehensive error handling and validation
162+
- Demonstrate best practices for memory management and thread safety
163+
- Provide clear comments explaining design decisions and usage patterns

CMakeLists.txt

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,34 @@ project(graph VERSION 2.0.3)
33

44
## Project Options
55
option(BUILD_TESTING "Build tests" OFF)
6+
option(BUILD_SAMPLES "Build samples" ON)
67
option(STATIC_CHECK "Perform static check" OFF)
78
option(COVERAGE_CHECK "Perform coverage check" OFF)
89

910
# sanity check of the options
10-
if(COVERAGE_CHECK)
11-
set(BUILD_TESTING ON)
12-
endif()
11+
if (COVERAGE_CHECK)
12+
set(BUILD_TESTING ON)
13+
endif ()
1314

1415
## generate symbols for IDE indexer
1516
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1617

17-
if(STATIC_CHECK)
18-
find_program(CPPCHECK cppcheck)
19-
if(CPPCHECK)
20-
message(STATUS "Found cppcheck")
21-
set(CMAKE_CXX_CPPCHECK cppcheck;--std=c++11;--enable=all)
22-
endif()
23-
endif()
24-
25-
if(COVERAGE_CHECK)
26-
find_program(GCOV gcov)
27-
if(GCOV)
28-
message(STATUS "Found gcov")
29-
set(CMAKE_BUILD_TYPE Debug)
30-
set(CMAKE_CXX_FLAGS "-g -O0 -Wall -fprofile-arcs -ftest-coverage")
31-
endif()
32-
endif()
18+
if (STATIC_CHECK)
19+
find_program(CPPCHECK cppcheck)
20+
if (CPPCHECK)
21+
message(STATUS "Found cppcheck")
22+
set(CMAKE_CXX_CPPCHECK cppcheck;--std=c++11;--enable=all)
23+
endif ()
24+
endif ()
25+
26+
if (COVERAGE_CHECK)
27+
find_program(GCOV gcov)
28+
if (GCOV)
29+
message(STATUS "Found gcov")
30+
set(CMAKE_BUILD_TYPE Debug)
31+
set(CMAKE_CXX_FLAGS "-g -O0 -Wall -fprofile-arcs -ftest-coverage -fprofile-update=atomic")
32+
endif ()
33+
endif ()
3334

3435
## Additional cmake module path
3536
set(USER_CMAKE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
@@ -43,14 +44,14 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
4344

4445
## Choose build type
4546
set(default_build_type "Release")
46-
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
47+
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
4748
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
4849
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
4950
STRING "Choose the type of build." FORCE)
5051
# Set the possible values of build type for cmake-gui
5152
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
52-
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
53-
endif()
53+
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
54+
endif ()
5455
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
5556

5657
## Use GNUInstallDirs to install libraries into correct locations on all platforms.
@@ -62,18 +63,29 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}
6263
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
6364

6465
## Build library
65-
add_subdirectory(src)
66+
# Add libraries
67+
add_library(graph INTERFACE)
68+
target_compile_definitions(graph INTERFACE -DMINIMAL_PRINTOUT)
69+
target_include_directories(graph INTERFACE
70+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
71+
$<INSTALL_INTERFACE:include>)
72+
73+
if (BUILD_SAMPLES)
74+
add_subdirectory(sample)
75+
endif ()
76+
77+
# Shared_ptr support validation completed - tests integrated into main test suite
6678

6779
# Build tests
68-
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
69-
message(STATUS "Tests will be built")
70-
enable_testing()
71-
include(GoogleTest)
72-
set(BUILD_TESTS ON)
73-
add_subdirectory(tests)
74-
else()
75-
message(STATUS "Tests will not be built")
76-
endif()
80+
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
81+
message(STATUS "Tests will be built")
82+
enable_testing()
83+
include(GoogleTest)
84+
set(BUILD_TESTS ON)
85+
add_subdirectory(tests)
86+
else ()
87+
message(STATUS "Tests will not be built")
88+
endif ()
7789

7890
# Show installation path
7991
message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX} with 'make install'")
@@ -82,19 +94,19 @@ message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX} with 'make
8294
set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
8395
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
8496
set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
85-
if(WIN32 AND NOT CYGWIN)
86-
set(DEF_INSTALL_CMAKEDIR CMake)
87-
else()
88-
set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
89-
endif()
97+
if (WIN32 AND NOT CYGWIN)
98+
set(DEF_INSTALL_CMAKEDIR CMake)
99+
else ()
100+
set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
101+
endif ()
90102
set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files")
91103

92104
# Report to user
93-
foreach(p LIB BIN INCLUDE CMAKE)
94-
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path)
95-
message(STATUS " - To install ${p} components to ${_path}")
96-
unset(_path)
97-
endforeach()
105+
foreach (p LIB BIN INCLUDE CMAKE)
106+
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path)
107+
message(STATUS " - To install ${p} components to ${_path}")
108+
unset(_path)
109+
endforeach ()
98110

99111
# targets to install
100112
install(TARGETS graph
@@ -121,8 +133,8 @@ install(EXPORT graphTargets
121133

122134
configure_file(cmake/graphConfig.cmake.in graphConfig.cmake @ONLY)
123135
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/graphConfig.cmake"
124-
"${CMAKE_CURRENT_BINARY_DIR}/graphConfigVersion.cmake"
125-
DESTINATION lib/cmake/graph)
136+
"${CMAKE_CURRENT_BINARY_DIR}/graphConfigVersion.cmake"
137+
DESTINATION lib/cmake/graph)
126138

127139
# Packaging support
128140
set(CPACK_PACKAGE_VENDOR "Ruixiang Du")
@@ -136,7 +148,7 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
136148

137149
set(CPACK_GENERATOR "DEB")
138150
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
139-
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ruixiang Du ([email protected])")
151+
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ruixiang Du ([email protected])")
140152
# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libasio-dev")
141153
set(CPACK_SOURCE_IGNORE_FILES /.git /dist /.*build.* /\\\\.DS_Store)
142154
include(CPack)

0 commit comments

Comments
 (0)