/* This file is part of VoltDB. * Copyright (C) 2008-2010 VoltDB Inc. * * VoltDB is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * VoltDB 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with VoltDB. If not, see <http://www.gnu.org/licenses/>. */ /* WARNING: THIS FILE IS AUTO-GENERATED DO NOT MODIFY THIS SOURCE ALL CHANGES MUST BE MADE IN THE CATALOG GENERATOR */ package org.voltdb.catalog; import java.lang.reflect.Array; import java.util.Collection; import java.util.Iterator; import java.util.Map.Entry; import java.util.Set; import java.util.TreeMap; import edu.brown.catalog.CatalogUtil; /** * A safe interface to a generic map of CatalogType instances. It is safe * because it is mostly read-only. All operations that modify the map are * either non-public, or they are convenience methods which generate * catalog commands and execute them on the root Catalog instance. By * generating commands, transactional safety is easier to assure. * * @param <T> The subclass of CatalogType that this map will contain. */ public final class CatalogMap<T extends CatalogType> implements Iterable<T>, Collection<T> { TreeMap<String, T> m_items = new TreeMap<String, T>(); T m_fastArray[]; Class<T> m_cls; Catalog m_catalog; CatalogType m_parent; String m_path; int m_subTreeVersion; CatalogMap(Catalog catalog, CatalogType parent, String path, Class<T> cls) { this.m_catalog = catalog; this.m_parent = parent; this.m_path = path; this.m_cls = cls; this.m_subTreeVersion = catalog.m_currentCatalogVersion; } public Class<T> getGenericClass() { return (m_cls); } public Set<String> keySet() { return (this.m_items.keySet()); } @Override public <X> X[] toArray(X[] a) { return (m_items.values().toArray(a)); } @Override public Object[] toArray() { return (m_items.values().toArray()); } /** * Get an item from the map by name * @param name The name of the requested CatalogType instance in the map * @return The item found in the map, or null if not found */ public T get(String name) { return m_items.get(name); } /** * Get an item from the map by name, ignoring case * @param name The name of the requested CatalogType instance in the map * @return The item found in the map, or null if not found */ public T getIgnoreCase(String name) { T t = m_items.get(name); if (t == null) { for (Entry<String, T> e : m_items.entrySet()) { if (e.getKey().equalsIgnoreCase(name)) { t = e.getValue(); break; } } // FOR } return (t); } /** * How many items are in the map? * @return The number of items in the map */ public int size() { return m_items.size(); } /** * Is the map empty? * @return A boolean indicating whether the map is empty */ public boolean isEmpty() { return (m_items.size() == 0); } /** * Get an iterator for the items in the map * @return The iterator for the items in the map */ public Iterator<T> iterator() { return m_items.values().iterator(); } // public T get(int index) { // // HACK // index++; // int i = 0; // T ret = null; // for (T t : m_items.values()) { // System.err.println("[" + (i++) + "] " + t + " (index=" + t.m_relativeIndex + ")"); // if (t.m_relativeIndex == index) ret = t; // return (t); // } // FOR // return (ret); // } public T get(String field, Object value) { T ret = null; for (T t : m_items.values()) { assert(t.m_fields.containsKey(field)) : t.getClass() + " does not contain field '" + field + "'"; if (t.getField(field).equals(value)) { ret = t; break; } } // FOR return (ret); } public T get(int index) { return (this.get("index", index)); } /** * Return an array of the values in this CatalogMap. * This will be generally faster than using an iterator because * we will cache the array locally * @return */ @SuppressWarnings("unchecked") public T[] values() { if (m_fastArray == null) { synchronized (this) { if (m_fastArray == null) { int capacity = this.size(); T arr[] = (T[])Array.newInstance(this.m_cls, capacity); int i = 0; for (T t : m_items.values()) { arr[i++] = t; } // FOR m_fastArray = arr; } } // SYNCH } return m_fastArray; } public int getSubTreeVersion() { return m_subTreeVersion; } /** * Create a new instance of a CatalogType as a child of this map with a * given name. Note: this just makes a catalog command and calls * catalog.execute(..). * @param name The name of the new instance to create, the thing to add * @return The newly created CatalogType instance */ public T add(String name) { try { if (m_items.containsKey(name)) throw new CatalogException("Catalog item '" + name + "' already exists for " + m_parent); T x = m_cls.newInstance(); String childPath = m_path + "[" + name + "]"; x.setBaseValues(m_catalog, m_parent, childPath, name); x.m_parentMap = this; m_items.put(name, x); // update versioning if needed updateVersioning(); // assign a relative index to every child item int index = 1; for (Entry<String, T> e : m_items.entrySet()) { e.getValue().m_relativeIndex = index++; } m_fastArray = null; return x; } catch (Exception ex) { throw new RuntimeException(ex); } } @Override public boolean add(T x) { return this.add(x, true); } /** * Add a CatalogType object into this CatalogMap * If initialize is set to true, then this will invoke CatalogType.setBaseValues() * @param x * @param initialize * @return */ public boolean add(T x, boolean initialize) { String name = x.getName(); if (m_items.containsKey(name)) throw new CatalogException("Catalog item '" + name + "' already exists for " + m_parent); String childPath = m_path + "[" + name + "]"; if (initialize) x.setBaseValues(m_catalog, m_parent, childPath, name); x.m_parentMap = this; m_items.put(name, x); // update versioning if needed updateVersioning(); // assign a relative index to every child item int index = 1; for (Entry<String, T> e : m_items.entrySet()) { e.getValue().m_relativeIndex = index++; } m_fastArray = null; return (true); } /** * Remove a {@link CatalogType} object from this collection. * @param name The name of the object to remove. */ public boolean delete(String name) { try { if (m_items.containsKey(name) == false) throw new CatalogException("Catalog item '" + name + "' doesn't exists in " + m_parent); m_items.remove(name); // update versioning if needed updateVersioning(); // assign a relative index to every child item int index = 1; for (Entry<String, T> e : m_items.entrySet()) { e.getValue().m_relativeIndex = index++; } } catch (Exception ex) { throw new RuntimeException(ex); } m_fastArray = null; return (true); } void updateVersioning() { if (m_subTreeVersion != m_catalog.m_currentCatalogVersion) { m_subTreeVersion = m_catalog.m_currentCatalogVersion; m_parent.updateSubTreeVersion(); } } void writeCommandsForMembers(StringBuilder sb) { for (T type : this) { type.writeCreationCommand(sb); type.writeFieldCommands(sb); type.writeChildCommands(sb); } } @SuppressWarnings("unchecked") void copyFrom(CatalogMap<? extends CatalogType> catalogMap) { CatalogMap<T> castedMap = (CatalogMap<T>) catalogMap; for (Entry<String, T> e : castedMap.m_items.entrySet()) { m_items.put(e.getKey(), (T) e.getValue().deepCopy(m_catalog, m_parent)); } m_subTreeVersion = catalogMap.m_subTreeVersion; } @Override public boolean equals(Object obj) { // returning false if null isn't the convention, oh well if (obj == null) return false; if (obj.getClass() != getClass()) return false; @SuppressWarnings("unchecked") CatalogMap<T> other = (CatalogMap<T>) obj; if (other.size() != size()) return false; for (Entry<String, T> e : m_items.entrySet()) { assert(e.getValue() != null); T type = other.get(e.getKey()); if (type == null) return false; if (type.equals(e.getValue()) == false) return false; } return true; } @Override public String toString() { return CatalogUtil.debug(this); } @Override public boolean addAll(Collection<? extends T> c) { boolean ret = true; for (T t : c) { ret = this.add(t) || ret; } return (ret); } @Override public void clear() { m_fastArray = null; this.m_items.clear(); } public boolean containsKey(String key) { return (this.m_items.containsKey(key)); } @Override public boolean contains(Object o) { return (this.m_items.values().contains(o)); } @Override public boolean containsAll(Collection<?> c) { return (this.m_items.values().containsAll(c)); } @Override public boolean remove(Object o) { if (o instanceof CatalogType) { return this.delete(((CatalogType)o).getName()); } return false; } @Override public boolean removeAll(Collection<?> c) { boolean ret = true; for (Object o : c) { ret = this.remove(o) || ret; } return (ret); } @Override public boolean retainAll(Collection<?> c) { // TODO Auto-generated method stub return false; } }