Skip to content

Commit 8c9853c

Browse files
committed
Merge branch 'master' into 5.x
# Conflicts: # version.xcconfig
2 parents 5e60490 + b8f3a4c commit 8c9853c

Some content is hidden

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

68 files changed

+40941
-40
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
Carthage/Build
22
gh-pages
33
/.build
4+
xcuserdata
5+
.DS_Store

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
language: objective-c
2-
osx_image: xcode8
2+
osx_image: xcode8.2
33
script:
44
- xcrun xcodebuild -project BTree.xcodeproj -scheme BTree-macOS test
55
- xcrun xcodebuild -project BTree.xcodeproj -scheme BTree-iOS

BTree.podspec

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
Pod::Spec.new do |spec|
22
spec.name = 'BTree'
3-
spec.version = '4.0.1'
3+
spec.version = '4.0.2'
44
spec.osx.deployment_target = "10.9"
55
spec.ios.deployment_target = "8.0"
66
spec.tvos.deployment_target = "9.0"
77
spec.watchos.deployment_target = "2.0"
8-
spec.summary = 'In-memory B-trees and ordered collections in Swift'
8+
spec.summary = 'Fast ordered collections for Swift using in-memory B-trees'
99
spec.author = 'Károly Lőrentey'
1010
spec.homepage = 'https://github.com/lorentey/BTree'
1111
spec.license = { :type => 'MIT', :file => 'LICENSE.md' }
12-
spec.source = { :git => 'https://github.com/lorentey/BTree.git', :tag => 'v4.0.1' }
12+
spec.source = { :git => 'https://github.com/lorentey/BTree.git',
13+
:tag => 'v' + String(spec.version) }
1314
spec.source_files = 'Sources/*.swift'
1415
spec.social_media_url = 'https://twitter.com/lorentey'
1516
spec.documentation_url = 'http://lorentey.github.io/BTree/api/'

BTree.xcodeproj/project.pbxproj

