diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index 1d2ede9..7564af1 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -1,17 +1,18 @@ name: analyze on: + workflow_dispatch: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] + branches: [ main ] jobs: package-analysis: runs-on: ubuntu-latest steps: - name: Git checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4.1.1 - name: Analyze package uses: axel-op/dart-package-analyzer@stable with: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 1ea9a34..fa636f6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,27 +1,29 @@ name: build on: + workflow_dispatch: push: - branches: [ master ] + branches: [ main ] pull_request: - branches: [ master ] - + branches: [ main ] jobs: build: runs-on: ubuntu-latest container: - image: google/dart:latest + image: dart:stable steps: - name: Git checkout - uses: actions/checkout@v2 + uses: actions/checkout@v4.1.1 - name: Install dependencies - run: pub get + run: dart pub get - name: Run tests - run: pub run test + run: dart pub run test - name: Measure coverage - run: pub run test_cov + run: dart pub run test_cov - name: Upload coverage - uses: codecov/codecov-action@v1.0.6 + uses: codecov/codecov-action@v3 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} with: token: ${{secrets.CODECOV_TOKEN}} file: coverage/lcov.info diff --git a/CHANGELOG.md b/CHANGELOG.md index b669cb5..08c53a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [0.4.0] - 2023-11-20 + +* Migrated to Dart 3 (thanks @slightfoot) + ## [0.3.0] - 2021-04-22 * Migrated to null-safety (thanks @scarnett!) diff --git a/README.md b/README.md index 808ab82..cc53cb2 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,8 @@ [![pub](https://img.shields.io/pub/v/interval_tree.svg)](https://pub.dev/packages/interval_tree) [![license: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -![build](https://github.com/jpnurmi/interval_tree/workflows/build/badge.svg) -[![codecov](https://codecov.io/gh/jpnurmi/interval_tree/branch/main/graph/badge.svg)](https://codecov.io/gh/jpnurmi/interval_tree) +[![build](https://github.com/fluttercommunity/interval_tree/actions/workflows/build.yml/badge.svg)](https://github.com/fluttercommunity/interval_tree/actions/workflows/build.yml) +[![codecov](https://codecov.io/gh/fluttercommunity/interval_tree/branch/main/graph/badge.svg)](https://codecov.io/gh/fluttercommunity/interval_tree) A [Dart][1] implementation of an [interval tree][2], with support for calculating unions, intersections, and differences between individual diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..572dd23 --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1 @@ +include: package:lints/recommended.yaml diff --git a/lib/interval_tree.dart b/lib/interval_tree.dart index b4d3716..def831b 100644 --- a/lib/interval_tree.dart +++ b/lib/interval_tree.dart @@ -84,7 +84,7 @@ import 'package:quiver/collection.dart'; /// final interval = ivt.Interval(1, 2); /// @immutable -class Interval extends Comparable { +class Interval implements Comparable { /// Creates an interval between [start] and [end] points. Interval(dynamic start, dynamic end) : _start = _min(start, end), @@ -101,10 +101,6 @@ class Interval extends Comparable { /// Returns the end point of this interval. dynamic get end => _end; - /// Returns the length of this interval. - @deprecated - dynamic get length => _end - _start; - /// Returns `true` if this interval contains the [other] interval. bool contains(Interval other) => other.start >= start && other.end <= end; @@ -247,7 +243,9 @@ class Interval extends Comparable { String toString() => '[$start, $end]'; static int _cmp(dynamic a, dynamic b) => Comparable.compare(a, b); + static dynamic _min(dynamic a, dynamic b) => _cmp(a, b) < 0 ? a : b; + static dynamic _max(dynamic a, dynamic b) => _cmp(a, b) > 0 ? a : b; final dynamic _start; @@ -327,13 +325,15 @@ class IntervalTree with IterableMixin { factory IntervalTree.of(Iterable intervals) => IntervalTree()..addAll(intervals); + final _tree = AvlTreeSet(comparator: Comparable.compare); + /// Adds an [interval] into this tree. - void add(dynamic? interval) { - Interval? iv = _asInterval(interval); + void add(dynamic interval) { + var iv = _asInterval(interval); if (iv == null) return; bool joined = false; - BidirectionalIterator it = _tree.fromIterator(iv); + var it = _tree.fromIterator(iv); while (it.movePrevious()) { final union = _tryJoin(it.current, iv); if (union == null) break; @@ -365,7 +365,7 @@ class IntervalTree with IterableMixin { void remove(dynamic interval) { final iv = _asInterval(interval); - BidirectionalIterator it = _tree.fromIterator(iv!); + var it = _tree.fromIterator(iv!); while (it.movePrevious()) { final current = it.current; if (!_trySplit(it.current, iv)) break; @@ -405,7 +405,7 @@ class IntervalTree with IterableMixin { final result = IntervalTree(); if (isEmpty || other.isEmpty) result; for (final iv in other) { - BidirectionalIterator it = _tree.fromIterator(iv); + var it = _tree.fromIterator(iv); while (it.movePrevious() && iv.intersects(it.current)) { result.add(iv.intersection(it.current)); } @@ -418,15 +418,15 @@ class IntervalTree with IterableMixin { } @override - bool contains(dynamic interval) { - final iv = _asInterval(interval); - BidirectionalIterator it = _tree.fromIterator(iv!); - while (it.movePrevious() && iv.intersects(it.current!)) { - if (it.current!.contains(iv)) return true; + bool contains(Object? element) { + final iv = _asInterval(element); + var it = _tree.fromIterator(iv!); + while (it.movePrevious() && iv.intersects(it.current)) { + if (it.current.contains(iv)) return true; } it = _tree.fromIterator(iv, inclusive: false); - while (it.moveNext() && it.current!.intersects(iv)) { - if (it.current!.contains(iv)) return true; + while (it.moveNext() && it.current.intersects(iv)) { + if (it.current.contains(iv)) return true; } return false; } @@ -457,13 +457,13 @@ class IntervalTree with IterableMixin { /// Returns a bidirectional iterator that allows iterating the intervals. @override - BidirectionalIterator get iterator => _tree.iterator; + TreeIterator get iterator => _tree.iterator; /// Returns a string representation of the tree. @override - String toString() => 'IntervalTree' + super.toString(); + String toString() => 'IntervalTree${super.toString()}'; - Interval? _asInterval(dynamic? interval) { + Interval? _asInterval(dynamic interval) { if (interval is Iterable) { if (interval.length != 2 || interval.first is Iterable) { throw ArgumentError('$interval is not an interval'); @@ -490,7 +490,4 @@ class IntervalTree with IterableMixin { _tree.addAll([...?a.difference(b)]); return true; } - - final AvlTreeSet _tree = - AvlTreeSet(comparator: Comparable.compare); } diff --git a/pubspec.yaml b/pubspec.yaml index 5408dc1..f153b5d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,18 +1,21 @@ name: interval_tree -version: 0.3.0 +version: 0.4.0 description: >- A non-overlapping interval tree with support for calculating unions, intersections, and differences between individual intervals and entire trees. -homepage: https://github.com/jpnurmi/interval_tree -repository: https://github.com/jpnurmi/interval_tree -issue_tracker: https://github.com/jpnurmi/interval_tree/issues +homepage: https://github.com/fluttercommunity/interval_tree +repository: https://github.com/fluttercommunity/interval_tree +issue_tracker: https://github.com/fluttercommunity/interval_tree/issues environment: - sdk: '>=2.12.0 <3.0.0' + sdk: '>=3.0.0 <4.0.0' + dependencies: - meta: ^1.1.8 - quiver: ^3.0.1 + lints: ^3.0.0 + meta: ^1.11.0 + quiver: ^3.2.1 + dev_dependencies: - test: ^1.14.2 + test: ^1.24.3 test_cov: ^1.0.1 diff --git a/test/interval_test.dart b/test/interval_test.dart index 5f89bea..b951654 100644 --- a/test/interval_test.dart +++ b/test/interval_test.dart @@ -39,13 +39,6 @@ void main() { expect(Interval(1, -10).end, 1); }); - test('length', () { - expect(Interval(0, 0).length, 0); - expect(Interval(-1, 1).length, 2); - expect(Interval(1, 10).length, 9); - expect(Interval(1, -10).length, 11); - }); - test('copy', () { final interval = Interval(0, 10); final copy = Interval.copy(interval); diff --git a/test/interval_tree_test.dart b/test/interval_tree_test.dart index 8a564c9..262664a 100644 --- a/test/interval_tree_test.dart +++ b/test/interval_tree_test.dart @@ -1,3 +1,5 @@ +// ignore_for_file: collection_methods_unrelated_type + /* * Copyright (c) 2020 J-P Nurmi *