Skip to content

Commit 92f6f31

Browse files
committed
clone and shift
multiplyWithCounter pedantic and lints clone multiply shiftLeft/shiftRight shift -> shiftLeft,shiftRight changelog
1 parent 332852a commit 92f6f31

14 files changed

+363
-102
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## 1.1.0
2+
3+
- `CompositeSet.clone` returns `CompositeSet`.
4+
- Support `shiftLeft` in many operations.
5+
- Support multiply and clone of counters.
6+
- Use `package:pedantic` and Dart 2.2 features.
7+
18
## 1.0.1
29

310
- `asUint64Iterable()` added to provide interface-level compatibility for future compressed bit arrays.

analysis_options.yaml

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,30 @@
1+
include: package:pedantic/analysis_options.yaml
2+
13
analyzer:
2-
# exclude:
3-
# - path/to/excluded/files/**
4+
strong-mode:
5+
implicit-casts: false
6+
errors:
7+
unused_import: error
8+
unused_local_variable: error
9+
dead_code: error
410

511
# Lint rules and documentation, see http://dart-lang.github.io/linter/lints
612
linter:
713
rules:
14+
- annotate_overrides
815
- cancel_subscriptions
16+
- directives_ordering
917
- hash_and_equals
1018
- iterable_contains_unrelated_type
1119
- list_remove_unrelated_type
1220
- test_types_in_equals
21+
- unnecessary_brace_in_string_interps
22+
- unnecessary_const
23+
- unnecessary_getters_setters
24+
- unnecessary_lambdas
25+
- unnecessary_new
26+
- unnecessary_null_aware_assignments
27+
- unnecessary_statements
28+
- unnecessary_this
1329
- unrelated_type_equality_checks
1430
- valid_regexps

example/example.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import 'package:bit_array/bit_array.dart';
22

