Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 24 additions & 13 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,10 @@ make quick # Quick test (clean + build + test)
```

3. **Make changes**
- C++ code: `cpp/prtree.h`, `cpp/main.cc`
- Python wrapper: `src/python_prtree/__init__.py`
- Tests: `tests/test_PRTree.py`
- C++ core: `include/prtree/core/prtree.h`
- Python bindings: `src/cpp/bindings/python_bindings.cc`
- Python wrapper: `src/python_prtree/core.py`
- Tests: `tests/unit/`, `tests/integration/`, `tests/e2e/`

4. **Build and test**
```bash
Expand Down Expand Up @@ -144,7 +145,7 @@ make quick # Quick test (clean + build + test)

3. **Implement feature**
```cpp
// cpp/prtree.h
// include/prtree/core/prtree.h
// Add implementation
```

Expand Down Expand Up @@ -205,20 +206,30 @@ make test-coverage

```
python_prtree/
├── cpp/ # C++ implementation
│ ├── prtree.h # PRTree core implementation
│ ├── main.cc # Python bindings
│ ├── parallel.h # Parallel processing utilities
│ └── small_vector.h # Optimized vector
├── src/python_prtree/ # Python wrapper
│ └── __init__.py
├── include/ # C++ public headers
│ └── prtree/
│ ├── core/ # Core algorithm headers
│ │ └── prtree.h # PRTree core implementation
│ └── utils/ # Utility headers
│ ├── parallel.h # Parallel processing utilities
│ └── small_vector.h # Optimized vector
├── src/
│ ├── cpp/ # C++ implementation
│ │ └── bindings/ # Python bindings
│ │ └── python_bindings.cc
│ └── python_prtree/ # Python wrapper
│ ├── __init__.py # Package entry point
│ └── core.py # Main user-facing classes
├── tests/ # Test suite
│ └── test_PRTree.py
│ ├── unit/ # Unit tests
│ ├── integration/ # Integration tests
│ └── e2e/ # End-to-end tests
├── third/ # Third-party libraries (submodules)
│ ├── pybind11/
│ └── snappy/
├── CMakeLists.txt # CMake configuration
├── setup.py # Packaging configuration
├── pyproject.toml # Project metadata and dependencies
├── setup.py # Build configuration
├── Makefile # Development workflow
└── README.md # User documentation
```
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ PIP := $(PYTHON) -m pip

# Project directories
SRC_DIR := src/python_prtree
CPP_DIR := cpp
CPP_DIR := src/cpp
TEST_DIR := tests
BUILD_DIR := build
DIST_DIR := dist
Expand Down
114 changes: 87 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ tree4d = PRTree4D(indices, boxes_4d) # 4D boxes
```python
# Query with point coordinates
result = tree.query([0.5, 0.5]) # Returns indices
result = tree.query(0.5, 0.5) # Varargs also supported (2D only)
result = tree.query(0.5, 0.5) # Varargs also supported
```

### Dynamic Updates
Expand Down Expand Up @@ -178,24 +178,38 @@ The library supports native float32 and float64 precision with automatic selecti
- **Auto-detection**: Precision automatically selected based on numpy array dtype
- **Save/Load**: Precision automatically detected when loading from file

Advanced precision control available:
```python
# Configure precision parameters for challenging cases
tree = PRTree2D(indices, boxes)
tree.set_adaptive_epsilon(True) # Adaptive epsilon based on box sizes
tree.set_relative_epsilon(1e-6) # Relative epsilon for intersection tests
tree.set_absolute_epsilon(1e-12) # Absolute epsilon for near-zero cases
tree.set_subnormal_detection(True) # Handle subnormal numbers correctly
```

The new architecture eliminates the previous float32 tree + refinement approach,
providing true native precision at each level for better performance and accuracy.

### Thread Safety

- Query operations are thread-safe
- Insert/erase operations are NOT thread-safe
- Use external synchronization for concurrent updates
**Read Operations (Thread-Safe):**
- `query()` and `batch_query()` are thread-safe when used concurrently from multiple threads
- Multiple threads can safely perform read operations simultaneously
- No external synchronization needed for concurrent queries

