Releases: attaswift/BTree
4.1.0
This release updates the project to Swift 4 with no functional changes.
BTree is now part of the Attaswift project. The bundle identifiers in the supplied Xcode project have been updated accordingly.
Note that the URL for the package's Git repository has changed; please update your references.
v4.0.2
This release contains the following changes:
- BTree now compiles in Swift 3.1.
- Issue #5: There is a new
PerformanceTeststarget in the Xcode project containing some simple benchmarks. This facility is experimental and may be replaced later. - (Xcode project) The macOS deployment target was corrected to 10.9. Previously it was set at 10.11 by mistake.
- (Xcode project) The build number is now correctly set in the tvOS framework.
- (Xcode project) Code signing has been disabled, following Xcode 8 best practices.
v4.0.1
v4.0.0
This is a major release incorporating API-breaking changes. It also includes fixes for several high-severity bugs uncovered while working on new features, so this is a highly recommended upgrade.
Breaking changes
- To support multiset operations, some of
BTree's methods have grown a new required parameter specifying the key matching strategy. To get the original behavior, specify.groupingMatchesas the matching strategy, except forunion, as noted below. The compiler will provide fixits, but you'll still need to update the code by hand. This affects the following methods:BTree.isSubset(of:)BTree.isStrictSubset(of:)BTree.isSuperset(of:)BTree.isStrictSuperset(of:)BTree.union(:)-- use the.countingMatchesstrategy to get the original, multiset-appropriate, behavior.BTree.distinctUnion(:)-- removed; useunionwith the.groupingMatchesstrategy instead.BTree.subtracting(:)(both overloads)BTree.intersection(:)(both overloads)BTree.symmetricDifference(:)
New Features
SortedBagis a new generic collection implementing an ordered multiset.BTreeMatchingStrategyis a new public enum for selecting one of two matching strategies when comparing elements from two trees with duplicate keys.BTree.index(forInserting:at:)is a new method that returns the index at which a new element with the given key would be inserted into the tree.SortedSet.indexOfFirstElement(after:)is a new method that finds the lowest index whose key is greater than the specified key.SortedSet.indexOfFirstElement(notBefore:)is a new method that finds the lowest index whose key is greater than or equal to the specified key.SortedSet.indexOfLastElement(before:)is a new method that finds the greatest index whose key is less than the specified key.SortedSet.indexOfLastElement(notAfter:)is a new method that finds the greatest index whose key is less than or equal to the specified key.
Bug Fixes
- Issue #19: BTree concatenation, set operations sometimes corrupt their input trees
- Issue #20: Corrupt BTree merge results when duplicate keys leak across common subtree boundaries
- Issue #21: BTree comparisons (subset/superset) may assert on certain shared subtrees
SortedSet.update(with:)now has a discardable result.
v3.1.0
This is a feature release extending the functionality of SortedSet and Map with several new methods.
New Features
SortedSet
Offset-based access
SortedSet.offset(of:)returns the offset to a particular member of the set.SortedSet.remove(atOffset:)removes and returns the element at a particular offset in the set.
Range-based operations
SortedSet.count(elementsIn:)returns the number of elements in the given open or closed range.SortedSet.intersection(elementsIn:)returns the result of intersecting the set with a given open or closed range.SortedSet.formIntersection(elementsIn:)is the in-place editing version of the above.SortedSet.subtracting(elementsIn:)returns a set without members in the given open or closed range.SortedSet.subtract(elementsIn:)is the in-place editing version of the previous method.
Shifting
SortedSet.shift(startingAt start: Element, by delta: Element.Stride)is a new method for sorted sets with strideable elements. It addsdeltato every element in the set that is greater than or equal tostart. The elements are modified in place.
All of these new methods run in logarithmic time, except for shift whose complexity is linear.
Map
Map.offset(of:)is a new method for finding the offset of a particular key in the map. It has logarithmic complexity.
Bug fixes
- The tvOS target now generates a framework that is explicitly restricted to only use extension-safe API.
v3.0.0
This release of BTree provides support for Swift 3.0, which involves extensive breaking API changes.
- All API names have been reviewed and renamed to follow current Swift guidelines. (See SE-0023, SE-0005, SE-0006, SE-0118, and possibly others.) The resulting changes are too numerous to list here. Unfortunately, resource constraints prevented me from including forwarding availability declarations for renamed APIs; fixits won't be available, you'll have to rename usages in your code by hand. (Sorry about that.)
- BTree's collection types now implement the new collection model described in SE-0065.
BTreeIndexhas been stripped of its public methods; use the new index manipulation methods in the various collection types instead. The underlying implementation hasn't been changed, but making the standalone index methods internal now allows for experimentation with more efficient indices without breaking API changes in the future. OrderedSetwas renamed toSortedSet, to prevent confusion with the similar class in Foundation. For a short while, SE-0086 renamedNSOrderedSettoOrderedSetin the Foundation framework, leading to a naming conflict withBTree. This was further aggravated by a naming lookup issue in the language itself that made it impossible to use the explicit nameBTree.OrderedSetto work around the conflict.NSOrderedSetwas quickly changed back to its original name, but the issue revealed that the two names are much too similar.SortedSetwas adapted to implement the newSetAlgebraprotocol in SE-0059.Lists that contain objects now have anarrayViewproperty that returns anNSArraywith the exact same values as theListin O(1) time. This is useful for using B-tree based lists in APIs that need arrays, without copying elements. (For example, you can now useNSCoderto encodeLists directly.)- Collection protocol conformance has been improved.
Listnow explicitly conforms toRandomAccessCollection, whileMapandSortedSetare nowBidirectionalCollections. This required no major changes as these types already implemented everything that was necessary for conformance to these stricter protocols, but now conformance is made explicit.
v3.0.0-rc.1
This release of BTree provides support for Swift 3.0, which involves extensive breaking API changes.
- All API names have been reviewed and renamed to follow current Swift guidelines. (See SE-0023, SE-0005, SE-0006, SE-0118, and possibly others.) The resulting changes are too numerous to list here. Unfortunately, resource constraints prevented me from including forwarding availability declarations for renamed APIs; fixits won't be available, you'll have to rename usages in your code by hand. (Sorry about that.)
- BTree's collection types now implement the new collection model described in SE-0065.
BTreeIndexhas been stripped of its public methods; use the new index manipulation methods in the various collection types instead. The underlying implementation hasn't been changed, but making the standalone index methods internal now allows for experimentation with more efficient indices without breaking API changes in the future. OrderedSetwas renamed toSortedSet, to prevent confusion with the similar class in Foundation. For a short while, SE-0086 renamedNSOrderedSettoOrderedSetin the Foundation framework, leading to a naming conflict withBTree. This was further aggravated by a naming lookup issue in the language itself that made it impossible to use the explicit nameBTree.OrderedSetto work around the conflict.NSOrderedSetwas quickly changed back to its original name, but the issue revealed that the two names are much too similar.SortedSetwas adapted to implement the newSetAlgebraprotocol in SE-0059.Lists that contain objects now have anarrayViewproperty that returns anNSArraywith the exact same values as theListin O(1) time. This is useful for using B-tree based lists in APIs that need arrays, without copying elements. (For example, you can now useNSCoderto encodeLists directly.)
v2.1.0
v2.0.0
This is a major release that includes breaking API changes, plus major new features and bug fixes.
The package now implements all major features that were on my initial roadmap; further development will likely concentrate on refining the API, improving performance and adapting the package to new Swift versions. (Although it is never too late to propose new features!)
This release supports Swift 2.1.1.
Swift 2.2 is conditionally supported; add -DSwift22 to the Swift compiler flags to enable it. Note that this version of the module will compile with a number of warnings on 2.2; these will be fixed when Swift 2.2 is released.
Swift 3 is not yet supported. In particular, API names mostly follow Swift 2 conventions, although certain internal APIs are following the new design conventions.
New Features
General
- The README has been rewritten and greatly expanded in scope. It now includes a short intro and a detailed rationale section.
- The term "position" has been systematically replaced with "offset" throughout the entire API and documentation.
BTree
- The second component of
BTree's elements has been renamed from "payload" to "value" throughout the entire API and documentation. This is for consistency with other Swift key-value collections. BTreenow includes efficient set operations:union,distinctUnion,subtract,exclusiveOr, andintersect. These are based on keys, and exploit the order of elements to detect when they can skip elementwise processing for specific subtrees.subtractandintersectalso have overloads for selecting for keys contained in a sorted sequence.BTreenow supports efficient tree comparison operations:elementsEqual,isDisjointWith,isSubsetOf,isStrictSubsetOf,isSupersetOf, andisStrictSupersetOf. All of these except the first work like set comparisons on the keys of the tree. They exploit the element order and detect shared nodes to skip over subtrees whenever possible. WhenValueisEquatable, you can now compare B-trees for equality using the==operator.BTreeKeySelectornow includes anAftercase, which selects first the element that has a key that is larger than the specified key. This is occasionally useful.BTreenow defines explicit overrides for the following methods onSequenceType:prefix,suffix,prefixUpTo,prefixThrough,suffixFrom,dropLast,dropFirst,first,last,popFirst,popLast,removeFirstandremoveLast.
The new implementations perform better than the default, index-based implementations provided byCollectionType. There are also new overloads for key-based slicing.BTreegained methods for starting a generator at any specific key, index or offset.- The
withCursorfamily of methods now allow their closure to return a value. BTree.remove(:)now returns the full element that was removed, not just the value component.- Bulk loading initializers of
BTreenow respect the original order of elements, and optionally allow filtering out elements with duplicate keys. When initializing aMapfrom a sequence that contains duplicates, only the last element is kept for any key. - New methods:
BTree.removeAtIndex(:), andBTree.removeAll() BTreeIndexnow contains efficient O(log(n)) implementations foradvancedByanddistanceTo, replacing their default O(n) variants.BTreeIndexis nowComparable. However, comparing indices only makes sense if the indices belong to the same tree.BTreeCursornow has anelementproperty that allows you to get or update the entire (key, value) pair at the current position.
OrderedSet
OrderedSetis a new general-use wrapper aroundBTree, implementing a sorted analogue ofSet.
List
- The generator type of
Listhas been renamed fromListGeneratortoBTreeValueGenerator. Listexplicitly implementsRangeReplaceableCollectionType.- You can now use
+to concatenate twoListvalues, just like you can withArrays.
Map
Mapnow supportselementsEqual, complete with an==operator when itsValueisEquatable.Mapgained two methods for offset-based removal of elements:removeAtOffsetandremoveAtOffsets- You can now merge two
Mapvalues into a single map usingmerge. - You can extract a submap from a
Mapthat includes or excludes a specific set or sequence of keys.
Improvements
- Navigation inside the B-tree is now unified under a single protocol,
BTreePath, for all three flavors of tree paths:BTreeStrongPath,BTreeWeakPathandBTreeCursorPath. - The complexity of
BTree.endIndexhas been reduced from O(log(n)) to O(1). This also improves theendIndexproperties ofMapandOrderedSet. - Iterating over B-trees is now a bit faster, as getting to the successor of an item does not normally involve array lookups.
BTree.shiftSlotsis a new internal method for shifting elements between nodes at the same level. This operation is often useful while reorganizing/rebalancing the tree.- The bulk loading algorithm has been extracted into a separate internal struct and generalized to allow appending full trees, not just elements.
- The generated docs now include nice method group headers splitting the method lists into organized chunks.
Bug fixes
- Fixed issue #3, "Crash when inserting Element in List".
- The copy-on-write semantics of
BTree.withCursor(at: Index)have been fixed. BTreenow never allows its arrays to get larger than their specified order. (Previously,BTree.joincould allow arrays to grow twice the maximum size, leading to wasted capacity.)
v1.1.0
This is a feature release that includes the following changes:
New features
BTree,ListandMapare now their own subsequences. This makes slicing them much more convenient.BTreenow includes a family ofsubtree()methods to create subtrees based on index, position or key ranges.Mapnow includes a family ofsubmap()methods to create subtrees based on index, position or key ranges.BTreeCursor.moveToKey(key, choosing: selector)is a new method for repositioning a cursor at a specific key.BTreeCursor.removeAll()is a new method for removing all elements.BTreeCursor.removeAllBefore(includingCurrent:)is a new method that removes all elements before the current position.BTreeCursor.removeAllAfter(includingCurrent:)is a new method that removes all elements after the current position.BTree.withCursorAt(index)is a new method that allows you to create a cursor positioned at an index. (Note that it doesn't make sense to reposition a cursor that's already been created, since creating a cursor invalidates existing indices.)
Improvements
- The default tree order is now based on the full element size, not just the size of the key (like in 1.0.0). The maximum node size has been bumped to 16kiB to compensate for this.
BTreeIndexnow includes the slot number for each node on its path, making navigation a bit faster.- Position-based searches now start at the end of the tree if the position we're looking for is likely closer to the end than the start. This is a potential 2x improvement.
BTree.indexOfPositionnow accepts the element count as a position, returning the tree's end index.
Other changes
BTreeCursor.insertBeforehas been renamed toinsert.BTreeCursor.isValidis not a public property anymore; invalid cursors aren't supposed to leak to correct programs.- There is now a shared tvOS scheme in the Xcode project. D'oh.
- All public APIs are now documented.
@warn_unused_resultattributes have been added for APIs that need them.