+9-5
Original file line numberDiff line numberDiff line change
@@ -573,7 +573,7 @@
573573
isa = PBXProject;
574574
attributes = {
575575
LastSwiftUpdateCheck = 0820;
576-
LastUpgradeCheck = 0810;
576+
LastUpgradeCheck = 0820;
577577
ORGANIZATIONNAME = "Károly Lőrentey";
578578
TargetAttributes = {
579579
BB338C841DD27D2F00BB401D = {
@@ -1236,6 +1236,7 @@
12361236
isa = XCBuildConfiguration;
12371237
buildSettings = {
12381238
APPLICATION_EXTENSION_API_ONLY = YES;
1239+
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
12391240
DEFINES_MODULE = YES;
12401241
DYLIB_INSTALL_NAME_BASE = "@rpath";
12411242
INFOPLIST_FILE = Sources/Info.plist;
@@ -1253,6 +1254,7 @@
12531254
isa = XCBuildConfiguration;
12541255
buildSettings = {
12551256
APPLICATION_EXTENSION_API_ONLY = YES;
1257+
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
12561258
DEFINES_MODULE = YES;
12571259
DYLIB_INSTALL_NAME_BASE = "@rpath";
12581260
INFOPLIST_FILE = Sources/Info.plist;
@@ -1270,6 +1272,7 @@
12701272
isa = XCBuildConfiguration;
12711273
buildSettings = {
12721274
APPLICATION_EXTENSION_API_ONLY = YES;
1275+
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
12731276
DEFINES_MODULE = YES;
12741277
DYLIB_INSTALL_NAME_BASE = "@rpath";
12751278
INFOPLIST_FILE = Sources/Info.plist;
@@ -1287,6 +1290,7 @@
12871290
isa = XCBuildConfiguration;
12881291
buildSettings = {
12891292
APPLICATION_EXTENSION_API_ONLY = YES;
1293+
"CODE_SIGN_IDENTITY[sdk=watchos*]" = "";
12901294
DEFINES_MODULE = YES;
12911295
DYLIB_INSTALL_NAME_BASE = "@rpath";
12921296
INFOPLIST_FILE = Sources/Info.plist;
@@ -1304,7 +1308,7 @@
13041308
isa = XCBuildConfiguration;
13051309
buildSettings = {
13061310
APPLICATION_EXTENSION_API_ONLY = YES;
1307-
CURRENT_PROJECT_VERSION = 1;
1311+
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
13081312
DEFINES_MODULE = YES;
13091313
DYLIB_INSTALL_NAME_BASE = "@rpath";
13101314
INFOPLIST_FILE = Sources/Info.plist;
@@ -1323,7 +1327,7 @@
13231327
isa = XCBuildConfiguration;
13241328
buildSettings = {
13251329
APPLICATION_EXTENSION_API_ONLY = YES;
1326-
CURRENT_PROJECT_VERSION = 1;
1330+
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
13271331
DEFINES_MODULE = YES;
13281332
DYLIB_INSTALL_NAME_BASE = "@rpath";
13291333
INFOPLIST_FILE = Sources/Info.plist;
@@ -1342,7 +1346,7 @@
13421346
isa = XCBuildConfiguration;
13431347
buildSettings = {
13441348
APPLICATION_EXTENSION_API_ONLY = YES;
1345-
CURRENT_PROJECT_VERSION = 1;
1349+
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
13461350
DEFINES_MODULE = YES;
13471351
DYLIB_INSTALL_NAME_BASE = "@rpath";
13481352
INFOPLIST_FILE = Sources/Info.plist;
@@ -1361,7 +1365,7 @@
13611365
isa = XCBuildConfiguration;
13621366
buildSettings = {
13631367
APPLICATION_EXTENSION_API_ONLY = YES;
1364-
CURRENT_PROJECT_VERSION = 1;
1368+
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
13651369
DEFINES_MODULE = YES;
13661370
DYLIB_INSTALL_NAME_BASE = "@rpath";
13671371
INFOPLIST_FILE = Sources/Info.plist;

BTree.xcodeproj/xcshareddata/xcschemes/BTree-iOS.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0810"
3+
LastUpgradeVersion = "0820"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

BTree.xcodeproj/xcshareddata/xcschemes/BTree-macOS.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0810"
3+
LastUpgradeVersion = "0820"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

BTree.xcodeproj/xcshareddata/xcschemes/BTree-tvOS.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0810"
3+
LastUpgradeVersion = "0820"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

BTree.xcodeproj/xcshareddata/xcschemes/BTree-watchOS.xcscheme

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<Scheme
3-
LastUpgradeVersion = "0810"
3+
LastUpgradeVersion = "0820"
44
version = "1.3">
55
<BuildAction
66
parallelizeBuildables = "YES"

CHANGELOG.md

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
1-
# Unreleased changes on master
1+
# 4.0.2 (2017-02-07)
22

3-
- [Issue #5][issue5]: Add a benchmark suite
3+
This release contains the following changes:
4+
5+
- BTree now compiles in Swift 3.1.
6+
- [Issue #5][issue5]: There is a new `PerformanceTests` target in the Xcode project containing some simple benchmarks. This facility is experimental and may be replaced later.
7+
- (Xcode project) The macOS deployment target was corrected to 10.9. Previously it was set at 10.11 by mistake.
8+
- (Xcode project) The build number is now correctly set in the tvOS framework.
9+
- (Xcode project) Code signing has been disabled, following Xcode 8 best practices.
10+
11+
[issue5]: https://github.com/lorentey/BTree/issues/5
412

513
# 4.0.1 (2016-11-08)
614

README.md

+25-12
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
# Fast Ordered Collections for Swift<br> Using In-Memory B-Trees
1+
# Fast Sorted Collections for Swift<br>Using In-Memory B-Trees
22

33
[![Swift 3.0](https://img.shields.io/badge/Swift-3.0-blue.svg)](https://swift.org)
44
[![License](https://img.shields.io/badge/licence-MIT-blue.svg)](https://github.com/lorentey/BTree/blob/master/LICENSE.md)
55
[![Platform](https://img.shields.io/badge/platforms-macOS%20∙%20iOS%20∙%20watchOS%20∙%20tvOS-blue.svg)](https://developer.apple.com/platforms/)
66

77
[![Build Status](https://travis-ci.org/lorentey/BTree.svg?branch=master)](https://travis-ci.org/lorentey/BTree)
88
[![Code Coverage](https://codecov.io/github/lorentey/BTree/coverage.svg?branch=master)](https://codecov.io/github/lorentey/BTree?branch=master)
9-
[![Documented](https://img.shields.io/cocoapods/metrics/doc-percent/BTree.svg)](http://lorentey.github.io/BTree/api)
109

1110
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage)
1211
[![CocoaPod Version](https://img.shields.io/cocoapods/v/BTree.svg)](http://cocoapods.org/pods/BTree)
@@ -15,6 +14,7 @@
1514

1615
* [Overview](#overview)
1716
* [Reference Documentation](#api)
17+
* [Optimizing Collections: The Book](#book)
1818
* [What Are B-Trees?](#what)
1919
* [Why In-Memory B-Trees?](#why)
2020
* [Laundry List of Issues with Standard Collection Types](#boo)
@@ -25,9 +25,9 @@
2525
### <a name="overview">Overview</a>
2626

2727
This project provides an efficient in-memory B-tree implementation in pure Swift, and several useful
28-
ordered collection types that use B-trees for their underlying storage.
28+
sorted collection types that use B-trees for their underlying storage.
2929

30-
- [`Map<Key, Value>`][Map] implements an ordered mapping from unique comparable keys to arbitrary values.
30+
- [`Map<Key, Value>`][Map] implements a sorted mapping from unique comparable keys to arbitrary values.
3131
It is like `Dictionary` in the standard library, but it does not require keys to be hashable,
3232
it has strong guarantees on worst-case performance, and it maintains its elements in a well-defined
3333
order.
@@ -40,13 +40,13 @@ ordered collection types that use B-trees for their underlying storage.
4040
removal of any subrange of elements, or extraction of an arbitrary sub-list are also
4141
operations with O(log(*n*)) complexity.
4242

43-
- [`SortedSet<Element>`][SortedSet] implements an ordered collection of unique comparable elements.
43+
- [`SortedSet<Element>`][SortedSet] implements a sorted collection of unique comparable elements.
4444
It is like `Set` in the standard library, but lookup, insertion and removal of any element
4545
has logarithmic complexity. Elements in an `SortedSet` are kept sorted in ascending order.
4646
Operations working on full sets (such as taking the union, intersection or difference)
4747
can take as little as O(log(*n*)) time if the elements in the source sets aren't interleaved.
4848

49-
- [`SortedBag<Element>`][SortedBag] implements an ordered [multiset][multiset] with
49+
- [`SortedBag<Element>`][SortedBag] implements a sorted [multiset][multiset] with
5050
comparable elements. This is a generalization of a set that allows multiple instances of the same value.
5151
(The standard library does not include such a collection, although you can use a dictionary to emulate one
5252
by storing the multiplicities of the keys as values.)
@@ -55,7 +55,7 @@ ordered collection types that use B-trees for their underlying storage.
5555
`SortedBag` operations have the same time complexities as the equivalent operations in `SortedSet`.
5656

5757
- [`BTree<Key, Value>`][BTree] is the underlying primitive collection that serves as base storage
58-
for all of the above collections. It is a general key-value store with full support
58+
for all of the above collections. It is a general sorted key-value store with full support
5959
for elements with duplicate keys; it provides a sum of all operations individually provided
6060
by the higher-level abstractions above (and more!).
6161

@@ -82,9 +82,22 @@ embedded in its source code.
8282

8383
[doc]: http://lorentey.github.io/BTree/api
8484

85+
### <a name="book">[Optimizing Collections: The Book][OptimizingCollections]</a>
86+
87+
If you want to learn more about how this package works, the book
88+
[Optimizing Collections][OptimizingCollections] includes detailed explanations of
89+
many of the algorithms and optimization tricks implemented by this package – and so, so much more.
90+
It is written by the same author, and published by the fine folks at objc.io.
91+
Buying a copy of the book is not only a nice way to support this project, it also gets you something quite interesting to read.
92+
Win-win!
93+
94+
[![Optimizing Collections (eBook)](docs/images/OptimizingCollections.png)][OptimizingCollections]
95+
96+
[OptimizingCollections]: https://www.objc.io/books/optimizing-collections/
97+
8598
### <a name="what">What Are B-Trees?</a>
8699

87-
[B-trees][B-tree wiki] are search trees that provide an ordered key-value store with excellent performance
100+
[B-trees][B-tree wiki] are search trees that provide a sorted key-value store with excellent performance
88101
characteristics. In essence, each node maintains a sorted array of its own elements, and
89102
another array for its children. The tree is kept balanced by three constraints:
90103

@@ -98,7 +111,7 @@ B-trees have huge nodes: nodes often contain hundreds (or even thousands) of key
98111
This module implements a "vanilla" B-tree where every node contains full key-value pairs.
99112
(The other popular type is the [B+-tree][b-plus tree] where only leaf nodes contain values;
100113
internal nodes contain only copies of keys.
101-
This often makes more sense on an external storage device with a fixed block size, but it is less useful for
114+
This often makes more sense on an external storage device with a fixed block size, but it seems less useful for
102115
an in-memory implementation.)
103116

104117
Each node in the tree also maintains the count of all elements under it.
@@ -144,7 +157,7 @@ For example, using a single array to hold a sorted list of items has quite horri
144157
complexity when there are many elements. However, up to a certain maximum size, a simple array is in fact
145158
the most efficient way to represent a sorted list.
146159

147-
![Typical benchmark results for ordered collections](http://lorentey.github.io/BTree/images/Ordered%20Collections%20in%20Swift.png)
160+
![Typical benchmark results for sorted collections](docs/images/Sorted%20Collections%20in%20Swift.png)
148161

149162
The benchmark above demonstrates this really well: insertion of *n* elements into a sorted array
150163
costs O(n^2) when there are many items, but for many reasonably sized data sets, it is still much faster
@@ -225,7 +238,7 @@ is fiddling around with loading pointer values and dereferencing them.
225238
So it makes perfect sense to employ B-trees as an in-memory data structure.
226239

227240
Think about this, though: how many times do you need to work with a hundred thousand
228-
ordered items in a typical app? Or even twenty thousand? Or even just two thousand? The most interesting
241+
sorted items in a typical app? Or even twenty thousand? Or even just two thousand? The most interesting
229242
benefits of B-trees often occur at element counts well over a hundred thousand.
230243
However, B-trees are not much slower than arrays for low element counts (remember, they *are* arrays in that
231244
case), so it makes sense to use them when there's even a slight chance that the count will get large.
@@ -486,7 +499,7 @@ Let's enumerate:
486499
[BTree.unsorted-load]: http://lorentey.github.io/BTree/api/Structs/BTree.html#/s:FV5BTree5BTreecuRd__s8SequenceWd__8Iterator7Element_zTxq__rFTqd__14dropDuplicatesSb5orderSi_GS0_xq__
487500

488501
- The package contains O(log(n)) methods to [extract a range of elements as a new B-tree][BTree.subtree]
489-
and to [insert a B-tree into another B-tree][BTreeCursor.insertTree]. (Keys need to remain ordered
502+
and to [insert a B-tree into another B-tree][BTreeCursor.insertTree]. (Keys need to remain sorted
490503
correctly, though.)
491504

492505
- Merge operations (such as [`BTree.union`][BTree.union] and [`BTree.symmetricDifference`)][BTree.symmetricDifference]

Sources/BTreeIndex.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ internal struct BTreeWeakPath<Key: Comparable, Value>: BTreePath {
120120
expectValid(_root.value === root)
121121
}
122122

123-
internal func expectValid(_ expression: @autoclosure (Void) -> Bool, file: StaticString = #file, line: UInt = #line) {
123+
internal func expectValid(_ expression: @autoclosure () -> Bool, file: StaticString = #file, line: UInt = #line) {
124124
precondition(expression(), "Invalid BTreeIndex", file: file, line: line)
125125
}
126126

Sources/Map.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ extension Map: BidirectionalCollection {
106106
public typealias Index = BTreeIndex<Key, Value>
107107
public typealias Iterator = BTreeIterator<Key, Value>
108108
public typealias Element = (Key, Value)
109+
public typealias _Element = Element // For _IndexableBase
109110
public typealias SubSequence = Map<Key, Value>
110111

111112
/// The index of the first element when non-empty. Otherwise the same as `endIndex`.
@@ -424,7 +425,6 @@ extension Map {
424425
/// Remove all (key, value) pairs in the specified offset range.
425426
///
426427
/// - Complexity: O(log(`count`))
427-
@discardableResult
428428
public mutating func remove(atOffsets offsets: Range<Int>) {
429429
precondition(offsets.lowerBound >= 0 && offsets.upperBound <= count)
430430
tree.withCursor(atOffset: offsets.lowerBound) { cursor in

0 commit comments

Comments
 (0)