Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
9dab92e
fixed a few minor issues
rxdu Aug 12, 2025
a775589
ReconstructPath(): improved impletation with loop detection
rxdu Aug 12, 2025
fe92e71
claude: added claude init and code review
rxdu Aug 12, 2025
e55667d
structure: updated code file organization
rxdu Aug 12, 2025
661815e
graph: separated vertex and edge classes from graph class
rxdu Aug 13, 2025
4dab7a7
renamed details folder to impl
rxdu Aug 13, 2025
8c5abb7
more fixes to header inclusion, updated TODO doc
rxdu Aug 13, 2025
f405748
test: improved tests, added more test cases
rxdu Aug 13, 2025
c6dc2b1
test: added memory and thread tests
rxdu Aug 14, 2025
c1fcd51
added more tests, updated TODO
rxdu Aug 14, 2025
cf5b85b
graph: fixed assignment operator
rxdu Aug 14, 2025
e1df224
added thread safe search implementation
rxdu Aug 14, 2025
54abc55
ci: fixing coverage collection in ubuntu 24.04
rxdu Aug 14, 2025
4de93c5
graph: enhanced graph api
rxdu Aug 15, 2025
fc56ff7
graph: replaced raw pointers for vertices with unique_ptr
rxdu Aug 15, 2025
8ad30d0
implemented all items in priority 2 group
rxdu Aug 15, 2025
cd33b05
removed duplicated header inclusion
rxdu Aug 16, 2025
9cae11b
minor improvements
rxdu Aug 16, 2025
1027d23
updated search implementation
rxdu Aug 16, 2025
18900ae
graph: enhanced graph cost impl, added dfs
rxdu Aug 16, 2025
6e5fc01
test: added performance test setup
rxdu Aug 16, 2025
94d8b79
improvements to dynamic priority queue
rxdu Aug 17, 2025
03bdc59
optimization on search context
rxdu Aug 17, 2025
5f660fa
improved error handling
rxdu Aug 17, 2025
c87af8b
improved iterator
rxdu Aug 17, 2025
b356835
enhanced search context with attribute system
rxdu Aug 17, 2025
8a124a4
improved search context and removed legacy fields
rxdu Aug 17, 2025
9995c3e
search: updated cost type handling
rxdu Aug 17, 2025
2dbec49
implemented custom transition comparator support
rxdu Aug 18, 2025
3dcbc99
code cleanup, updated tests and samples
rxdu Aug 18, 2025
00f497b
updated documentation
rxdu Aug 18, 2025
738a035
more documentation and sample code improvements
rxdu Aug 18, 2025
b418d9a
updated TODO.md
rxdu Aug 18, 2025
5b3df9d
googletest: upgraded to 1.17.0
rxdu Aug 19, 2025
6bbcf08
cleanup: minor cleanup on search algorithm alias names
rxdu Aug 19, 2025
958c727
tree: updatd tree implementation
rxdu Aug 19, 2025
d8e0d68
fixed a few minor inconsistencies
rxdu Aug 19, 2025
befb323
fixed inconsistencies in size() related functions
rxdu Aug 19, 2025
8ad8547
enhanced a few test implementations to address code review
rxdu Aug 19, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
# The type of runner that the job will run on
strategy:
matrix:
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
os: [ubuntu-24.04, ubuntu-22.04]
runs-on: ${{ matrix.os }}
steps:
# Checks-out your repository under $GITHUB_WORKSPACE
Expand All @@ -31,7 +31,7 @@ jobs:
# The type of runner that the job will run on
strategy:
matrix:
os: [ubuntu-24.04, ubuntu-22.04, ubuntu-20.04]
os: [ubuntu-24.04, ubuntu-22.04]
runs-on: ${{ matrix.os }}
steps:
# Checks-out your repository under $GITHUB_WORKSPACE
Expand All @@ -48,7 +48,7 @@ jobs:
if: matrix.os == 'ubuntu-24.04'
run: |
/usr/bin/lcov --directory ./build --capture --output-file ./build/coverage.info \
--rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch
--rc geninfo_unexecuted_blocks=1 --ignore-errors mismatch,negative
/usr/bin/lcov --ignore-errors unused -remove ./build/coverage.info \
"/usr/*" \
"*/tests/*" \
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
performance_results

# Temp files
*/Debug
build/
Expand Down
163 changes: 163 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

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.

## Build Commands

### Basic Build
```bash
mkdir build && cd build
cmake ..
cmake --build .
```

### Build with Tests
```bash
mkdir build && cd build
cmake -DBUILD_TESTING=ON ..
cmake --build .
```

### Build with Coverage
```bash
mkdir build && cd build
cmake -DBUILD_TESTING=ON -DCOVERAGE_CHECK=ON ..
cmake --build .
```

### Run Tests
```bash
cd build
make test
# or run directly
./bin/utests
```

### Generate Documentation
```bash
cd docs
doxygen doxygen/Doxyfile
```

### Create Installation Package
```bash
cd build
cpack # Creates .deb package
```

## Code Architecture

### Core Components

The library is organized around three main template classes in the `xmotion` namespace:

1. **Graph<State, Transition, StateIndexer>** (`src/include/graph/graph.hpp`)
- Main graph class using adjacency list representation
- Uses `std::unordered_map<int64_t, Vertex*>` for vertex storage
- Each vertex contains `std::list<Edge>` for edges
- Supports directed and undirected graphs
- Provides vertex/edge iterators for traversal

2. **Tree<State, Transition, StateIndexer>** (`src/include/graph/tree.hpp`)
- Specialized graph structure for tree representations
- Enforces tree properties (single parent, no cycles)

3. **Search Algorithms** (`src/include/graph/search/`)
- `AStar`: A* pathfinding with custom heuristics
- `Dijkstra`: Shortest path algorithm for weighted graphs
- `BFS`: Breadth-first search for unweighted shortest paths
- `DFS`: Depth-first search for graph traversal
- All algorithms use unified framework with `SearchContext` for thread-safe concurrent searches
- Dynamic priority queue implementation for efficient priority updates

### State Indexing System

The library uses a StateIndexer functor to generate unique indices for graph vertices:
- **DefaultIndexer** (`src/include/graph/impl/default_indexer.hpp`): Automatically works with states that have `GetId()`, `id_`, or `id`
- Custom indexers can be defined by implementing `operator()(State)` returning `int64_t`

### Priority Queue Implementation

The search algorithms rely on specialized priority queues:
- **PriorityQueue** (`src/include/graph/impl/priority_queue.hpp`): Basic priority queue
- **DynamicPriorityQueue** (`src/include/graph/impl/dynamic_priority_queue.hpp`): Supports priority updates, crucial for efficient graph searches

## Testing Structure

- **Unit Tests** (`tests/unit_test/`): Core functionality tests using Google Test
- Graph construction, modification, iteration
- Search algorithm correctness
- Priority queue operations
- Tree operations
- **Development Tests** (`tests/devel_test/`): Performance and specialized tests

## Important Implementation Details

- The library is header-only; all implementation is in `.hpp` files
- Graph vertices are stored as pointers in an unordered_map for O(1) average access
- Edge lists use std::list for O(1) insertion
- The library exports as `xmotion::graph` when installed via CMake
- Namespace `xmotion` is used throughout to avoid naming conflicts
- Thread-safe concurrent searches using external `SearchContext`
- Support for custom cost types with `CostTraits` specialization
- RAII memory management with `std::unique_ptr` for exception safety
- Modern C++ design patterns including CRTP for zero-overhead polymorphism

## Documentation Structure

### Core Documentation (docs/)
- **getting_started.md**: 20-minute tutorial from installation to first working graph
- **api.md**: Complete API reference covering all 21 header files
- **architecture.md**: In-depth system design, template patterns, and implementation details
- **advanced_features.md**: Custom costs, thread safety, performance optimization
- **search_algorithms.md**: Comprehensive guide to A*, Dijkstra, BFS, DFS with examples
- **real_world_examples.md**: Industry applications across gaming, robotics, GPS, networks

### Tutorial Series (docs/tutorials/)
- Progressive learning path from basic to advanced usage
- Hands-on examples with complete working code
- **01-basic-graph.md**: Fundamental operations
- **02-pathfinding.md**: Search algorithms
- **03-state-types.md**: Custom states and indexing

### Supporting Documentation
- **README.md**: Professional project overview with quick start
- **index.md**: Documentation homepage for Doxygen integration
- **doxygen/mainpage.md**: Main page for API documentation

## Documentation Standards

### File Naming Convention
- Use **underscores** for documentation files (e.g., `getting_started.md`, `advanced_features.md`)
- Maintain consistency across all documentation links

### Content Guidelines
- **Professional tone**: No emojis or casual language in technical documentation
- **Complete code examples**: All code snippets must be compilable and working
- **Progressive complexity**: Start simple, build to advanced concepts
- **Real-world focus**: Emphasize practical applications and use cases
- **Performance awareness**: Include complexity analysis and optimization guidance

### Cross-Reference Standards
- Link to related sections using relative paths
- Maintain up-to-date cross-references between documentation files
- Include file:line_number references for code locations when relevant

## Sample Code Structure

### Working Examples (sample/)
- **simple_graph_demo.cpp**: Basic graph construction and pathfinding
- **thread_safe_search_demo.cpp**: Concurrent search demonstrations
- **lexicographic_cost_demo.cpp**: Multi-criteria optimization with custom cost types
- **tuple_cost_demo.cpp**: std::tuple-based automatic lexicographic comparison
- **incremental_search_demo.cpp**: Dynamic pathfinding scenarios

### Code Quality Standards
- All sample code must compile and run successfully
- Include comprehensive error handling and validation
- Demonstrate best practices for memory management and thread safety
- Provide clear comments explaining design decisions and usage patterns
102 changes: 57 additions & 45 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,34 @@ project(graph VERSION 2.0.3)

## Project Options
option(BUILD_TESTING "Build tests" OFF)
option(BUILD_SAMPLES "Build samples" ON)
option(STATIC_CHECK "Perform static check" OFF)
option(COVERAGE_CHECK "Perform coverage check" OFF)

# sanity check of the options
if(COVERAGE_CHECK)
set(BUILD_TESTING ON)
endif()
if (COVERAGE_CHECK)
set(BUILD_TESTING ON)
endif ()

## generate symbols for IDE indexer
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if(STATIC_CHECK)
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
message(STATUS "Found cppcheck")
set(CMAKE_CXX_CPPCHECK cppcheck;--std=c++11;--enable=all)
endif()
endif()

if(COVERAGE_CHECK)
find_program(GCOV gcov)
if(GCOV)
message(STATUS "Found gcov")
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-g -O0 -Wall -fprofile-arcs -ftest-coverage")
endif()
endif()
if (STATIC_CHECK)
find_program(CPPCHECK cppcheck)
if (CPPCHECK)
message(STATUS "Found cppcheck")
set(CMAKE_CXX_CPPCHECK cppcheck;--std=c++11;--enable=all)
endif ()
endif ()

if (COVERAGE_CHECK)
find_program(GCOV gcov)
if (GCOV)
message(STATUS "Found gcov")
set(CMAKE_BUILD_TYPE Debug)
set(CMAKE_CXX_FLAGS "-g -O0 -Wall -fprofile-arcs -ftest-coverage -fprofile-update=atomic")
endif ()
endif ()

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

## Choose build type
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to '${default_build_type}' as none was specified.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif ()
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")

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

## Build library
add_subdirectory(src)
# Add libraries
add_library(graph INTERFACE)
target_compile_definitions(graph INTERFACE -DMINIMAL_PRINTOUT)
target_include_directories(graph INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)

if (BUILD_SAMPLES)
add_subdirectory(sample)
endif ()

# Shared_ptr support validation completed - tests integrated into main test suite

# Build tests
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
message(STATUS "Tests will be built")
enable_testing()
include(GoogleTest)
set(BUILD_TESTS ON)
add_subdirectory(tests)
else()
message(STATUS "Tests will not be built")
endif()
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME AND BUILD_TESTING)
message(STATUS "Tests will be built")
enable_testing()
include(GoogleTest)
set(BUILD_TESTS ON)
add_subdirectory(tests)
else ()
message(STATUS "Tests will not be built")
endif ()

# Show installation path
message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX} with 'make install'")
Expand All @@ -82,19 +94,19 @@ message(STATUS "Project will be installed to ${CMAKE_INSTALL_PREFIX} with 'make
set(INSTALL_LIBDIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries")
set(INSTALL_BINDIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables")
set(INSTALL_INCLUDEDIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for header files")
if(WIN32 AND NOT CYGWIN)
set(DEF_INSTALL_CMAKEDIR CMake)
else()
set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
endif()
if (WIN32 AND NOT CYGWIN)
set(DEF_INSTALL_CMAKEDIR CMake)
else ()
set(DEF_INSTALL_CMAKEDIR share/cmake/${PROJECT_NAME})
endif ()
set(INSTALL_CMAKEDIR ${DEF_INSTALL_CMAKEDIR} CACHE PATH "Installation directory for CMake files")

# Report to user
foreach(p LIB BIN INCLUDE CMAKE)
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path)
message(STATUS " - To install ${p} components to ${_path}")
unset(_path)
endforeach()
foreach (p LIB BIN INCLUDE CMAKE)
file(TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${INSTALL_${p}DIR} _path)
message(STATUS " - To install ${p} components to ${_path}")
unset(_path)
endforeach ()

# targets to install
install(TARGETS graph
Expand All @@ -121,8 +133,8 @@ install(EXPORT graphTargets

configure_file(cmake/graphConfig.cmake.in graphConfig.cmake @ONLY)
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/graphConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/graphConfigVersion.cmake"
DESTINATION lib/cmake/graph)
"${CMAKE_CURRENT_BINARY_DIR}/graphConfigVersion.cmake"
DESTINATION lib/cmake/graph)

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

set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ruixiang Du (ruixiang.du@gmail.com)")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Ruixiang Du (ruixiang.du@gmail.com)")
# set(CPACK_DEBIAN_PACKAGE_DEPENDS "libasio-dev")
set(CPACK_SOURCE_IGNORE_FILES /.git /dist /.*build.* /\\\\.DS_Store)
include(CPack)
Loading