/* This file is part of VoltDB. * Copyright (C) 2008-2017 VoltDB Inc. * * 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 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.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import org.voltdb.catalog.CatalogDiffEngine.DiffClass; /** * Describes the set of changes to a subtree of the catalog. For example, a {@link ChangeGroup} * could describe all of the changes to procedures in a catalog. This is purely used for * printing human readable summaries. */ class CatalogChangeGroup { /** * Given a type present in both catalogs, list the fields * that have changed between them. Together with the types * themselves, you can get the values of the fields before * and after. */ static class FieldChange { CatalogType newType = null; CatalogType prevType = null; final Set<String> changedFields = new HashSet<String>(); } /** * For a particular CatalogType instance, list child additions, deletions, * children with modified fields and personally modified fields. */ static class TypeChanges { CatalogType typeInstance = null; // nodes added under a clz instance, mapped from their parent final List<CatalogType> typeAdditions = new ArrayList<CatalogType>(); // nodes dropped from under a clz instance, mapped from their parent final List<CatalogType> typeDeletions = new ArrayList<CatalogType>(); // all field changes for the clz instance final FieldChange typeChanges = new FieldChange(); // all fields changed for the descendants of the parent clz instance // for each descendant with changed fields, store a list of all changed fields final Map<CatalogType, FieldChange> childChanges = new TreeMap<CatalogType, FieldChange>(); } // the class of the base item in the subtree // for example, procedure final Class<?> clz; // nodes of type clz added List<CatalogType> groupAdditions = new ArrayList<CatalogType>(); // nodes of type clz dropped List<CatalogType> groupDeletions = new ArrayList<CatalogType>(); Map<CatalogType, TypeChanges> groupChanges = new TreeMap<CatalogType, TypeChanges>(); CatalogChangeGroup(DiffClass diffClass) { clz = diffClass.clz; } void processAddition(CatalogType type) { if (type.getClass().equals(clz)) { groupAdditions.add(type); return; } CatalogType parent = type.getParent(); while (parent.getClass().equals(clz) == false) { parent = parent.getParent(); } TypeChanges metaChanges = groupChanges.get(parent); if (metaChanges == null) { metaChanges = new TypeChanges(); metaChanges.typeInstance = parent; groupChanges.put(parent, metaChanges); } metaChanges.typeAdditions.add(type); } void processDeletion(CatalogType type, CatalogType newlyChildlessParent) { if (type.getClass().equals(clz)) { groupDeletions.add(type); return; } // need to use a parent from the new tree, not the old one CatalogType parent = newlyChildlessParent; while (parent.getClass().equals(clz) == false) { parent = parent.getParent(); } TypeChanges metaChanges = groupChanges.get(parent); if (metaChanges == null) { metaChanges = new TypeChanges(); metaChanges.typeInstance = parent; groupChanges.put(parent, metaChanges); } metaChanges.typeDeletions.add(type); } void processChange(CatalogType newType, CatalogType prevType, String field) { CatalogType parent = newType; while (parent.getClass().equals(clz) == false) { parent = parent.getParent(); } TypeChanges metaChanges = groupChanges.get(parent); if (metaChanges == null) { metaChanges = new TypeChanges(); metaChanges.typeInstance = parent; groupChanges.put(parent, metaChanges); } FieldChange fc = null; // object equality is intentional here if (parent == newType) { fc = metaChanges.typeChanges; } else { fc = metaChanges.childChanges.get(newType); if (fc == null) { fc = new FieldChange(); metaChanges.childChanges.put(newType, fc); } } fc.newType = newType; // might be setting this twice, but no harm done fc.prevType = prevType; // ditto fc.changedFields.add(field); } }