/**
* This file is part of Erjang - A JVM-based Erlang VM
*
* Copyright (c) 2013 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 java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import com.trifork.clj_ds.APersistentMap;
import com.trifork.clj_ds.APersistentSet;
import com.trifork.clj_ds.IMapEntry;
import com.trifork.clj_ds.IPersistentCollection;
import com.trifork.clj_ds.IPersistentMap;
import com.trifork.clj_ds.IPersistentSet;
import com.trifork.clj_ds.ISeq;
import com.trifork.clj_ds.PersistentHashMap;
import com.trifork.clj_ds.PersistentHashSet;
import com.trifork.clj_ds.PersistentTreeMap;
import com.trifork.clj_ds.RT;
public class EPersistentInsertionOrderedSet<V> extends APersistentSet<V> {
public static class EIterator<V> implements Iterator<V> {
private Iterator<Map.Entry<Long, V>> it;
public EIterator(
Iterator<Map.Entry<Long, V>> it) {
this.it = it;
}
@Override
public boolean hasNext() {
return it.hasNext();
}
@Override
public V next() {
return it.next().getValue();
}
@Override
public void remove() {
it.remove();
}
}
private final IPersistentMap<Long, V> iorder;
private final IPersistentMap<V, Long> korder;
private final long ins;
@SuppressWarnings({ "rawtypes", "unchecked" })
public static EPersistentInsertionOrderedSet EMPTY = new EPersistentInsertionOrderedSet(0, PersistentTreeMap.EMPTY, PersistentHashMap.EMPTY);
private EPersistentInsertionOrderedSet(long ins, IPersistentMap<Long,V> iorder, IPersistentMap<V,Long> keyorder)
{
super(null);
this.ins = ins+1;
this.iorder = iorder;
this.korder = keyorder;
}
@Override
public IPersistentSet<V> disjoin(V value) throws Exception {
Long idx = korder.valAt(value);
IPersistentMap<Long, V> i = iorder;
if (idx == null) { return this; }
i = i.without(idx);
IPersistentMap<V, Long> k = korder.without(value);
return make(i, k);
}
@Override
public IPersistentSet<V> cons(V value) {
Long idx = korder.valAt(value);
IPersistentMap<Long, V> i = iorder;
if (idx != null) {
try {
i = i.without(idx);
} catch (Exception e) {
// ignore //
}
}
Long inso = new Long(ins);
i = i.assoc(inso, value);
IPersistentMap<V, Long> k = korder.assoc(value, inso);
return make(i, k);
}
private IPersistentSet<V> make(IPersistentMap<Long, V> i,
IPersistentMap<V, Long> k) {
return new EPersistentInsertionOrderedSet<V>(ins, i, k);
}
@Override
public int count() {
return korder.count();
}
@SuppressWarnings("unchecked")
@Override
public IPersistentCollection<V> empty() {
return EPersistentInsertionOrderedSet.EMPTY;
}
@Override
public ISeq<V> seq() {
return new ESeq<V>(iorder.seq());
}
static class ESeq<V> implements ISeq<V> {
ISeq<IMapEntry<Long, V>> iseq;
ESeq(ISeq<IMapEntry<Long, V>> iSeq2) { this.iseq = iSeq2; }
@Override
public int count() {
return iseq.count();
}
@SuppressWarnings("unchecked")
@Override
public IPersistentCollection<V> empty() {
return EPersistentInsertionOrderedSet.EMPTY;
}
@Override
public boolean equiv(Object arg0) {
return equals(arg0);
}
@Override
public ISeq<V> seq() {
return new ESeq<V>(iseq.seq());
}
@SuppressWarnings("unchecked")
@Override
public ISeq<V> cons(V arg0) {
return RT.cons(arg0, seq());
}
@Override
public V first() {
Map.Entry<Long, V> first = iseq.first();
if (first == null) return null;
return first.getValue();
}
// @SuppressWarnings("unchecked")
@Override
public ISeq<V> more() {
ISeq<IMapEntry<Long, V>> more = iseq.more();
return new ESeq<V>(more);
}
@Override
public ISeq<V> next() {
ISeq<IMapEntry<Long, V>> next = iseq.next();
if (next == null) return null;
return new ESeq<V>(next);
}
}
}