/* * Concept profile generation tool suite * Copyright (C) 2015 Biosemantics Group, Erasmus University Medical Center, * Rotterdam, The Netherlands * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.erasmusmc.collections; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; public class SparseHighDimensionalMap<K,V> { private SparseHighDimensionalMatrix<V> data; private List<Map<K, Integer>> dim2key2index; public SparseHighDimensionalMap(int numberOfDimensions){ data = new SparseHighDimensionalMatrix<V>(numberOfDimensions); dim2key2index = new ArrayList<Map<K,Integer>>(numberOfDimensions); for (int i = 0; i < numberOfDimensions; i++) dim2key2index.add(new HashMap<K, Integer>()); } public void put(V value, K...keys){ data.set(convertToIndicesAddIfNeeded(keys),value); } public V get(K...keys){ int[] indices = convertToIndices(keys); if (indices == null) return null; else return data.get(indices); } private int[] convertToIndices(K...keys){ int[] indices = new int[data.dimensions()]; for (int i = 0; i < keys.length; i++){ Integer index = dim2key2index.get(i).get(keys[i]); if (index == null) return null; indices[i] = index; } return indices; } public Set<K> keySet(int dimension){ return dim2key2index.get(dimension).keySet(); } private int[] convertToIndicesAddIfNeeded(K...keys){ int[] indices = new int[data.dimensions()]; for (int i = 0; i < keys.length; i++){ Map<K,Integer> key2index = dim2key2index.get(i); Integer index = key2index.get(keys[i]); if (index == null){ index = key2index.size(); key2index.put(keys[i], index); } indices[i] = index; } return indices; } public static class Entry<K,V>{ public List<K> keys; public V value; } public Iterator<Entry<K,V>> iterator(){ return new EntryIterator(); } private class EntryIterator implements Iterator<Entry<K,V>>{ private Iterator<SparseHighDimensionalMatrix.Entry<V>> iterator; public EntryIterator(){ iterator = data.iterator(); } @Override public boolean hasNext() { return iterator.hasNext(); } @Override public Entry<K, V> next() { Entry<K, V> entry = new Entry<K, V>(); entry.keys = new ArrayList<K>(data.dimensions()); SparseHighDimensionalMatrix.Entry<V> shdmEntry = iterator.next(); for (int i = 0; i < shdmEntry.indices.length; i++) entry.keys.add(findKey(i,shdmEntry.indices[i])); entry.value = shdmEntry.value; return entry; } private K findKey(int dim, int index) { for (Map.Entry<K, Integer> entry : dim2key2index.get(dim).entrySet()) if (entry.getValue().equals(index)) return entry.getKey(); throw new RuntimeException("Value not found in map"); } @Override public void remove() { System.err.println("Remove method not implemented"); } } }