mirror of
https://github.com/dart-lang/sdk
synced 2024-10-01 19:14:49 +00:00
Fix analysis issues in benchmarks/ directory
Now that I'm able to open the entire SDK in VSC, I'm fixing some of the analysis issues in various files (carefully) without changing their meaning. In this case, I removed unnecessary imports from benchmarks. In regexp_benchmark I ignored one warning which likely would have changed the behavior of the code. BUG=https://github.com/dart-lang/sdk/issues/52419 Change-Id: I9a195a4e45121313bd9f065f2579a165c3fec05b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/303901 Auto-Submit: Eric Seidel <eric@shorebird.dev> Reviewed-by: William Hesse <whesse@google.com> Commit-Queue: William Hesse <whesse@google.com>
This commit is contained in:
parent
987c7a7c35
commit
4c20cedd30
|
@ -7,14 +7,14 @@ import 'dart:isolate';
|
||||||
import 'json_benchmark.dart';
|
import 'json_benchmark.dart';
|
||||||
import 'latency.dart';
|
import 'latency.dart';
|
||||||
|
|
||||||
main() async {
|
Future<void> main() async {
|
||||||
// Start GC pressure from helper isolate.
|
// Start GC pressure from helper isolate.
|
||||||
final exitPort = ReceivePort();
|
final exitPort = ReceivePort();
|
||||||
final exitFuture = exitPort.first;
|
final exitFuture = exitPort.first;
|
||||||
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
||||||
|
|
||||||
// Measure event loop latency.
|
// Measure event loop latency.
|
||||||
const tickDuration = const Duration(milliseconds: 1);
|
const tickDuration = Duration(milliseconds: 1);
|
||||||
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
||||||
final EventLoopLatencyStats stats =
|
final EventLoopLatencyStats stats =
|
||||||
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
class JsonRoundTripBenchmark {
|
class JsonRoundTripBenchmark {
|
||||||
void run() {
|
void run() {
|
||||||
|
|
|
@ -9,14 +9,14 @@ import 'dart:isolate';
|
||||||
import 'json_benchmark.dart';
|
import 'json_benchmark.dart';
|
||||||
import 'latency.dart';
|
import 'latency.dart';
|
||||||
|
|
||||||
main() async {
|
Future<void> main() async {
|
||||||
// Start GC pressure from helper isolate.
|
// Start GC pressure from helper isolate.
|
||||||
final exitPort = ReceivePort();
|
final exitPort = ReceivePort();
|
||||||
final exitFuture = exitPort.first;
|
final exitFuture = exitPort.first;
|
||||||
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
||||||
|
|
||||||
// Measure event loop latency.
|
// Measure event loop latency.
|
||||||
const tickDuration = const Duration(milliseconds: 1);
|
const tickDuration = Duration(milliseconds: 1);
|
||||||
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
||||||
final EventLoopLatencyStats stats =
|
final EventLoopLatencyStats stats =
|
||||||
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
||||||
|
|
|
@ -7,14 +7,14 @@ import 'dart:isolate';
|
||||||
import 'json_benchmark.dart';
|
import 'json_benchmark.dart';
|
||||||
import 'latency.dart';
|
import 'latency.dart';
|
||||||
|
|
||||||
main() async {
|
Future<void> main() async {
|
||||||
// Start GC pressure from helper isolate.
|
// Start GC pressure from helper isolate.
|
||||||
final exitPort = ReceivePort();
|
final exitPort = ReceivePort();
|
||||||
final exitFuture = exitPort.first;
|
final exitFuture = exitPort.first;
|
||||||
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
||||||
|
|
||||||
// Measure event loop latency.
|
// Measure event loop latency.
|
||||||
const tickDuration = const Duration(milliseconds: 1);
|
const tickDuration = Duration(milliseconds: 1);
|
||||||
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
||||||
final EventLoopLatencyStats stats =
|
final EventLoopLatencyStats stats =
|
||||||
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:math';
|
||||||
|
|
||||||
class JsonRoundTripBenchmark {
|
class JsonRoundTripBenchmark {
|
||||||
void run() {
|
void run() {
|
||||||
|
|
|
@ -4,16 +4,16 @@
|
||||||
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'regexp_benchmark.dart';
|
|
||||||
import 'latency.dart';
|
import 'latency.dart';
|
||||||
|
import 'regexp_benchmark.dart';
|
||||||
|
|
||||||
main() async {
|
Future<void> main() async {
|
||||||
final exitPort = ReceivePort();
|
final exitPort = ReceivePort();
|
||||||
final exitFuture = exitPort.first;
|
final exitFuture = exitPort.first;
|
||||||
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
final isolate = await Isolate.spawn(run, null, onExit: exitPort.sendPort);
|
||||||
|
|
||||||
// Measure event loop latency.
|
// Measure event loop latency.
|
||||||
const tickDuration = const Duration(milliseconds: 1);
|
const tickDuration = Duration(milliseconds: 1);
|
||||||
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
const numberOfTicks = 8 * 1000; // min 8 seconds.
|
||||||
final EventLoopLatencyStats stats =
|
final EventLoopLatencyStats stats =
|
||||||
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
await measureEventLoopLatency(tickDuration, numberOfTicks);
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:math';
|
|
||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
class RegexpBenchmark {
|
class RegexpBenchmark {
|
||||||
void run() {
|
void run() {
|
||||||
final re = RegExp(r'(x+)*y');
|
final re = RegExp(r'(x+)*y');
|
||||||
|
// ignore: prefer_interpolation_to_compose_strings
|
||||||
final s = 'x' * 26 + '';
|
final s = 'x' * 26 + '';
|
||||||
re.allMatches(s).iterator.moveNext();
|
re.allMatches(s).iterator.moveNext();
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,11 @@ class D<T> {
|
||||||
}
|
}
|
||||||
''');
|
''');
|
||||||
|
|
||||||
final maxCount = instantiateCounts.reduce(((v, e) => max(v, e)));
|
final maxCount = instantiateCounts.reduce(max);
|
||||||
for (int i = 0; i < maxCount; i++) {
|
for (int i = 0; i < maxCount; i++) {
|
||||||
output.write('''
|
output.write('''
|
||||||
|
|
||||||
class C${i} {}
|
class C$i {}
|
||||||
''');
|
''');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
// for details. All rights reserved. Use of this source code is governed by a
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:collection';
|
||||||
// Benchmark for https://github.com/dart-lang/sdk/issues/48641.
|
// Benchmark for https://github.com/dart-lang/sdk/issues/48641.
|
||||||
//
|
//
|
||||||
// Measures the average time needed for a lookup in Sets of integers.
|
// Measures the average time needed for a lookup in Sets of integers.
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
import 'dart:collection';
|
|
||||||
import 'package:benchmark_harness/benchmark_harness.dart';
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
||||||
|
|
||||||
class SetBenchmark extends BenchmarkBase {
|
class SetBenchmark extends BenchmarkBase {
|
||||||
|
@ -30,13 +31,13 @@ void main() {
|
||||||
final randomList = List<int>.generate(14790, (_) => r.nextInt(1 << 31));
|
final randomList = List<int>.generate(14790, (_) => r.nextInt(1 << 31));
|
||||||
|
|
||||||
final benchmarks = [
|
final benchmarks = [
|
||||||
() => SetBenchmark("IntegerSetLookup.DefaultHashSet", {...list}),
|
() => SetBenchmark('IntegerSetLookup.DefaultHashSet', {...list}),
|
||||||
() =>
|
() =>
|
||||||
SetBenchmark("IntegerSetLookup.HashSet", HashSet<int>()..addAll(list)),
|
SetBenchmark('IntegerSetLookup.HashSet', HashSet<int>()..addAll(list)),
|
||||||
() =>
|
() =>
|
||||||
SetBenchmark("IntegerSetLookup.DefaultHashSet_Random", {...randomList}),
|
SetBenchmark('IntegerSetLookup.DefaultHashSet_Random', {...randomList}),
|
||||||
() => SetBenchmark(
|
() => SetBenchmark(
|
||||||
"IntegerSetLookup.HashSet_Random", HashSet<int>()..addAll(randomList)),
|
'IntegerSetLookup.HashSet_Random', HashSet<int>()..addAll(randomList)),
|
||||||
];
|
];
|
||||||
for (final benchmark in benchmarks) {
|
for (final benchmark in benchmarks) {
|
||||||
benchmark().report();
|
benchmark().report();
|
||||||
|
|
|
@ -49,7 +49,7 @@ class SendReceiveHelper {
|
||||||
outbox.send(null);
|
outbox.send(null);
|
||||||
await workerExitedPort.first;
|
await workerExitedPort.first;
|
||||||
workerExitedPort.close();
|
workerExitedPort.close();
|
||||||
inbox.cancel();
|
await inbox.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send regexp to worker, get one back, repeat few times.
|
// Send regexp to worker, get one back, repeat few times.
|
||||||
|
@ -78,7 +78,7 @@ Future<void> isolate(SendPort sendPort) async {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// use RegExp to ensure it is compiled
|
// use RegExp to ensure it is compiled
|
||||||
RegExp re = received as RegExp;
|
final RegExp re = received as RegExp;
|
||||||
re.firstMatch('h' * 1000);
|
re.firstMatch('h' * 1000);
|
||||||
// send the RegExp
|
// send the RegExp
|
||||||
sendPort.send(re);
|
sendPort.send(re);
|
||||||
|
|
|
@ -6,13 +6,11 @@
|
||||||
// via exit/send.
|
// via exit/send.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:typed_data';
|
|
||||||
import 'dart:math' as math;
|
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
|
|
||||||
import 'latency.dart';
|
import 'latency.dart';
|
||||||
|
|
||||||
main() async {
|
Future<void> main() async {
|
||||||
final statsFuture =
|
final statsFuture =
|
||||||
measureEventLoopLatency(const Duration(milliseconds: 1), 4000, work: () {
|
measureEventLoopLatency(const Duration(milliseconds: 1), 4000, work: () {
|
||||||
// Every 1 ms we allocate some objects which may trigger GC some time.
|
// Every 1 ms we allocate some objects which may trigger GC some time.
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:io';
|
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,11 @@ import 'dart:io';
|
||||||
import 'dart:isolate';
|
import 'dart:isolate';
|
||||||
import 'dart:math' as math;
|
import 'dart:math' as math;
|
||||||
|
|
||||||
import '../../../pkg/vm/bin/gen_kernel.dart' as gen_kernel;
|
|
||||||
import 'package:vm_service/vm_service.dart' as vm_service;
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
||||||
import 'package:vm_service/vm_service_io.dart' as vm_service_io;
|
import 'package:vm_service/vm_service_io.dart' as vm_service_io;
|
||||||
|
|
||||||
|
import '../../../pkg/vm/bin/gen_kernel.dart' as gen_kernel;
|
||||||
|
|
||||||
const String compilerIsolateName = 'isolate-compiler';
|
const String compilerIsolateName = 'isolate-compiler';
|
||||||
|
|
||||||
class Result {
|
class Result {
|
||||||
|
|
|
@ -264,12 +264,12 @@ void main() {
|
||||||
setNativeResolverForTest(getRootLibraryUrl());
|
setNativeResolverForTest(getRootLibraryUrl());
|
||||||
|
|
||||||
final benchmarks = [
|
final benchmarks = [
|
||||||
() => Uint8x01(),
|
Uint8x01.new,
|
||||||
() => Int64x20(),
|
Int64x20.new,
|
||||||
() => Doublex01(),
|
Doublex01.new,
|
||||||
() => Doublex20(),
|
Doublex20.new,
|
||||||
() => Handlex01(),
|
Handlex01.new,
|
||||||
() => Handlex20(),
|
Handlex20.new,
|
||||||
];
|
];
|
||||||
for (final benchmark in benchmarks) {
|
for (final benchmark in benchmarks) {
|
||||||
benchmark().report();
|
benchmark().report();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
// Benchmark for `Object.hash` and `Object.hashAll`.
|
// Benchmark for `Object.hash` and `Object.hashAll`.
|
||||||
|
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:benchmark_harness/benchmark_harness.dart';
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
||||||
|
|
||||||
int get nextHash => Random().nextInt(0x20000000);
|
int get nextHash => Random().nextInt(0x20000000);
|
||||||
|
@ -134,11 +135,11 @@ void main() {
|
||||||
generalUses();
|
generalUses();
|
||||||
|
|
||||||
final benchmarks = [
|
final benchmarks = [
|
||||||
() => BenchmarkNode5Hash(),
|
BenchmarkNode5Hash.new,
|
||||||
() => BenchmarkNode5Manual(),
|
BenchmarkNode5Manual.new,
|
||||||
() => BenchmarkNode5List(),
|
BenchmarkNode5List.new,
|
||||||
() => BenchmarkNode5HashHashAll(),
|
BenchmarkNode5HashHashAll.new,
|
||||||
() => BenchmarkNode5ManualHashAll(),
|
BenchmarkNode5ManualHashAll.new,
|
||||||
];
|
];
|
||||||
|
|
||||||
// Warmup all benchmarks so that JIT compilers see full polymorphism before
|
// Warmup all benchmarks so that JIT compilers see full polymorphism before
|
||||||
|
|
|
@ -15,8 +15,8 @@ import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
|
||||||
as lib_BigIntParsePrint;
|
as lib_BigIntParsePrint;
|
||||||
import '../../Iterators/dart/Iterators.dart' as lib_Iterators;
|
import '../../Iterators/dart/Iterators.dart' as lib_Iterators;
|
||||||
import '../../ListCopy/dart/ListCopy.dart' as lib_ListCopy;
|
import '../../ListCopy/dart/ListCopy.dart' as lib_ListCopy;
|
||||||
import '../../MapCopy/dart/MapCopy.dart' as lib_MapCopy;
|
|
||||||
import '../../MD5/dart/md5.dart' as lib_MD5;
|
import '../../MD5/dart/md5.dart' as lib_MD5;
|
||||||
|
import '../../MapCopy/dart/MapCopy.dart' as lib_MapCopy;
|
||||||
import '../../RecordCollections/dart/RecordCollections.dart'
|
import '../../RecordCollections/dart/RecordCollections.dart'
|
||||||
as lib_RecordCollections;
|
as lib_RecordCollections;
|
||||||
import '../../RuntimeType/dart/RuntimeType.dart' as lib_RuntimeType;
|
import '../../RuntimeType/dart/RuntimeType.dart' as lib_RuntimeType;
|
||||||
|
|
|
@ -15,8 +15,8 @@ import '../../BigIntParsePrint/dart/BigIntParsePrint.dart'
|
||||||
deferred as lib_BigIntParsePrint;
|
deferred as lib_BigIntParsePrint;
|
||||||
import '../../Iterators/dart/Iterators.dart' deferred as lib_Iterators;
|
import '../../Iterators/dart/Iterators.dart' deferred as lib_Iterators;
|
||||||
import '../../ListCopy/dart/ListCopy.dart' deferred as lib_ListCopy;
|
import '../../ListCopy/dart/ListCopy.dart' deferred as lib_ListCopy;
|
||||||
import '../../MapCopy/dart/MapCopy.dart' deferred as lib_MapCopy;
|
|
||||||
import '../../MD5/dart/md5.dart' deferred as lib_MD5;
|
import '../../MD5/dart/md5.dart' deferred as lib_MD5;
|
||||||
|
import '../../MapCopy/dart/MapCopy.dart' deferred as lib_MapCopy;
|
||||||
import '../../RecordCollections/dart/RecordCollections.dart'
|
import '../../RecordCollections/dart/RecordCollections.dart'
|
||||||
deferred as lib_RecordCollections;
|
deferred as lib_RecordCollections;
|
||||||
import '../../RuntimeType/dart/RuntimeType.dart' deferred as lib_RuntimeType;
|
import '../../RuntimeType/dart/RuntimeType.dart' deferred as lib_RuntimeType;
|
||||||
|
|
|
@ -6,6 +6,7 @@ import 'dart:collection';
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:benchmark_harness/benchmark_harness.dart';
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
||||||
|
|
||||||
import 'sound_splay_tree.dart';
|
import 'sound_splay_tree.dart';
|
||||||
|
|
||||||
List<int> sieve(List<int> initialCandidates) {
|
List<int> sieve(List<int> initialCandidates) {
|
||||||
|
@ -85,7 +86,7 @@ void busyWork() {
|
||||||
exercise(M2.values);
|
exercise(M2.values);
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
void main() {
|
||||||
final benchmarks = [
|
final benchmarks = [
|
||||||
Base(sieve, 'CollectionSieves-SplayTreeSet-removeLoop'),
|
Base(sieve, 'CollectionSieves-SplayTreeSet-removeLoop'),
|
||||||
Base(sieveSound, 'CollectionSieves-SoundSplayTreeSet-removeLoop'),
|
Base(sieveSound, 'CollectionSieves-SoundSplayTreeSet-removeLoop'),
|
||||||
|
@ -105,6 +106,7 @@ class Base extends BenchmarkBase {
|
||||||
final algorithm;
|
final algorithm;
|
||||||
Base(this.algorithm, String name) : super(name);
|
Base(this.algorithm, String name) : super(name);
|
||||||
static final input = range(2, 5000);
|
static final input = range(2, 5000);
|
||||||
|
@override
|
||||||
void run() {
|
void run() {
|
||||||
final primes = algorithm(input);
|
final primes = algorithm(input);
|
||||||
if (primes.length != 669) throw 'Wrong result for $name: ${primes.length}';
|
if (primes.length != 669) throw 'Wrong result for $name: ${primes.length}';
|
||||||
|
|
|
@ -7,17 +7,18 @@ abstract class EfficientLengthIterable<T> extends Iterable<T> {
|
||||||
///
|
///
|
||||||
/// This is an efficient operation that doesn't require iterating through
|
/// This is an efficient operation that doesn't require iterating through
|
||||||
/// the elements.
|
/// the elements.
|
||||||
|
@override
|
||||||
int get length;
|
int get length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates errors throw by [Iterable] when the element count is wrong.
|
/// Creates errors throw by [Iterable] when the element count is wrong.
|
||||||
abstract class IterableElementError {
|
abstract class IterableElementError {
|
||||||
/// Error thrown by, e.g., [Iterable.first] when there is no result.
|
/// Error thrown by, e.g., [Iterable.first] when there is no result.
|
||||||
static StateError noElement() => StateError("No element");
|
static StateError noElement() => StateError('No element');
|
||||||
|
|
||||||
/// Error thrown by, e.g., [Iterable.single] if there are too many results.
|
/// Error thrown by, e.g., [Iterable.single] if there are too many results.
|
||||||
static StateError tooMany() => StateError("Too many elements");
|
static StateError tooMany() => StateError('Too many elements');
|
||||||
|
|
||||||
/// Error thrown by, e.g., [List.setRange] if there are too few elements.
|
/// Error thrown by, e.g., [List.setRange] if there are too few elements.
|
||||||
static StateError tooFew() => StateError("Too few elements");
|
static StateError tooFew() => StateError('Too few elements');
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// BSD-style license that can be found in the LICENSE file.
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
import 'dart:collection';
|
import 'dart:collection';
|
||||||
|
|
||||||
import 'iterable.dart';
|
import 'iterable.dart';
|
||||||
|
|
||||||
typedef _Predicate<T> = bool Function(T value);
|
typedef _Predicate<T> = bool Function(T value);
|
||||||
|
@ -347,7 +348,7 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
static _id(x) => x;
|
static dynamic _id(x) => x;
|
||||||
|
|
||||||
static void fillMapWithMappedIterable<K, V, E>(
|
static void fillMapWithMappedIterable<K, V, E>(
|
||||||
Map<K, V> map, Iterable<E> iterable, K Function(E element)? key, V Function(E element)? value) {
|
Map<K, V> map, Iterable<E> iterable, K Function(E element)? key, V Function(E element)? value) {
|
||||||
|
@ -360,8 +361,8 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fillMapWithIterables(Map map, Iterable keys, Iterable values) {
|
static void fillMapWithIterables(Map map, Iterable keys, Iterable values) {
|
||||||
Iterator keyIterator = keys.iterator;
|
final Iterator keyIterator = keys.iterator;
|
||||||
Iterator valueIterator = values.iterator;
|
final Iterator valueIterator = values.iterator;
|
||||||
|
|
||||||
bool hasNextKey = keyIterator.moveNext();
|
bool hasNextKey = keyIterator.moveNext();
|
||||||
bool hasNextValue = valueIterator.moveNext();
|
bool hasNextValue = valueIterator.moveNext();
|
||||||
|
@ -373,7 +374,7 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasNextKey || hasNextValue) {
|
if (hasNextKey || hasNextValue) {
|
||||||
throw ArgumentError("Iterables do not have same length.");
|
throw ArgumentError('Iterables do not have same length.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,17 +389,19 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
/// It is an error if the two [Iterable]s don't have the same length.
|
/// It is an error if the two [Iterable]s don't have the same length.
|
||||||
factory SoundSplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values,
|
factory SoundSplayTreeMap.fromIterables(Iterable<K> keys, Iterable<V> values,
|
||||||
[int Function(K key1, K key2)? compare, bool Function(Object? potentialKey)? isValidKey]) {
|
[int Function(K key1, K key2)? compare, bool Function(Object? potentialKey)? isValidKey]) {
|
||||||
SoundSplayTreeMap<K, V> map = SoundSplayTreeMap<K, V>(compare, isValidKey);
|
final SoundSplayTreeMap<K, V> map = SoundSplayTreeMap<K, V>(compare, isValidKey);
|
||||||
fillMapWithIterables(map, keys, values);
|
fillMapWithIterables(map, keys, values);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
int _compare(K key1, K key2) => _comparator(key1, key2);
|
int _compare(K key1, K key2) => _comparator(key1, key2);
|
||||||
|
|
||||||
|
@override
|
||||||
V? operator [](Object? key) {
|
V? operator [](Object? key) {
|
||||||
if (!_validKey(key)) return null;
|
if (!_validKey(key)) return null;
|
||||||
if (_root != null) {
|
if (_root != null) {
|
||||||
int comp = _splay(key as K);
|
final int comp = _splay(key as K);
|
||||||
if (comp == 0) {
|
if (comp == 0) {
|
||||||
return _root!.value;
|
return _root!.value;
|
||||||
}
|
}
|
||||||
|
@ -406,6 +409,7 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
V? remove(Object? key) {
|
V? remove(Object? key) {
|
||||||
if (!_validKey(key)) return null;
|
if (!_validKey(key)) return null;
|
||||||
final _SoundSplayTreeMapNode<K, V>? mapRoot = _remove(key as K) as _SoundSplayTreeMapNode<K, V>?;
|
final _SoundSplayTreeMapNode<K, V>? mapRoot = _remove(key as K) as _SoundSplayTreeMapNode<K, V>?;
|
||||||
|
@ -413,11 +417,12 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void operator []=(K key, V value) {
|
void operator []=(K key, V value) {
|
||||||
if (key == null) throw ArgumentError(key);
|
if (key == null) throw ArgumentError(key);
|
||||||
// Splay on the key to move the last node on the search path for
|
// Splay on the key to move the last node on the search path for
|
||||||
// the key to the root of the tree.
|
// the key to the root of the tree.
|
||||||
int comp = _splay(key);
|
final int comp = _splay(key);
|
||||||
if (comp == 0) {
|
if (comp == 0) {
|
||||||
_root!.value = value;
|
_root!.value = value;
|
||||||
return;
|
return;
|
||||||
|
@ -425,15 +430,16 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
_addNewRoot(_SoundSplayTreeMapNode<K, V>(key, value), comp);
|
_addNewRoot(_SoundSplayTreeMapNode<K, V>(key, value), comp);
|
||||||
}
|
}
|
||||||
|
|
||||||
V putIfAbsent(K key, V ifAbsent()) {
|
@override
|
||||||
|
V putIfAbsent(K key, V Function() ifAbsent) {
|
||||||
if (key == null) throw ArgumentError(key);
|
if (key == null) throw ArgumentError(key);
|
||||||
int comp = _splay(key);
|
int comp = _splay(key);
|
||||||
if (comp == 0) {
|
if (comp == 0) {
|
||||||
return _root!.value!;
|
return _root!.value!;
|
||||||
}
|
}
|
||||||
int modificationCount = _modificationCount;
|
final int modificationCount = _modificationCount;
|
||||||
int splayCount = _splayCount;
|
final int splayCount = _splayCount;
|
||||||
V value = ifAbsent();
|
final V value = ifAbsent();
|
||||||
if (modificationCount != _modificationCount) {
|
if (modificationCount != _modificationCount) {
|
||||||
throw ConcurrentModificationError(this);
|
throw ConcurrentModificationError(this);
|
||||||
}
|
}
|
||||||
|
@ -446,40 +452,48 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void addAll(Map<K, V> other) {
|
void addAll(Map<K, V> other) {
|
||||||
other.forEach((K key, V value) {
|
other.forEach((K key, V value) {
|
||||||
this[key] = value;
|
this[key] = value;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool get isEmpty {
|
bool get isEmpty {
|
||||||
return (_root == null);
|
return (_root == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool get isNotEmpty => !isEmpty;
|
bool get isNotEmpty => !isEmpty;
|
||||||
|
|
||||||
void forEach(void f(K key, V value)) {
|
@override
|
||||||
Iterator<_SoundSplayTreeNode<K>?> nodes = _SoundSplayTreeNodeIterator<K>(this);
|
void forEach(void Function(K key, V value) f) {
|
||||||
|
final Iterator<_SoundSplayTreeNode<K>?> nodes = _SoundSplayTreeNodeIterator<K>(this);
|
||||||
while (nodes.moveNext()) {
|
while (nodes.moveNext()) {
|
||||||
_SoundSplayTreeMapNode<K, V> node = nodes.current as _SoundSplayTreeMapNode<K, V>;
|
final _SoundSplayTreeMapNode<K, V> node = nodes.current as _SoundSplayTreeMapNode<K, V>;
|
||||||
f(node.key, node.value!);
|
f(node.key, node.value!);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
int get length {
|
int get length {
|
||||||
return _count;
|
return _count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void clear() {
|
void clear() {
|
||||||
_clear();
|
_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool containsKey(Object? key) {
|
bool containsKey(Object? key) {
|
||||||
return _validKey(key) && _splay(key as K) == 0;
|
return _validKey(key) && _splay(key as K) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool containsValue(Object? value) {
|
bool containsValue(Object? value) {
|
||||||
int initialSplayCount = _splayCount;
|
final int initialSplayCount = _splayCount;
|
||||||
bool visit(_SoundSplayTreeMapNode<K, V>? node) {
|
bool visit(_SoundSplayTreeMapNode<K, V>? node) {
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
if (node.value == value) return true;
|
if (node.value == value) return true;
|
||||||
|
@ -495,8 +509,10 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
return visit(_root);
|
return visit(_root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Iterable<K> get keys => _SoundSplayTreeKeyIterable<K>(this);
|
Iterable<K> get keys => _SoundSplayTreeKeyIterable<K>(this);
|
||||||
|
|
||||||
|
@override
|
||||||
Iterable<V> get values => _SoundSplayTreeValueIterable<K, V>(this);
|
Iterable<V> get values => _SoundSplayTreeValueIterable<K, V>(this);
|
||||||
|
|
||||||
/// Get the first key in the map. Returns [:null:] if the map is empty.
|
/// Get the first key in the map. Returns [:null:] if the map is empty.
|
||||||
|
@ -516,7 +532,7 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
K? lastKeyBefore(K key) {
|
K? lastKeyBefore(K key) {
|
||||||
if (key == null) throw ArgumentError(key);
|
if (key == null) throw ArgumentError(key);
|
||||||
if (_root == null) return null;
|
if (_root == null) return null;
|
||||||
int comp = _splay(key);
|
final int comp = _splay(key);
|
||||||
if (comp < 0) return _root!.key;
|
if (comp < 0) return _root!.key;
|
||||||
_SoundSplayTreeNode<K>? node = _root!.left;
|
_SoundSplayTreeNode<K>? node = _root!.left;
|
||||||
if (node == null) return null;
|
if (node == null) return null;
|
||||||
|
@ -531,7 +547,7 @@ class SoundSplayTreeMap<inout K, inout V> extends _SoundSplayTree<K>
|
||||||
K? firstKeyAfter(K key) {
|
K? firstKeyAfter(K key) {
|
||||||
if (key == null) throw ArgumentError(key);
|
if (key == null) throw ArgumentError(key);
|
||||||
if (_root == null) return null;
|
if (_root == null) return null;
|
||||||
int comp = _splay(key);
|
final int comp = _splay(key);
|
||||||
if (comp > 0) return _root!.key;
|
if (comp > 0) return _root!.key;
|
||||||
_SoundSplayTreeNode<K>? node = _root!.right;
|
_SoundSplayTreeNode<K>? node = _root!.right;
|
||||||
if (node == null) return null;
|
if (node == null) return null;
|
||||||
|
@ -563,12 +579,12 @@ abstract class _SoundSplayTreeIterator<inout K, inout T> implements Iterator<T>
|
||||||
///
|
///
|
||||||
/// Not final because some iterators may modify the tree knowingly,
|
/// Not final because some iterators may modify the tree knowingly,
|
||||||
/// and they update the modification count in that case.
|
/// and they update the modification count in that case.
|
||||||
int _modificationCount;
|
final int _modificationCount;
|
||||||
|
|
||||||
/// Count of splay operations on [_tree] when [_workList] was built.
|
/// Count of splay operations on [_tree] when [_workList] was built.
|
||||||
///
|
///
|
||||||
/// If the splay count on [_tree] increases, [_workList] becomes invalid.
|
/// If the splay count on [_tree] increases, [_workList] becomes invalid.
|
||||||
int? _splayCount;
|
final int? _splayCount;
|
||||||
|
|
||||||
/// Current node.
|
/// Current node.
|
||||||
_SoundSplayTreeNode<K>? _currentNode;
|
_SoundSplayTreeNode<K>? _currentNode;
|
||||||
|
@ -580,6 +596,7 @@ abstract class _SoundSplayTreeIterator<inout K, inout T> implements Iterator<T>
|
||||||
_findLeftMostDescendant(tree._root);
|
_findLeftMostDescendant(tree._root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
T get current {
|
T get current {
|
||||||
if (_currentNode == null) {
|
if (_currentNode == null) {
|
||||||
throw StateError('Use moveNext to detect the end of an iterator');
|
throw StateError('Use moveNext to detect the end of an iterator');
|
||||||
|
@ -612,6 +629,7 @@ abstract class _SoundSplayTreeIterator<inout K, inout T> implements Iterator<T>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool moveNext() {
|
bool moveNext() {
|
||||||
if (_modificationCount != _tree._modificationCount) {
|
if (_modificationCount != _tree._modificationCount) {
|
||||||
throw ConcurrentModificationError(_tree);
|
throw ConcurrentModificationError(_tree);
|
||||||
|
@ -637,14 +655,18 @@ abstract class _SoundSplayTreeIterator<inout K, inout T> implements Iterator<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SoundSplayTreeKeyIterable<inout K> extends EfficientLengthIterable<K> {
|
class _SoundSplayTreeKeyIterable<inout K> extends EfficientLengthIterable<K> {
|
||||||
_SoundSplayTree<K> _tree;
|
final _SoundSplayTree<K> _tree;
|
||||||
_SoundSplayTreeKeyIterable(this._tree);
|
_SoundSplayTreeKeyIterable(this._tree);
|
||||||
|
@override
|
||||||
int get length => _tree._count;
|
int get length => _tree._count;
|
||||||
|
@override
|
||||||
bool get isEmpty => _tree._count == 0;
|
bool get isEmpty => _tree._count == 0;
|
||||||
|
@override
|
||||||
Iterator<K> get iterator => _SoundSplayTreeKeyIterator<K>(_tree);
|
Iterator<K> get iterator => _SoundSplayTreeKeyIterator<K>(_tree);
|
||||||
|
|
||||||
|
@override
|
||||||
Set<K> toSet() {
|
Set<K> toSet() {
|
||||||
SoundSplayTreeSet<K> set = SoundSplayTreeSet<K>(_tree._comparator, _tree._validKey);
|
final SoundSplayTreeSet<K> set = SoundSplayTreeSet<K>(_tree._comparator, _tree._validKey);
|
||||||
set._count = _tree._count;
|
set._count = _tree._count;
|
||||||
set._root = set._copyNode(_tree._root);
|
set._root = set._copyNode(_tree._root);
|
||||||
return set;
|
return set;
|
||||||
|
@ -652,10 +674,13 @@ class _SoundSplayTreeKeyIterable<inout K> extends EfficientLengthIterable<K> {
|
||||||
}
|
}
|
||||||
|
|
||||||
class _SoundSplayTreeValueIterable<inout K, inout V> extends EfficientLengthIterable<V> {
|
class _SoundSplayTreeValueIterable<inout K, inout V> extends EfficientLengthIterable<V> {
|
||||||
SoundSplayTreeMap<K, V> _map;
|
final SoundSplayTreeMap<K, V> _map;
|
||||||
_SoundSplayTreeValueIterable(this._map);
|
_SoundSplayTreeValueIterable(this._map);
|
||||||
|
@override
|
||||||
int get length => _map._count;
|
int get length => _map._count;
|
||||||
|
@override
|
||||||
bool get isEmpty => _map._count == 0;
|
bool get isEmpty => _map._count == 0;
|
||||||
|
@override
|
||||||
Iterator<V> get iterator => _SoundSplayTreeValueIterator<K, V>(_map);
|
Iterator<V> get iterator => _SoundSplayTreeValueIterator<K, V>(_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -667,8 +692,9 @@ class _SoundSplayTreeKeyIterator<inout K> extends _SoundSplayTreeIterator<K, K>
|
||||||
|
|
||||||
class _SoundSplayTreeValueIterator<inout K, inout V> extends _SoundSplayTreeIterator<K, V> {
|
class _SoundSplayTreeValueIterator<inout K, inout V> extends _SoundSplayTreeIterator<K, V> {
|
||||||
_SoundSplayTreeValueIterator(SoundSplayTreeMap<K, V> map) : super(map);
|
_SoundSplayTreeValueIterator(SoundSplayTreeMap<K, V> map) : super(map);
|
||||||
|
@override
|
||||||
V _getValue(_SoundSplayTreeNode<K> node) {
|
V _getValue(_SoundSplayTreeNode<K> node) {
|
||||||
_SoundSplayTreeMapNode<K, V> mapNode = node as _SoundSplayTreeMapNode<K, V>;
|
final _SoundSplayTreeMapNode<K, V> mapNode = node as _SoundSplayTreeMapNode<K, V>;
|
||||||
return mapNode.value!;
|
return mapNode.value!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -697,10 +723,14 @@ class _SoundSplayTreeNodeIterator<inout K>
|
||||||
/// in that case.
|
/// in that case.
|
||||||
class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
with IterableMixin<E>, SetMixin<E> {
|
with IterableMixin<E>, SetMixin<E> {
|
||||||
|
@override
|
||||||
_SoundSplayTreeNode<E>? _root;
|
_SoundSplayTreeNode<E>? _root;
|
||||||
|
@override
|
||||||
final _SoundSplayTreeNode<E> _dummy = _DummySoundSplayTreeNode<E>();
|
final _SoundSplayTreeNode<E> _dummy = _DummySoundSplayTreeNode<E>();
|
||||||
|
|
||||||
|
@override
|
||||||
Comparator<E> _comparator;
|
Comparator<E> _comparator;
|
||||||
|
@override
|
||||||
_Predicate _validKey;
|
_Predicate _validKey;
|
||||||
|
|
||||||
/// Create a new [SoundSplayTreeSet] with the given compare function.
|
/// Create a new [SoundSplayTreeSet] with the given compare function.
|
||||||
|
@ -744,9 +774,9 @@ class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
/// ```
|
/// ```
|
||||||
factory SoundSplayTreeSet.from(Iterable elements,
|
factory SoundSplayTreeSet.from(Iterable elements,
|
||||||
[int Function(E key1, E key2)? compare, bool Function(Object? potentialKey)? isValidKey]) {
|
[int Function(E key1, E key2)? compare, bool Function(Object? potentialKey)? isValidKey]) {
|
||||||
SoundSplayTreeSet<E> result = SoundSplayTreeSet<E>(compare, isValidKey);
|
final SoundSplayTreeSet<E> result = SoundSplayTreeSet<E>(compare, isValidKey);
|
||||||
for (final element in elements) {
|
for (final element in elements) {
|
||||||
E e = element;
|
final E e = element;
|
||||||
result.add(e);
|
result.add(e);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -764,27 +794,36 @@ class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
Set<T> _newSet<T>() =>
|
Set<T> _newSet<T>() =>
|
||||||
SoundSplayTreeSet<T>((T a, T b) => _comparator(a as E, b as E), _validKey);
|
SoundSplayTreeSet<T>((T a, T b) => _comparator(a as E, b as E), _validKey);
|
||||||
|
|
||||||
|
@override
|
||||||
Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
|
Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
|
||||||
|
@override
|
||||||
int _compare(E e1, E e2) => _comparator(e1, e2);
|
int _compare(E e1, E e2) => _comparator(e1, e2);
|
||||||
|
|
||||||
// From Iterable.
|
// From Iterable.
|
||||||
|
|
||||||
|
@override
|
||||||
Iterator<E> get iterator => _SoundSplayTreeKeyIterator<E>(this);
|
Iterator<E> get iterator => _SoundSplayTreeKeyIterator<E>(this);
|
||||||
|
|
||||||
|
@override
|
||||||
int get length => _count;
|
int get length => _count;
|
||||||
|
@override
|
||||||
bool get isEmpty => _root == null;
|
bool get isEmpty => _root == null;
|
||||||
|
@override
|
||||||
bool get isNotEmpty => _root != null;
|
bool get isNotEmpty => _root != null;
|
||||||
|
|
||||||
|
@override
|
||||||
E get first {
|
E get first {
|
||||||
if (_count == 0) throw IterableElementError.noElement();
|
if (_count == 0) throw IterableElementError.noElement();
|
||||||
return _first!.key;
|
return _first!.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
E get last {
|
E get last {
|
||||||
if (_count == 0) throw IterableElementError.noElement();
|
if (_count == 0) throw IterableElementError.noElement();
|
||||||
return _last!.key;
|
return _last!.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
E get single {
|
E get single {
|
||||||
if (_count == 0) throw IterableElementError.noElement();
|
if (_count == 0) throw IterableElementError.noElement();
|
||||||
if (_count > 1) throw IterableElementError.tooMany();
|
if (_count > 1) throw IterableElementError.tooMany();
|
||||||
|
@ -792,41 +831,47 @@ class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
}
|
}
|
||||||
|
|
||||||
// From Set.
|
// From Set.
|
||||||
|
@override
|
||||||
bool contains(Object? element) {
|
bool contains(Object? element) {
|
||||||
return _validKey(element) && _splay(element as E) == 0;
|
return _validKey(element) && _splay(element as E) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool add(E element) {
|
bool add(E element) {
|
||||||
int compare = _splay(element);
|
final int compare = _splay(element);
|
||||||
if (compare == 0) return false;
|
if (compare == 0) return false;
|
||||||
_addNewRoot(_SoundSplayTreeNode<E>(element), compare);
|
_addNewRoot(_SoundSplayTreeNode<E>(element), compare);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
bool remove(Object? object) {
|
bool remove(Object? object) {
|
||||||
if (!_validKey(object)) return false;
|
if (!_validKey(object)) return false;
|
||||||
return _remove(object as E) != null;
|
return _remove(object as E) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void addAll(Iterable<E> elements) {
|
void addAll(Iterable<E> elements) {
|
||||||
for (E element in elements) {
|
for (E element in elements) {
|
||||||
int compare = _splay(element);
|
final int compare = _splay(element);
|
||||||
if (compare != 0) {
|
if (compare != 0) {
|
||||||
_addNewRoot(_SoundSplayTreeNode<E>(element), compare);
|
_addNewRoot(_SoundSplayTreeNode<E>(element), compare);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void removeAll(Iterable<Object?> elements) {
|
void removeAll(Iterable<Object?> elements) {
|
||||||
for (Object? element in elements) {
|
for (Object? element in elements) {
|
||||||
if (_validKey(element)) _remove(element as E);
|
if (_validKey(element)) _remove(element as E);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void retainAll(Iterable<Object?> elements) {
|
void retainAll(Iterable<Object?> elements) {
|
||||||
// Build a set with the same sense of equality as this set.
|
// Build a set with the same sense of equality as this set.
|
||||||
SoundSplayTreeSet<E> retainSet = SoundSplayTreeSet<E>(_comparator, _validKey);
|
final SoundSplayTreeSet<E> retainSet = SoundSplayTreeSet<E>(_comparator, _validKey);
|
||||||
int modificationCount = _modificationCount;
|
final int modificationCount = _modificationCount;
|
||||||
for (Object? object in elements) {
|
for (Object? object in elements) {
|
||||||
if (modificationCount != _modificationCount) {
|
if (modificationCount != _modificationCount) {
|
||||||
// The iterator should not have side effects.
|
// The iterator should not have side effects.
|
||||||
|
@ -845,35 +890,39 @@ class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
E? lookup(Object? object) {
|
E? lookup(Object? object) {
|
||||||
if (!_validKey(object)) return null;
|
if (!_validKey(object)) return null;
|
||||||
int comp = _splay(object as E);
|
final int comp = _splay(object as E);
|
||||||
if (comp != 0) return null;
|
if (comp != 0) return null;
|
||||||
return _root!.key;
|
return _root!.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Set<E> intersection(Set<Object?> other) {
|
Set<E> intersection(Set<Object?> other) {
|
||||||
Set<E> result = SoundSplayTreeSet<E>(_comparator, _validKey);
|
final Set<E> result = SoundSplayTreeSet<E>(_comparator, _validKey);
|
||||||
for (E element in this) {
|
for (E element in this) {
|
||||||
if (other.contains(element)) result.add(element);
|
if (other.contains(element)) result.add(element);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Set<E> difference(Set<Object?> other) {
|
Set<E> difference(Set<Object?> other) {
|
||||||
Set<E> result = SoundSplayTreeSet<E>(_comparator, _validKey);
|
final Set<E> result = SoundSplayTreeSet<E>(_comparator, _validKey);
|
||||||
for (E element in this) {
|
for (E element in this) {
|
||||||
if (!other.contains(element)) result.add(element);
|
if (!other.contains(element)) result.add(element);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Set<E> union(Set<E> other) {
|
Set<E> union(Set<E> other) {
|
||||||
return _clone()..addAll(other);
|
return _clone()..addAll(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundSplayTreeSet<E> _clone() {
|
SoundSplayTreeSet<E> _clone() {
|
||||||
var set = SoundSplayTreeSet<E>(_comparator, _validKey);
|
final set = SoundSplayTreeSet<E>(_comparator, _validKey);
|
||||||
set._count = _count;
|
set._count = _count;
|
||||||
set._root = _copyNode(_root);
|
set._root = _copyNode(_root);
|
||||||
return set;
|
return set;
|
||||||
|
@ -888,11 +937,14 @@ class SoundSplayTreeSet<inout E> extends _SoundSplayTree<E>
|
||||||
..right = _copyNode(node.right));
|
..right = _copyNode(node.right));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
void clear() {
|
void clear() {
|
||||||
_clear();
|
_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
Set<E> toSet() => _clone();
|
Set<E> toSet() => _clone();
|
||||||
|
|
||||||
|
@override
|
||||||
String toString() => IterableBase.iterableToFullString(this, '{', '}');
|
String toString() => IterableBase.iterableToFullString(this, '{', '}');
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
import 'dart:typed_data';
|
import 'dart:typed_data';
|
||||||
|
|
||||||
import 'package:expect/expect.dart';
|
|
||||||
import 'package:benchmark_harness/benchmark_harness.dart';
|
import 'package:benchmark_harness/benchmark_harness.dart';
|
||||||
|
import 'package:expect/expect.dart';
|
||||||
|
|
||||||
import 'match_class.dart' as match_class;
|
import 'match_class.dart' as match_class;
|
||||||
import 'match_enum.dart' as match_enum;
|
import 'match_enum.dart' as match_enum;
|
||||||
|
@ -85,8 +85,9 @@ class Benchmark extends BenchmarkBase {
|
||||||
return repeats + padding;
|
return repeats + padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
static convert(String s) => Uint8List.fromList(s.codeUnits);
|
static Uint8List convert(String s) => Uint8List.fromList(s.codeUnits);
|
||||||
|
|
||||||
|
@override
|
||||||
void run() {
|
void run() {
|
||||||
Expect.equals(true, match(testInput));
|
Expect.equals(true, match(testInput));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue