Last active
December 14, 2015 04:38
-
-
Save davidB/5029293 to your computer and use it in GitHub Desktop.
SimpleLinkedList for dart, success on single-thread but Failed when used with Future, requestAnimationFrame, httpRequest.onLoadEnd,...
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
class SimpleLinkedEntry { | |
SimpleLinkedEntry _next = null; | |
var _obj; | |
} | |
class AsyncSimpleLinkedList<E> { | |
Future<SimpleLinkedEntry> _head = new Future.immediate(null); | |
get length { | |
return _head.then((h){ | |
int i = 0; | |
for(var a = h; a != null; a = a._next, i++); | |
return i; | |
}); | |
} | |
void add(E obj) { | |
_head = _head.then((h){ | |
SimpleLinkedEntry e = new SimpleLinkedEntry(); | |
e._next = h; | |
e._obj = obj; | |
return e; | |
}); | |
} | |
num iterateAndRemove(bool f(E)) { | |
_head = _head.then((h){ | |
var current = h; | |
var prev = null; | |
var head = null; | |
int i = 0; | |
bool c = false; | |
while(current != null) { | |
var cont = f(current._obj); | |
if (!cont) { | |
i++; | |
if (prev != null) { | |
prev._next = null; | |
} | |
} else { | |
if (head == null) { | |
head = current; | |
} | |
if (prev != null) { | |
prev._next = current; | |
} | |
prev = current; | |
} | |
current = current._next; | |
} | |
return head; | |
}); | |
return 0; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LinkedBag<E> { | |
LinkedEntry _head = new LinkedEntry(); | |
get length { | |
int i = 0; | |
for(var a = _head; a != null; a = a._next) { | |
if (a._obj != null) i++; | |
} | |
return i; | |
} | |
void add(E obj) { | |
var a = _head; | |
while(a != null) { | |
if (a._obj == null) { | |
a._obj = obj; | |
return; | |
} | |
if (a._next == null) { | |
var e = new LinkedEntry(); | |
e._obj = obj; | |
a._next = e; | |
return; | |
} | |
a = a._next; | |
} | |
} | |
num iterateAndRemove(bool f(E)) { | |
int i = 0; | |
for(var current = _head; current != null; current = current._next) { | |
if (current._obj != null) { | |
var cont = f(current._obj); | |
if (!cont) { | |
i++; | |
current._obj = null; | |
} | |
} | |
} | |
return i; | |
} | |
} | |
class LinkedEntry { | |
LinkedEntry _next = null; | |
var _obj; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class SimpleLinkedEntry { | |
SimpleLinkedEntry _next = null; | |
var _obj; | |
} | |
class SimpleLinkedList<E> { | |
SimpleLinkedEntry _head = null; | |
bool iterating = false; | |
get length { | |
int i = 0; | |
for(var a = _head; a != null; a = a._next, i++); | |
return i; | |
} | |
void add(E obj) { | |
if (iterating) { | |
print("try to add when iterating"); | |
throw new StateError("iterating"); | |
} | |
SimpleLinkedEntry e = new SimpleLinkedEntry(); | |
e._next = _head; | |
e._obj = obj; | |
_head = e; | |
} | |
num iterateAndRemove(bool f(E)) { | |
iterating = true; | |
int i = 0; | |
try { | |
var current = _head; | |
var prev = null; | |
var head = null; | |
bool c = false; | |
while(current != null) { | |
var cont = f(current._obj); | |
if (!cont) { | |
i++; | |
if (prev != null) { | |
prev._next = null; | |
} | |
} else { | |
if (head == null) { | |
head = current; | |
} | |
if (prev != null) { | |
prev._next = current; | |
} | |
prev = current; | |
} | |
current = current._next; | |
} | |
_head = head; | |
} finally { | |
iterating = false; | |
} | |
return i; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:unittest/unittest.dart'; | |
main() { | |
test("SimpleLinkedList", () { | |
var d = new SimpleLinkedList(); | |
d.add(1); | |
d.add(2); | |
d.add(3); | |
d.add(1); | |
expect(d.length, equals(4)); | |
var ndeleted = 0; | |
var lbefore = 0; | |
var lafter = 0; | |
lbefore = d.length; | |
ndeleted = d.iterateAndRemove((v) => v != 2); | |
lafter = d.length; | |
expect(lafter, equals(lbefore - ndeleted), reason : "${lbefore} - ${ndeleted} != ${lafter}"); | |
lbefore = d.length; | |
ndeleted = d.iterateAndRemove((v) => v != 1); | |
lafter = d.length; | |
expect(lafter, equals(lbefore - ndeleted), reason : "${lbefore} - ${ndeleted} != ${lafter}"); | |
expect(d.length, equals(1)); | |
lbefore = d.length; | |
ndeleted = d.iterateAndRemove((v) => v != 1); | |
lafter = d.length; | |
expect(lafter, equals(lbefore - ndeleted), reason : "${lbefore} - ${ndeleted} != ${lafter}"); | |
expect(d.length, equals(1)); | |
d.add(3); | |
d.add(1); | |
d.add(1); | |
expect(d.length, equals(4)); | |
lbefore = d.length; | |
ndeleted = d.iterateAndRemove((v) => v != 3); | |
lafter = d.length; | |
expect(lafter, equals(lbefore - ndeleted), reason : "${lbefore} - ${ndeleted} != ${lafter}"); | |
expect(d.length, equals(2)); | |
lbefore = d.length; | |
ndeleted = d.iterateAndRemove((v) => v != 1); | |
lafter = d.length; | |
expect(lafter, equals(lbefore - ndeleted), reason : "${lbefore} - ${ndeleted} != ${lafter}"); | |
expect(d.length, equals(0)); | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment