Skip to content

Commit

Permalink
Merge branch 'master' of git://github.com/eriksoe/erjang
Browse files Browse the repository at this point in the history
  • Loading branch information
krestenkrab committed Nov 8, 2010
2 parents 2dc5e63 + efc313e commit 15fc136
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
15 changes: 15 additions & 0 deletions src/main/java/erjang/ETuple.java
Expand Up @@ -518,6 +518,21 @@ public boolean equals(Object obj) {
return false;
}

@Override
public boolean equalsExactly(EObject obj) {
if (obj instanceof ETuple) {
ETuple ot = (ETuple) obj;
if (arity() != ot.arity())
return false;
for (int i = 0; i < arity(); i++) {
if (!elm(i + 1).equalsExactly(ot.elm(i + 1)))
return false;
}
return true;
}
return false;
}

@Override
public Type emit_const(MethodVisitor fa) {

Expand Down
23 changes: 18 additions & 5 deletions src/main/java/erjang/m/ets/ETableSet.java
Expand Up @@ -49,6 +49,7 @@
*
*/
public class ETableSet extends ETable {
private boolean ordered;

ETableSet(EProc owner, EAtom type, EInteger tid, EAtom aname, EAtom access, int keypos,
boolean write_concurrency, boolean is_named, EInternalPID heirPID, EObject heirData) {
Expand All @@ -57,6 +58,7 @@ public class ETableSet extends ETable {
type == Native.am_set
? PersistentHashMap.EMPTY
: PersistentTreeMap.EMPTY);
this.ordered = type != Native.am_set;
}

@Override
Expand Down Expand Up @@ -180,13 +182,19 @@ protected EObject first() {


@Override
protected boolean insert_new_many(final ESeq values) {
protected boolean insert_new_many(final ESeq values) {
// Input verification outside of transaction:
for (ESeq seq = values; !seq.isNil(); seq = seq.tail()) {
ETuple value = seq.head().testTuple();
if (value == null) throw ERT.badarg(values);
EObject key = get_key(value);
}

return in_tx(new WithMap<Boolean>() {
@Override
protected Boolean run(IPersistentMap map) {
for (ESeq seq = values; !seq.isNil(); seq = seq.tail()) {
ETuple value = seq.head().testTuple();
if (value == null) throw ERT.badarg(values);
EObject key = get_key(value);
if (map.containsKey(key)) {
return false;
Expand Down Expand Up @@ -232,6 +240,7 @@ public ESeq match(EPattern matcher) {
EObject key = matcher.getKey(keypos1);
if (key == null) {
res = matcher.match(res, (Map<EObject, ETuple>) map);
if (ordered) res = res.reverse();
} else {
ETuple candidate = (ETuple) map.valAt(key);
if (candidate != null) {
Expand All @@ -250,6 +259,7 @@ public ESeq match_object(EPattern matcher) {
EObject key = matcher.getKey(keypos1);
if (key == null) {
res = matcher.match_members(res, (Map<EObject, ETuple>) map);
if (ordered) res = res.reverse();
} else {
ETuple candidate = (ETuple) map.valAt(key);
if (candidate != null) {
Expand Down Expand Up @@ -312,7 +322,7 @@ public EObject select(final EMatchSpec matcher, int limit) {
EObject key = matcher.getTupleKey(keypos1);

if (key == null) {
ESetCont cont0 = new ESetCont(matcher, map.seq(), limit);
ESetCont cont0 = new ESetCont(matcher, map.seq(), ordered, limit);
return cont0.select();

} else {
Expand All @@ -331,11 +341,13 @@ static class ESetCont extends EPseudoTerm implements ISelectContinuation {

private final ISeq ent;
private final EMatchSpec matcher;
private final boolean ordered;
private final int limit;

public ESetCont(EMatchSpec matcher, ISeq ent, int limit) {
public ESetCont(EMatchSpec matcher, ISeq ent, boolean ordered, int limit) {
this.matcher = matcher;
this.ent = ent;
this.ordered = ordered;
this.limit = limit;
}

Expand All @@ -356,13 +368,14 @@ public EObject select() {
vals = vals.cons(res);
}
}
if (ordered) vals = vals.reverse();

if (vals == ERT.NIL) {
return Native.am_$end_of_table;
} else if (!seq_has_more(map_seq)) {
return new ETuple2(vals, Native.am_$end_of_table);
} else {
return new ETuple2(vals, new ESetCont(matcher, map_seq, limit));
return new ETuple2(vals, new ESetCont(matcher, map_seq, ordered, limit));
}
}

Expand Down
20 changes: 17 additions & 3 deletions src/test/erl/ets_test.erl
Expand Up @@ -102,7 +102,9 @@ ets_do({match_object, Tab, Pattern}) -> lists:sort(ets:match_object(Tab, Pattern
ets_do({match_delete, Tab, Pattern}) -> ets:match_delete(Tab, Pattern);
ets_do({info, Tab}) -> [{P,ets:info(Tab,P)}
|| P <- [name, type, size, named_table, keypos, protection]];
ets_do({key_walk, Tab, Dir}) -> sort_if_unordered(key_walk(Tab, Dir), Tab).
ets_do({key_walk, Tab, Dir}) -> sort_if_unordered(key_walk(Tab, Dir), Tab);
ets_do({match_limit_walk, Tab, Pattern, Limit}) ->
sort_if_unordered(cont_walk(match(Tab, Pattern, Limit), fun match/1), Tab).


sort_if_unordered(L, Tab) ->
Expand All @@ -126,6 +128,17 @@ key_walk(_Tab, '$end_of_table', _NextFun, Acc) ->
key_walk(Tab, Key, NextFun, Acc) ->
key_walk(Tab, NextFun(Tab,Key), NextFun, [Key | Acc]).

cont_walk('$end_of_table', _MoreFun) -> [];
cont_walk({Ms, Cont}, MoreFun) -> Ms ++ cont_walk(MoreFun(Cont), MoreFun).


%% ===========================================
%% As long as match/3 and match/1 aren't implemented...:
match(Tab, Pattern, Limit) ->
ets:select(Tab,[{Pattern,[],['$_']}], Limit).
match(Cont) ->
ets:select(Cont).

%% ===========================================
%% Run erlang:Fun(Args) here
%% ===========================================
Expand Down Expand Up @@ -175,14 +188,15 @@ ets_cmd() ->
{insert_new, table_name(), table_tuple()},
{insert_new, table_name(), much_smaller(list(table_tuple()))},
{lookup, table_name(), table_key()},
{lookup_element, table_name(), table_key(), much_smaller(?DELAY(int()))},
{lookup_element, table_name(), table_key(), much_smaller(int())},
{member, table_name(), table_key()},
{delete, table_name()},
{delete, table_name(), table_key()},
{match_object, table_name(), much_smaller(table_tuple_pattern())},
{match_delete, table_name(), much_smaller(table_tuple_pattern())},
{info, table_name()},
{key_walk, table_name(), ?SUCHTHAT(X, oneof([forward, backward]), X/=backward)} % Implementation of prev & last is missing yet
{key_walk, table_name(), ?SUCHTHAT(X, oneof([forward, backward]), X/=backward)}, % Implementation of prev & last is missing yet
{match_limit_walk, table_name(), much_smaller(table_tuple_pattern()), much_smaller(int())} % Implementation of prev & last is missing yet
]).

any2() ->
Expand Down

0 comments on commit 15fc136

Please sign in to comment.