33
main() {
4-
final array = new BitArray(1024);
4+
final array = BitArray(1024);
55
array[12] = true;
66
array.setBit(123);
77
array.invertBit(200);
88
array.clearBit(12);
99
print(array.asIntIterable().toList()); // prints [123, 200]
1010

11-
final other = new BitArray(1024);
11+
final other = BitArray(1024);
1212
other[123] = true;
1313

1414
final and = array & other;

lib/src/bit_array.dart

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ class BitArray implements BitSet {
1111
///
1212
/// [length] will be rounded up to match the 64-bit boundary.
1313
factory BitArray(int length) =>
14-
new BitArray._(new Uint64List(_bufferLength64(length)));
14+
BitArray._(Uint64List(_bufferLength64(length)));
1515

1616
/// Creates a bit array using a byte buffer.
1717
factory BitArray.fromByteBuffer(ByteBuffer buffer) {
1818
final data = buffer.asUint64List();
19-
return new BitArray._(data);
19+
return BitArray._(data);
2020
}
2121

2222
/// Creates a bit array using a generic bit set.
2323
factory BitArray.fromBitSet(BitSet set, {int length}) {
2424
length ??= set.length;
2525
final setDataLength = _bufferLength64(set.length);
26-
final data = new Uint64List(_bufferLength64(length));
26+
final data = Uint64List(_bufferLength64(length));
2727
data.setRange(0, setDataLength, set.asUint64Iterable());
28-
return new BitArray._(data);
28+
return BitArray._(data);
2929
}
3030

3131
/// The value of the bit with the specified [index].
@@ -48,12 +48,13 @@ class BitArray implements BitSet {
4848
/// [length] will be rounded up to match the 64-bit boundary.
4949
///
5050
/// The valid index values for the array are `0` through `length - 1`.
51+
@override
5152
int get length => _length;
52-
void set length(int value) {
53+
set length(int value) {
5354
if (_length == value) {
5455
return;
5556
}
56-
final data = new Uint64List(_bufferLength64(value));
57+
final data = Uint64List(_bufferLength64(value));
5758
data.setRange(0, math.min(data.length, _data.length), _data);
5859
_data = data;
5960
_length = _data.length << 6;
@@ -112,7 +113,7 @@ class BitArray implements BitSet {
112113
/// Inverts all the bit values in the current [BitArray].
113114
void invertAll() {
114115
for (int i = 0; i < _data.length; i++) {
115-
_data[i] = ~_data[i];
116+
_data[i] = ~(_data[i]);
116117
}
117118
}
118119

@@ -163,34 +164,34 @@ class BitArray implements BitSet {
163164
/// Creates a copy of the current [BitArray].
164165
@override
165166
BitArray clone() {
166-
final newData = new Uint64List(_data.length);
167+
final newData = Uint64List(_data.length);
167168
newData.setRange(0, _data.length, _data);
168-
return new BitArray._(newData);
169+
return BitArray._(newData);
169170
}
170171

171-
/// Creates a new [BitArray] using a logical AND operation with the
172+
/// Creates a [BitArray] using a logical AND operation with the
172173
/// corresponding elements in the specified [set].
173174
/// Excess size of the [set] is ignored.
174175
BitArray operator &(BitSet set) => clone()..and(set);
175176

176-
/// Creates a new [BitArray] using a logical AND NOT operation with the
177+
/// Creates a [BitArray] using a logical AND NOT operation with the
177178
/// corresponding elements in the specified [set].
178179
/// Excess size of the [set] is ignored.
179180
BitArray operator %(BitSet set) => clone()..andNot(set);
180181

181-
/// Creates a new [BitArray] using a logical OR operation with the
182+
/// Creates a [BitArray] using a logical OR operation with the
182183
/// corresponding elements in the specified [set].
183184
/// Excess size of the [set] is ignored.
184185
BitArray operator |(BitSet set) => clone()..or(set);
185186

186-
/// Creates a new [BitArray] using a logical XOR operation with the
187+
/// Creates a [BitArray] using a logical XOR operation with the
187188
/// corresponding elements in the specified [set].
188189
/// Excess size of the [set] is ignored.
189190
BitArray operator ^(BitSet set) => clone()..xor(set);
190191

191192
/// Creates a string of 0s and 1s of the content of the array.
192193
String toBinaryString() {
193-
final sb = new StringBuffer();
194+
final sb = StringBuffer();
194195
for (int i = 0; i < length; i++) {
195196
sb.write(this[i] ? '1' : '0');
196197
}
@@ -210,13 +211,13 @@ class BitArray implements BitSet {
210211
/// numbers that match [value] (by default the bits that are set).
211212
@override
212213
Iterable<int> asIntIterable([bool value = true]) {
213-
return new _IntIterable(this, value);
214+
return _IntIterable(this, value);
214215
}
215216
}
216217

217-
final _bitMask = new List<int>.generate(64, (i) => 1 << i);
218-
final _clearMask = new List<int>.generate(64, (i) => ~(1 << i));
219-
final _cardinalityBitCounts = new List<int>.generate(256, _cardinalityOfByte);
218+
final _bitMask = List<int>.generate(64, (i) => 1 << i);
219+
final _clearMask = List<int>.generate(64, (i) => ~(1 << i));
220+
final _cardinalityBitCounts = List<int>.generate(256, _cardinalityOfByte);
220221

221222
int _cardinalityOfByte(int value) {
222223
int result = 0;
@@ -236,7 +237,7 @@ class _IntIterable extends IterableBase<int> {
236237

237238
@override
238239
Iterator<int> get iterator =>
239-
new _IntIterator(_array._data, _array.length, _value);
240+
_IntIterator(_array._data, _array.length, _value);
240241
}
241242

242243
class _IntIterator implements Iterator<int> {

lib/src/bit_counter.dart

Lines changed: 81 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ class BitCounter {
3434
while (value > 0) {
3535
BitArray array;
3636
if (_bits.length == pos) {
37-
array = new BitArray(_length);
37+
array = BitArray(_length);
3838
_bits.add(array);
3939
} else {
4040
array = _bits[pos];
@@ -50,7 +50,7 @@ class BitCounter {
5050

5151
/// Returns the binary string representation of the count at the given [index].
5252
String toBinaryString(int index) {
53-
final sb = new StringBuffer();
53+
final sb = StringBuffer();
5454
for (int i = _bits.length - 1; i >= 0; i--) {
5555
final value = _bits[i][index];
5656
if (sb.isEmpty && !value) continue;
@@ -68,20 +68,25 @@ class BitCounter {
6868
}
6969

7070
/// Adds a [set] to the counter.
71-
void addBitSet(BitSet set) {
71+
///
72+
/// The add starts at the bit position specified by [shiftLeft].
73+
void addBitSet(BitSet set, {int shiftLeft = 0}) {
7274
if (_length < set.length) {
7375
_length = set.length;
7476
_bits.forEach((a) => a.length = _length);
7577
}
78+
for (int i = _bits.length; i < shiftLeft; i++) {
79+
_bits.add(BitArray(_length));
80+
}
7681
final arrayDataLength = _bufferLength64(_length);
7782
final iterator = set.asUint64Iterable().iterator;
7883
for (int i = 0; i < arrayDataLength && iterator.moveNext(); i++) {
7984
int overflow = iterator.current;
8085

81-
for (int pos = 0; overflow != 0; pos++) {
86+
for (int pos = shiftLeft; overflow != 0; pos++) {
8287
BitArray counter;
8388
if (_bits.length == pos) {
84-
counter = new BitArray(_length);
89+
counter = BitArray(_length);
8590
_bits.add(counter);
8691
} else {
8792
counter = _bits[pos];
@@ -94,12 +99,26 @@ class BitCounter {
9499
}
95100
}
96101

102+
/// Adds a [counter] to the set.
103+
///
104+
/// The add starts at the bit position specified by [shiftLeft].
105+
void addBitCounter(BitCounter counter, {int shiftLeft = 0}) {
106+
for (int i = 0; i < counter.bitLength; i++) {
107+
addBitSet(counter.bits[i], shiftLeft: shiftLeft + i);
108+
}
109+
}
110+
97111
/// Increments the value at the [index].
98-
void increment(int index) {
99-
for (int pos = 0;; pos++) {
112+
///
113+
/// The increment starts at the bit position specified by [shiftLeft].
114+
void increment(int index, {int shiftLeft = 0}) {
115+
for (int i = _bits.length; i < shiftLeft; i++) {
116+
_bits.add(BitArray(_length));
117+
}
118+
for (int pos = shiftLeft;; pos++) {
100119
BitArray counter;
101120
if (_bits.length == pos) {
102-
counter = new BitArray(_length);
121+
counter = BitArray(_length);
103122
_bits.add(counter);
104123
} else {
105124
counter = _bits[pos];
@@ -113,4 +132,58 @@ class BitCounter {
113132
}
114133
}
115134
}
135+
136+
/// Multiply this instance with [value] and return the result.
137+
BitCounter multiply(int value) {
138+
final result = BitCounter(_length);
139+
int shiftLeft = 0;
140+
while (value > 0) {
141+
final bit = value & 0x01;
142+
if (bit == 1) {
143+
result.addBitCounter(this, shiftLeft: shiftLeft);
144+
}
145+
value = value >> 1;
146+
shiftLeft++;
147+
}
148+
return result;
149+
}
150+
151+
/// Multiply this instance with [counter] and return the result.
152+
BitCounter multiplyWithCounter(BitCounter counter) {
153+
final result = BitCounter(math.min(_length, counter._length));
154+
for (int i = 0; i < bitLength; i++) {
155+
for (int j = 0; j < counter.bitLength; j++) {
156+
final ba = _bits[i].clone()..and(counter._bits[j]);
157+
result.addBitSet(ba, shiftLeft: i + j);
158+
}
159+
}
160+
return result;
161+
}
162+
163+
/// Add [bits] cleared bits to the lower binary digits.
164+
void shiftLeft(int bits) {
165+
if (bits <= 0) return;
166+
final list = List<BitArray>.generate(bits, (i) => BitArray(_length));
167+
_bits.insertAll(0, list);
168+
}
169+
170+
/// Remove [bits] lower binary digits.
171+
void shiftRight(int bits) {
172+
if (bits <= 0) return;
173+
final end = math.min(bits, bitLength);
174+
if (end > 0) {
175+
_bits.removeRange(0, end);
176+
}
177+
}
178+
179+
/// Creates a copy of the current [BitCounter].
180+
///
181+
/// The cloned instance starts at the bit position specified by [shiftRight].
182+
BitCounter clone({int shiftRight = 0}) {
183+
final c = BitCounter(_length);
184+
for (int i = shiftRight; i < bitLength; i++) {
185+
c._bits.add(_bits[i].clone());
186+
}
187+
return c;
188+
}
116189
}

lib/src/bit_set.dart

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class EmptySet implements BitSet {
5050
}
5151

5252
/// Memory-efficient empty [BitSet] instance.
53-
const emptyBitSet = const EmptySet();
53+
const emptyBitSet = EmptySet();
5454

5555
/// A list-based [BitSet] implementation.
5656
class ListSet implements BitSet {
@@ -91,7 +91,7 @@ class ListSet implements BitSet {
9191

9292
@override
9393
BitSet clone() {
94-
return new ListSet.fromSorted(_cloneList(_list));
94+
return ListSet.fromSorted(_cloneList(_list));
9595
}
9696

9797
@override
@@ -150,7 +150,7 @@ class RangeSet implements BitSet {
150150

151151
@override
152152
BitSet clone() {
153-
return new ListSet.fromSorted(_cloneList(_list));
153+
return ListSet.fromSorted(_cloneList(_list));
154154
}
155155

156156
@override
@@ -199,22 +199,22 @@ Iterable<int> _toUint64Iterable(Iterable<int> values) sync* {
199199

200200
List<int> _cloneList(List<int> list) {
201201
if (list is Uint16List) {
202-
final clone = new Uint16List(list.length);
202+
final clone = Uint16List(list.length);
203203
clone.setRange(0, list.length, list);
204204
return clone;
205205
} else if (list is Uint8List) {
206-
final clone = new Uint8List(list.length);
206+
final clone = Uint8List(list.length);
207207
clone.setRange(0, list.length, list);
208208
return clone;
209209
} else if (list is Uint32List) {
210-
final clone = new Uint32List(list.length);
210+
final clone = Uint32List(list.length);
211211
clone.setRange(0, list.length, list);
212212
return clone;
213213
} else if (list is Uint64List) {
214-
final clone = new Uint64List(list.length);
214+
final clone = Uint64List(list.length);
215215
clone.setRange(0, list.length, list);
216216
return clone;
217217
} else {
218-
return new List<int>.from(list);
218+
return List<int>.from(list);
219219
}
220220
}

0 commit comments

Comments
 (0)