**Write Operations (Require Synchronization):**
- `insert()`, `erase()`, and `rebuild()` modify the tree structure
- These operations use internal mutex locks for atomicity
- **Important**: Do NOT perform write operations concurrently with read operations
- Use external synchronization (locks) to prevent concurrent reads and writes

**Recommended Pattern:**
```python
import threading

tree = PRTree2D([1, 2], [[0, 0, 1, 1], [2, 2, 3, 3]])
lock = threading.Lock()

# Multiple threads can query safely without locks
def query_worker():
result = tree.query([0.5, 0.5, 1.5, 1.5]) # Safe without lock

# Write operations need external synchronization
def insert_worker(idx, box):
with lock: # Protect against concurrent reads/writes
tree.insert(idx, box)
```

## Installation from Source

Expand All @@ -216,22 +230,68 @@ For detailed development setup, see [DEVELOPMENT.md](docs/DEVELOPMENT.md).

#### Constructor
```python
PRTree2D(indices=None, boxes=None)
PRTree2D(filename) # Load from file
PRTree2D() # Empty tree
PRTree2D(indices, boxes) # With data
PRTree2D(filename) # Load from file
```

**Parameters:**
- `indices` (optional): Array of integer indices for each bounding box
- `boxes` (optional): Array of bounding boxes (shape: [n, 2*D] where D is dimension)
- `filename` (optional): Path to saved tree file

#### Methods
- `query(box, return_obj=False)` - Find overlapping boxes
- `batch_query(boxes)` - Parallel batch queries
- `query_intersections()` - Find all intersecting pairs
- `insert(idx, bb, obj=None)` - Add box
- `erase(idx)` - Remove box
- `rebuild()` - Rebuild tree for optimal performance
- `save(filename)` - Save to binary file
- `load(filename)` - Load from binary file
- `size()` - Get number of boxes
- `get_obj(idx)` - Get stored object
- `set_obj(idx, obj)` - Update stored object

**Query Methods:**
- `query(*args, return_obj=False)` → `List[int]` or `List[Any]`
- Find all bounding boxes that overlap with the query box or point
- Accepts box coordinates as list/array or varargs (e.g., `query(x, y)` for 2D points)
- Set `return_obj=True` to return associated objects instead of indices

- `batch_query(boxes)` → `List[List[int]]`
- Parallel batch queries for multiple query boxes
- Returns a list of result lists, one per query

- `query_intersections()` → `np.ndarray`
- Find all pairs of intersecting bounding boxes
- Returns array of shape (n_pairs, 2) containing index pairs

**Modification Methods:**
- `insert(idx=None, bb=None, obj=None)` → `None`
- Add a new bounding box to the tree
- `idx`: Index for the box (auto-assigned if None)
- `bb`: Bounding box coordinates (required)
- `obj`: Optional Python object to associate with the box

- `erase(idx)` → `None`
- Remove a bounding box by index

- `rebuild()` → `None`
- Rebuild tree for optimal performance after many updates

**Persistence Methods:**
- `save(filename)` → `None`
- Save tree to binary file

- `load(filename)` → `None`
- Load tree from binary file

**Object Storage Methods:**
- `get_obj(idx)` → `Any`
- Retrieve the Python object associated with a bounding box

- `set_obj(idx, obj)` → `None`
- Update the Python object associated with a bounding box

**Size and Properties:**
- `size()` → `int`
- Get the number of bounding boxes in the tree

- `len(tree)` → `int`
- Same as `size()`, allows using `len(tree)`

- `n` → `int` (property)
- Get the number of bounding boxes (same as `size()`)

## Version History

