001    /*
002     * SingleCopySelector.java
003     *
004     * Created on March 13, 2003, 10:52 AM
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    package gov.bnl.star.offline.scheduler.policy.copyselector;
024    
025    import gov.bnl.star.offline.scheduler.CatalogQuery;
026    import gov.bnl.star.offline.scheduler.catalog.PhysicalFile;
027    import gov.bnl.star.offline.scheduler.catalog.QueryResult;
028    import gov.bnl.star.offline.scheduler.policy.FileAssignment;
029    
030    import java.util.*;
031    
032    
033    /**
034     * Choses a copy for each files randomly, taking into consideration the
035     * preferStorage. It doesn't use minFilesPerProcess.
036     *
037     * @author Gabriele Carcassi & Pavel Jakl
038     */
039    public class SingleCopySelector implements CopySelector {
040    
041        private boolean HPSSAllowed;
042    
043        public SingleCopySelector(boolean HPSSFiles) {
044            this.HPSSAllowed = HPSSFiles;
045        }
046    
047        public int selectCopy(QueryResult list, CatalogQuery query,
048                              FileAssignment assignment) {
049            Random rand = new Random();
050            int currentFile = 0;
051    
052            Set logicalIDs = list.getLogicalNames();
053            Iterator iter = logicalIDs.iterator();
054    
055            while (iter.hasNext()) {
056                List physicalFiles = list.getCopies(iter.next());
057    
058                PhysicalFile toAdd = null;
059    
060                // If there is a preferred storage, scan the physical files
061                // for a match (preferStorage cannot be HPSS if xrootdSyntax is not Available)
062                if (query.getPreferStorage() != null) {
063                    List preferedFiles = new ArrayList();
064                    Iterator iterPhys = physicalFiles.iterator();
065    
066                    while (iterPhys.hasNext()) {
067                        PhysicalFile temp = (PhysicalFile) iterPhys.next();
068    
069                        if (query.getPreferStorage().equals(temp.getStorage())) {
070                            preferedFiles.add(temp);
071                        }
072                    }
073    
074                    // Once all the matches are found, pick one.
075                    if (preferedFiles.size() != 0) {
076                        Collections.shuffle(preferedFiles);
077                        toAdd = (PhysicalFile) preferedFiles.get(0);
078                    }
079                }
080    
081                // If the preferred storage wasn't found, or if no file matched,
082                // get random, if random is HPSS and HPSS is not allowed, continue in randomize
083                if (toAdd == null) {
084                    toAdd = (PhysicalFile) physicalFiles.get(rand.nextInt(physicalFiles.size()));
085                    if (!HPSSAllowed) {
086                        notFound:
087                                            while ("HPSS".equals(toAdd.getStorage())) {
088                                                // check due to infinite loop (LFN can have only HPSS PFN)
089                                                if (physicalFiles.size() != 1) {
090                                                    toAdd = (PhysicalFile) physicalFiles.get(rand.nextInt(physicalFiles.size()));
091                                                } else {
092                                                    toAdd = null;
093                                                    break notFound;
094                                                }
095                                            }
096                    }
097                }
098                if (toAdd != null) {
099                    assignment.add(toAdd);
100                    currentFile++;
101                }
102            }
103    
104            return currentFile;
105        }
106    }