Skip to content

Commit

Permalink
feat: allow for custom encoder and decoders
Browse files Browse the repository at this point in the history
  • Loading branch information
emma-k-alexandra committed Dec 27, 2021
1 parent ade0991 commit e2f0d25
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 17 deletions.
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# RTree

RTree is an on-disk, [`Codable`](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types) R*-Tree.
RTree is an on-disk, [`Codable`](https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types) R\*-Tree for searching.

RTree is a port of the Rust crate [`Spade`](https://crates.io/crates/spade)'s N-Dimentional R*-Tree, modified to store the tree on disk rather than in memory.
RTree is a port of the Rust crate [`Spade`](https://crates.io/crates/spade)'s N-Dimentional R\*-Tree, modified to store the tree on disk rather than in memory. It only can perform inserts and nearest neighbor queries.

## Contents
- [Requirements](#requirements)
Expand All @@ -19,21 +19,26 @@ RTree is a port of the Rust crate [`Spade`](https://crates.io/crates/spade)'s N-

## Requirements
- Swift 5.1+
- iOS 13, watchOS 6, macOS 10.15, tvOS 15

## Installation

### Swift Package Manager
```swift
dependencies: [
.package(url: "https://github.com/emma-k-alexandra/RTree.git", from: "2.1.2")
.package(
name: "RTree",
url: "https://github.com/emma-k-alexandra/RTree.git",
from: "2.2.0"
)
]
```

## Disclaimer & Warnings
RTree performs nearest neighbor searches at the expected speed of a R*-Tree. RTree uses far more space than expected on disk, and inserts are extemely inefficient. RTree does not currently support deletion or updating of records.

## Design
This R*-Tree is designed to use exclusively Swift, and provide a general interface for doing nearest neighbor queries on N-dimensional objects.
This R\*-Tree is designed to use exclusively Swift, and provide a general interface for doing nearest neighbor queries on N-dimensional objects.

Expect to a implement your own `SpatialObject`-implementing structure and `PointN`-implementing vector type in order to use RTree. For an example, see `RTreeTests.swift` or [Usage](#usage)

Expand Down Expand Up @@ -132,7 +137,7 @@ extension Element: Equatable {
}
```

Then, I'm able to create an R*-Tree that stores `Elements` over `Point2D`:
Then, I'm able to create an R\*-Tree that stores `Elements` over `Point2D`:

```swift
var tree = try RTree<Element>(path: path)
Expand Down
33 changes: 27 additions & 6 deletions Sources/RTree/RTree.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,27 @@ where
/// The offset of the root node of this tree
private var rootOffset: UInt64 = 0

public init(path: URL, readOnly: Bool = false) throws {
let storage = try Storage<T>(path: path, readOnly: readOnly)
/// Decoder to use for elements of the tree
public var decoder = JSONDecoder()

/// Encoder to use for elements of the tree
public var encoder = JSONEncoder()

public init(
path: URL,
readOnly: Bool = false,
encoder: JSONEncoder = JSONEncoder(),
decoder: JSONDecoder = JSONDecoder()
) throws {
self.encoder = encoder
self.decoder = decoder

let storage = try Storage<T>(
path: path,
readOnly: readOnly,
encoder: encoder,
decoder: decoder
)

if storage.isEmpty() {
if readOnly {
Expand Down Expand Up @@ -162,8 +181,12 @@ extension RTree {

mutating func load() throws {
if self.storage == nil {
self.storage = try Storage<T>(path: self.path!, readOnly: self.isReadOnly)

self.storage = try Storage<T>(
path: self.path!,
readOnly: self.isReadOnly,
encoder: encoder,
decoder: decoder
)
}

self.root = try self.storage!.loadDirectoryNodeData(withOffset: self.rootOffset)
Expand Down Expand Up @@ -201,7 +224,5 @@ extension RTree: Codable {
self.rootOffset = rootNodeOffset

self.isReadOnly = false

}

}
13 changes: 10 additions & 3 deletions Sources/RTree/Storage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,25 @@ where
private var writeFile: FileHandle? = nil

/// A JSON encoder
private let encoder = JSONEncoder()
private let encoder: JSONEncoder

/// A JSON decoder
private let decoder = JSONDecoder()
private let decoder: JSONDecoder

/// Length of a 64-bit int + \n
private let lengthOfRecordSize = 19

/// Length of a 64-bit int + \n
private let rootRecordPointerSize = 19

public init(path: URL, readOnly: Bool = false) throws {
public init(
path: URL,
readOnly: Bool = false,
encoder: JSONEncoder,
decoder: JSONDecoder
) throws {
self.encoder = encoder
self.decoder = decoder
self.path = path
self.writeFilePath = URL(string: "\(path.absoluteString).tmp")!
self.readOnly = readOnly
Expand Down
4 changes: 1 addition & 3 deletions Tests/RTreeTests/RTreeTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -61,16 +61,14 @@ struct Element: SpatialObject {
typealias Point = Point2D

let point: Point
let hello = "world"
var hello = "world"

func minimumBoundingRectangle() -> BoundingRectangle<Point2D> {
BoundingRectangle(lower: self.point, upper: self.point)

}

func distanceSquared(point: Point2D) -> Double {
pow(point.x - self.point.x, 2) + pow(point.y - self.point.y, 2)

}

}
Expand Down

0 comments on commit e2f0d25

Please sign in to comment.