001 /* 002 * RootdMinMaxSingleCopySelector.java 003 * 004 * Created on April 28, 2003, 1:13 PM 005 * 006 * This file is part of the STAR Scheduler. 007 * Copyright (c) 2002-2006 STAR Collaboration - Brookhaven National Laboratory 008 * 009 * STAR Scheduler is free software; you can redistribute it and/or modify 010 * it under the terms of the GNU General Public License as published by 011 * the Free Software Foundation; either version 2 of the License, or 012 * (at your option) any later version. 013 * 014 * STAR Scheduler is distributed in the hope that it will be useful, 015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 017 * GNU General Public License for more details. 018 * 019 * You should have received a copy of the GNU General Public License 020 * along with STAR Scheduler; if not, write to the Free Software 021 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 022 */ 023 024 package gov.bnl.star.offline.scheduler.policy.copyselector; 025 026 import gov.bnl.star.offline.scheduler.CatalogQuery; 027 import gov.bnl.star.offline.scheduler.catalog.QueryResult; 028 import gov.bnl.star.offline.scheduler.policy.FileAssignment; 029 import gov.bnl.star.offline.scheduler.policy.Location; 030 import java.util.*; 031 import org.apache.log4j.Logger; 032 033 /** 034 * 035 * @author Gabriele Carcassi 036 */ 037 public class RootdMinMaxSingleCopySelector extends MinMaxSingleCopySelector { 038 static private Logger log = Logger.getLogger(RootdMinMaxSingleCopySelector.class.getName()); 039 040 public int selectCopy(QueryResult list, CatalogQuery query, 041 FileAssignment assignment) { 042 this.assignment = assignment; 043 int nFiles = super.selectCopy(list, query, assignment); 044 if (!assignment.isValid()) { 045 log.debug("Using rootd local file distribution. Intital summary " + assignment.getSummary()); 046 moveLocalInvalid(); 047 log.debug("Using rootd local file distribution. End summary " + assignment.getSummary()); 048 } 049 return nFiles; 050 } 051 052 private List invalidLocations; 053 private FileAssignment assignment; 054 055 private void moveLocalInvalid() { 056 // Get the list of invalid locations 057 invalidLocations = new ArrayList(assignment.getInvalidLocations()); 058 log.debug("Invalid locations: " + invalidLocations); 059 060 // Order them by number of surplus files 061 Collections.sort(invalidLocations, new Comparator() { 062 public int compare(Object obj1, Object obj2) { 063 return Double.compare(assignment.needsLessFiles((Location)obj1), 064 assignment.needsLessFiles((Location)obj2)); 065 } 066 }); 067 log.debug("Invalid locations by dimension: " + invalidLocations); 068 069 // Keeps moving files from the location with the least surplus to the 070 // the one with the most. This will end when there is 1 or 0 locations 071 // left 072 while(invalidLocations.size() > 1) { 073 Location mostFiles = (Location) invalidLocations.get(invalidLocations.size() - 1); 074 Location leastFiles = (Location) invalidLocations.get(0); 075 076 moveNeededCopies(leastFiles, mostFiles); 077 log.debug("Invalid locations by dimension: " + invalidLocations); 078 } 079 080 // Move the remaining files on the processes 081 // Making a copy of the locations because the set will be modified 082 // while iterating 083 Iterator iter = new ArrayList(assignment.getLocations()).iterator(); 084 085 if(invalidLocations.size() != 0){ //Bugfix: If all the files are removed from the last location, it will be destroyed and so no files need salvaging. (LBH) 086 087 Location lastLocation = (Location) invalidLocations.get(0); 088 while ((assignment.getFiles(lastLocation) != null) && iter.hasNext()) { 089 Location location = (Location) iter.next(); 090 if (location.equals(lastLocation)) continue; 091 moveCopies(lastLocation, location); 092 log.debug("Last invalid location: " + invalidLocations); 093 } 094 095 } 096 097 } 098 099 /** Moves some or all the files from the source to fill the destination 100 * requirements. 101 */ 102 private void moveNeededCopies(Location source, Location dest) { 103 log.debug("Moving needed files from " + source + " to " + dest); 104 int filesToMove = assignment.needsLessFiles(source); 105 int filesCanMove = assignment.needsMoreFiles(dest); 106 int nFiles = Math.min(filesToMove, filesCanMove); 107 108 109 moveCopies(source, dest, nFiles); 110 } 111 112 /** Moves some or all the files from the source without changing the 113 * number of jobs on the destination. 114 */ 115 private void moveCopies(Location source, Location dest) { 116 log.debug("Moving all files from " + source + " to " + dest); 117 int filesToMove = assignment.needsLessFiles(source); 118 int filesCanMove = assignment.canAdd(dest); 119 int nFiles = Math.min(filesToMove, filesCanMove); 120 121 moveCopies(source, dest, nFiles); 122 } 123 124 /** Copies some files from the source to the destination. 125 */ 126 private void moveCopies(Location source, Location dest, int nFiles) { 127 log.debug("Moving " + nFiles + " files from " + source + " to " + dest); 128 List files = new ArrayList(); 129 for (int n = 0; n < nFiles; n++) { 130 files.add(assignment.getFiles(source).get(n)); 131 } 132 133 assignment.removeAllPhysical(source, files); 134 assignment.addAllPhysical(dest, files); 135 if (assignment.getFiles(source) == null) invalidLocations.remove(source); 136 if (assignment.isValid(dest)) invalidLocations.remove(dest); 137 } 138 139 }