/**
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2009 by Trifork
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
**/
package erjang.m.ets;
import com.trifork.clj_ds.IMapEntry;
import com.trifork.clj_ds.IPersistentCollection;
import com.trifork.clj_ds.IPersistentMap;
import com.trifork.clj_ds.ISeq;
import com.trifork.clj_ds.PersistentHashMap;
import com.trifork.clj_ds.PersistentList;
import com.trifork.clj_ds.PersistentTreeMap;
/**
*
*/
@SuppressWarnings("rawtypes")
public class PersistentBag extends Object implements IPersistentBag {
public static PersistentBag EMPTY = new PersistentBag(PersistentHashMap.EMPTY, 0);
IPersistentMap impl;
int count;
private PersistentBag(IPersistentMap impl, int count) {
this.impl = impl;
this.count = count;
}
@Override
public IPersistentBag disjoin(Object element) {
Integer val = (Integer) impl.valAt(element);
if (val == null) {
return this;
} else if (val == 1) {
try {
return new PersistentBag(impl.without(element), count - 1);
} catch (Exception e) {
throw new Error(e);
}
} else {
return new PersistentBag(impl.assoc(element, val - 1), count - 1);
}
}
@Override
public IPersistentCollection cons(Object element) {
Integer val = (Integer) impl.valAt(element);
if (val == null) {
return new PersistentBag(impl.assoc(element, 1), count + 1);
} else {
return new PersistentBag(impl.assoc(element, val + 1), count + 1);
}
}
@Override
public int count() {
return count;
}
@Override
public IPersistentCollection empty() {
return new PersistentBag(PersistentTreeMap.EMPTY, 0);
}
@Override
public boolean equiv(Object arg0) {
throw new UnsupportedOperationException();
}
class ElemSeq implements ISeq {
private final int total;
private final int pos;
private final ISeq pairs;
@Override
public ISeq cons(Object arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public Object first() {
IMapEntry elem_count_pair = (IMapEntry) pairs.first();
return elem_count_pair.getKey();
}
@Override
public ISeq more() {
ISeq next = next();
if (next == null)
return PersistentList.EMPTY;
return next;
}
@Override
public ISeq next() {
IMapEntry elem_count_pair = (IMapEntry) pairs.first();
int count = (Integer) elem_count_pair.getValue();
if (count == pos + 1) {
ISeq succ = pairs.next();
if (succ == null) {
return null;
} else {
return new ElemSeq(succ, 0, total-1);
}
} else {
return new ElemSeq(pairs, pos + 1, total-1);
}
}
@Override
public int count() {
return total;
}
@Override
public IPersistentCollection empty() {
return PersistentBag.EMPTY;
}
@Override
public boolean equiv(Object arg0) {
throw new UnsupportedOperationException();
}
/*
* (non-Javadoc)
*
* @see com.trifork.clj_ds.Seqable#seq()
*/
@Override
public ISeq seq() {
return this;
}
ElemSeq(ISeq pairs, int count, int total) {
this.pairs = pairs;
this.pos = count;
this.total = total;
}
}
/*
* (non-Javadoc)
*
* @see com.trifork.clj_ds.Seqable#seq()
*/
@Override
public ISeq seq() {
if (count() == 0) return null;
return new ElemSeq(impl.seq(), 0, count);
}
}