Expand Down
13 changes: 6 additions & 7 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,15 @@ python_prtree/
│ ├── e2e/ # End-to-end tests
│ │ ├── test_readme_examples.py
│ │ └── test_user_workflows.py
│ ├── legacy/ # Legacy test suite
│ └── conftest.py # Shared test fixtures
├── benchmarks/ # Performance Benchmarks
│ ├── cpp/ # C++ benchmarks
│ │ ├── benchmark_construction.cpp
│ │ ├── benchmark_query.cpp
│ │ ├── benchmark_parallel.cpp
│ │ └── stress_test_concurrent.cpp
│ └── python/ # Python benchmarks (future)
│ └── README.md
│ └── cpp/ # C++ benchmarks
│ ├── benchmark_construction.cpp
│ ├── benchmark_query.cpp
│ ├── benchmark_parallel.cpp
│ └── stress_test_concurrent.cpp
├── docs/ # Documentation
│ ├── examples/ # Example notebooks and scripts
Expand Down
12 changes: 5 additions & 7 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@ python_prtree/
│ ├── integration/ # Integration tests
│ └── e2e/ # End-to-end tests
├── benchmarks/ # Performance benchmarks
│ ├── cpp/ # C++ benchmarks
│ └── python/ # Python benchmarks
│ └── cpp/ # C++ benchmarks
├── docs/ # Documentation
│ ├── examples/ # Example code
│ ├── images/ # Images
Expand Down Expand Up @@ -198,7 +197,6 @@ All project metadata and dependencies are defined in `pyproject.toml`:
- `tests/unit/`: Unit tests for individual components
- `tests/integration/`: Tests for component interactions
- `tests/e2e/`: End-to-end workflow tests
- `tests/legacy/`: Legacy test suite

### Writing Tests

Expand Down Expand Up @@ -343,9 +341,9 @@ pip install -e .

## Additional Resources

- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution guidelines
- [README.md](README.md) - Project overview
- [CHANGES.md](CHANGES.md) - Version history
- [CONTRIBUTING.md](../CONTRIBUTING.md) - Contribution guidelines
- [README.md](../README.md) - Project overview
- [CHANGES.md](../CHANGES.md) - Version history
- [GitHub Issues](https://github.com/atksh/python_prtree/issues) - Bug reports and feature requests

## Questions?
Expand All @@ -354,6 +352,6 @@ If you have questions or need help, please:

1. Check existing [GitHub Issues](https://github.com/atksh/python_prtree/issues)
2. Open a new issue with your question
3. See [CONTRIBUTING.md](CONTRIBUTING.md) for more details
3. See [CONTRIBUTING.md](../CONTRIBUTING.md) for more details

Happy coding! 🎉
64 changes: 64 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Documentation Directory

This directory contains comprehensive documentation for python_prtree developers and contributors.

## Contents

### Core Documentation

- **[ARCHITECTURE.md](ARCHITECTURE.md)** - Project architecture and design decisions
- Directory structure and separation of concerns
- Data flow diagrams
- Build system overview
- Native precision support architecture

- **[DEVELOPMENT.md](DEVELOPMENT.md)** - Development environment setup
- Prerequisites and installation
- Build instructions
- Testing and code quality tools
- Troubleshooting guide

- **[MIGRATION.md](MIGRATION.md)** - Migration guides between versions
- v0.7.0 project restructuring guide
- Breaking changes and migration steps
- Planned future migrations

### Supplementary Resources

- **baseline/** - Performance baseline measurements
- System information
- Benchmark results and analysis
- Used for regression testing and performance comparison

- **examples/** - Example notebooks and scripts
- Experimental notebooks for exploring the API
- Usage demonstrations
- Prototyping and development examples

- **images/** - Documentation images
- Benchmark graphs used in README
- Performance comparison charts
- Referenced by main documentation

## For Users

If you're a user looking for usage documentation, see:
- [README.md](../README.md) - Main user documentation with examples
- [CONTRIBUTING.md](../CONTRIBUTING.md) - How to contribute to the project
- [CHANGES.md](../CHANGES.md) - Version history and changelog

## For Developers

Start with these files in order:
1. [README.md](../README.md) - Understand what the library does
2. [DEVELOPMENT.md](DEVELOPMENT.md) - Set up your development environment
3. [ARCHITECTURE.md](ARCHITECTURE.md) - Understand the codebase structure
4. [CONTRIBUTING.md](../CONTRIBUTING.md) - Learn the contribution workflow

## Keeping Documentation Updated

When making changes:
- Update ARCHITECTURE.md if you change the project structure
- Update DEVELOPMENT.md if you change build/test processes
- Update MIGRATION.md when introducing breaking changes
- Regenerate benchmarks if performance characteristics change
Loading