/* * Copyright (C) 2010 Medo <smaxein@googlemail.com> * * This file is part of GmkSplitter. * GmkSplitter is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package com.ganggarrison.gmdec.dupes; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * This dupe removal strategy will preserve the order of all items with valid * IDs. It tries to prevent changing IDs unless neccessary. Items without valid * IDs will be inserted at the upper end of the range. */ public class OrderPreservingDupeRemoval { public static <Item> void perform(ItemAccessor<Item> accessor) { int changed = 0; List<Item> items = accessor.getItems(); List<Item> invalidIdItems = new ArrayList<Item>(); TreeMultiMap<Integer, Item> itemsById = new TreeMultiMap<Integer, Item>(); for (Item item : items) { Integer id = accessor.getId(item); if (id == null) { invalidIdItems.add(item); } else { itemsById.add(id, item); } } int nextFreeItemId = accessor.getFirstValidId(); for (Map.Entry<Integer, List<Item>> entry : itemsById) { for (Item item : entry.getValue()) { int id = entry.getKey(); if (id >= nextFreeItemId) { nextFreeItemId = id + 1; } else { accessor.setId(item, nextFreeItemId++); changed++; } } } for (Item item : invalidIdItems) { accessor.setId(item, nextFreeItemId++); } accessor.setMaxId(nextFreeItemId - 1); if (changed > 0) { System.err.println("INFO: " + changed + " duplicate " + accessor.getItemName() + " IDs have been changed."); } if (invalidIdItems.size() > 0 && accessor.informAboutNewIds()) { System.err.println("INFO: " + invalidIdItems.size() + " new " + accessor.getItemName() + " IDs have been assigned."); } } }