/******************************************************************************* * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek * * 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 de.mxro.thrd.jdbm2V22.htree; import java.io.IOError; import java.io.IOException; import java.util.AbstractSet; import java.util.Iterator; import java.util.NoSuchElementException; import java.util.Set; import de.mxro.thrd.jdbm2V22.PrimaryHashMap; import de.mxro.thrd.jdbm2V22.RecordListener; import de.mxro.thrd.jdbm2V22.RecordManager; import de.mxro.thrd.jdbm2V22.helper.AbstractPrimaryMap; public class HTreeMap<K,V> extends AbstractPrimaryMap<K,V> implements PrimaryHashMap<K,V>{ protected final HTree<K,V> tree; protected final boolean readonly; public HTreeMap(HTree<K,V> tree, boolean readonly){ this.tree = tree; this.readonly = readonly; } @Override public Set<java.util.Map.Entry<K, V>> entrySet() { return new AbstractSet<Entry<K,V>>(){ protected Entry<K,V> newEntry(K k,V v){ return new SimpleEntry<K,V>(k,v){ private static final long serialVersionUID = 978651696969194154L; public V setValue(V arg0) { HTreeMap.this.put(getKey(), arg0); return super.setValue(arg0); }; }; } public boolean add(java.util.Map.Entry<K, V> e) { if(readonly) throw new UnsupportedOperationException("readonly"); try { if(e.getKey() == null) throw new NullPointerException("Can not add null key"); if(e.getValue().equals(tree.find(e.getKey()))) return false; tree.put(e.getKey(), e.getValue()); return true; } catch (IOException e1) { throw new IOError(e1); } } @SuppressWarnings("unchecked") public boolean contains(Object o) { if(o instanceof Entry){ Entry<K,V> e = (java.util.Map.Entry<K, V>) o; try { if(e.getKey()!=null && tree.find(e.getKey())!=null) return true; } catch (IOException e1) { throw new IOError(e1); } } return false; } public Iterator<java.util.Map.Entry<K, V>> iterator() { try { final Iterator<K> br = tree.keys(); return new Iterator<Entry<K,V>>(){ private Entry<K,V> next; private K lastKey; void ensureNext(){ try{ if(br.hasNext()){ K k = br.next(); next = newEntry(k,tree.find(k)); }else next = null; }catch (IOException e){ throw new IOError(e); } } { ensureNext(); } public boolean hasNext() { return next!=null; } public java.util.Map.Entry<K, V> next() { if(next == null) throw new NoSuchElementException(); Entry<K,V> ret = next; lastKey = ret.getKey(); //move to next position ensureNext(); return ret; } public void remove() { if(readonly) throw new UnsupportedOperationException("readonly"); if(lastKey == null) throw new IllegalStateException(); HTreeMap.this.remove(lastKey); lastKey = null; }}; } catch (IOException e) { throw new IOError(e); } } @SuppressWarnings("unchecked") public boolean remove(Object o) { if(readonly) throw new UnsupportedOperationException("readonly"); if(o instanceof Entry){ Entry<K,V> e = (java.util.Map.Entry<K, V>) o; try { //check for nulls if(e.getKey() == null || e.getValue() == null) return false; //find old value, must be same as item in entry V v = get(e.getKey()); if(v == null || !e.getValue().equals(v)) return false; tree.remove(e.getKey()); return true; } catch (IOException e1) { throw new IOError(e1); } } return false; } @Override public int size() { try{ int counter = 0; Iterator<K> it = tree.keys(); while(it.hasNext()){ it.next(); counter ++; } return counter; }catch (IOException e){ throw new IOError(e); } } }; } @SuppressWarnings("unchecked") @Override public V get(Object key) { try{ if(key == null) return null; return tree.find((K) key); }catch (ClassCastException e){ return null; }catch (IOException e){ throw new IOError(e); } } @SuppressWarnings("unchecked") @Override public V remove(Object key) { if(readonly) throw new UnsupportedOperationException("readonly"); try{ if(key == null) return null; V oldVal = tree.find((K) key); if(oldVal!=null) tree.remove((K) key); return oldVal; }catch (ClassCastException e){ return null; }catch (IOException e){ throw new IOError(e); } } public V put(K key, V value) { if(readonly) throw new UnsupportedOperationException("readonly"); try { if(key == null || value == null) throw new NullPointerException("Null key or value"); V oldVal = tree.find(key); tree.put(key, value); return oldVal; } catch (IOException e) { throw new IOError(e); } }; @SuppressWarnings("unchecked") @Override public boolean containsKey(Object key) { if(key == null) return false; try { V v = tree.find((K) key); return v!=null; } catch (IOException e) { throw new IOError(e); } catch (ClassCastException e){ return false; } } public HTree<K, V> getTree() { return tree; } public void addRecordListener(RecordListener<K, V> listener) { tree.addRecordListener(listener); } public RecordManager getRecordManager() { return tree.getRecordManager(); } public void removeRecordListener(RecordListener<K, V> listener) { tree.removeRecordListener(listener); } public void clear(){ try{ Iterator<K> keyIter = tree.keys(); while(keyIter.hasNext()) tree.remove(keyIter.next()); }catch(IOException e){ throw new IOError(e); } } }