Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*-
   * See the file LICENSE for redistribution information.
   *
   * Copyright (c) 2002, 2010 Oracle and/or its affiliates.  All rights reserved.
   *
   */
  
  package com.sleepycat.je.cleaner;
  
 import java.util.List;
 
Iterator over files that should be migrated by cleaning them, even if they don't need to be cleaned for other reasons. Files are migrated either because they are named in the CLEANER_FORCE_CLEAN_FILES parameter or their log version is prior to the CLEANER_UPGRADE_TO_LOG_VERSION parameter. An iterator is used rather than finding the entire set at startup to avoid opening a large number of files to examine their log version. For example, if all files are being migrated in a very large data set, this would involve opening a very large number of files in order to read their header. This could significantly delay application startup. Because we don't have the entire set at startup, we can't select the lowest utilization file from the set to clean next. Inteaad we iterate in file number order to increase the odds of cleaning lower utilization files first.
 
 class FilesToMigrate {
 
     private final EnvironmentImpl env;

    
An array of pairs of file numbers, where each pair is a range of files to be force cleaned. Index i is the from value and i+1 is the to value, both inclusive.
 
     private long[] forceCleanFiles;

    
Log version to upgrade to, or zero if none.
 
     private int upgradeToVersion;

    
Whether to continue checking the log version.
 
     private boolean checkLogVersion;

    
Whether hasNext() has prepared a valid nextFile.
 
     private boolean nextAvailable;

    
File to return; set by hasNext() and returned by next().
 
     private long nextFile;
 
         this. = env;
         String forceCleanProp = env.getConfigManager().get
             (.);
         parseForceCleanFiles(forceCleanProp);
 
          = env.getConfigManager().getInt
         if ( == -1) {
              = .;
         }
 
          = ( != 0);
          = false;
          = -1;
     }

    
Returns whether there are more files to be migrated. Must be called while synchronized on the UtilizationProfile.
 
     boolean hasNext(SortedMap<LongFileSummaryfileSummaryMap) {
         if () {
             /* hasNext() has returned true since the last next(). */
             return true;
         }
         long foundFile = -1;
         for (long file :
              fileSummaryMap.tailMap( + 1).keySet()) {
             if (isForceCleanFile(file)) {
                 /* Found a file to force clean. */
                 foundFile = file;
                 break;
             } else if () {
                 try {
                     int logVersion =
                         .getFileManager().getFileLogVersion(file);
                     if (logVersion < ) {
                        /* Found a file to migrate. */
                        foundFile = file;
                        break;
                    } else {
                        /*
                         * All following files have a log version greater
                         * or equal to this one; stop checking.
                         */
                         = false;
                    }
                } catch (RuntimeException e) {
                    /* Throw exception but allow iterator to continue. */
                     = file;
                    throw e;
                }
            }
        }
        if (foundFile != -1) {
             = foundFile;
             = true;
            return true;
        } else {
            return false;
        }
    }

    
Returns the next file file to be migrated. Must be called while synchronized on the UtilizationProfile.
    long next(SortedMap<LongFileSummaryfileSummaryMap)
        throws NoSuchElementException {
        if (hasNext(fileSummaryMap)) {
             = false;
            return ;
        } else {
            throw new NoSuchElementException();
        }
    }

    
Returns whether the given file is in the forceCleanFiles set.
    private boolean isForceCleanFile(long file) {
        if ( != null) {
            for (int i = 0; i < .i += 2) {
                long from = [i];
                long to = [i + 1];
                if (file >= from && file <= to) {
                    return true;
                }
            }
        }
        return false;
    }

    
Parses the je.cleaner.forceCleanFiles property value and initializes the forceCleanFiles field.

Throws:
java.lang.IllegalArgumentException via Environment ctor and setMutableConfig.
    private void parseForceCleanFiles(String propValue)
        throws IllegalArgumentException {
        if (propValue == null || propValue.length() == 0) {
             = null;
        } else {
            String errPrefix = "Error in " +
                ..getName() +
                "=" + propValue + ": ";
            StringTokenizer tokens = new StringTokenizer
                (propValue",-"true /*returnDelims*/);
            /* Resulting list of Long file numbers. */
            List<Longlist = new ArrayList<Long>();
            while (tokens.hasMoreTokens()) {
                /* Get "from" file number. */
                String fromStr = tokens.nextToken();
                long fromNum;
                try {
                    fromNum = Long.parseLong(fromStr, 16);
                } catch (NumberFormatException e) {
                    throw new IllegalArgumentException
                        (errPrefix + "Invalid hex file number: " +
                         fromStr);
                }
                long toNum = -1;
                if (tokens.hasMoreTokens()) {
                    /* Get delimiter. */
                    String delim = tokens.nextToken();
                    if (",".equals(delim)) {
                        toNum = fromNum;
                    } else if ("-".equals(delim)) {
                        /* Get "to" file number." */
                        if (tokens.hasMoreTokens()) {
                            String toStr = tokens.nextToken();
                            try {
                                toNum = Long.parseLong(toStr, 16);
                            } catch (NumberFormatException e) {
                                throw new IllegalArgumentException
                                    (errPrefix +
                                     "Invalid hex file number: " +
                                     toStr);
                            }
                        } else {
                            throw new IllegalArgumentException
                                (errPrefix + "Expected file number: " +
                                 delim);
                        }
                    } else {
                        throw new IllegalArgumentException
                            (errPrefix + "Expected '-' or ',': " + delim);
                    }
                } else {
                    toNum = fromNum;
                }
                assert toNum != -1;
                list.add(Long.valueOf(fromNum));
                list.add(Long.valueOf(toNum));
            }
             = new long[list.size()];
            for (int i = 0; i < .i += 1) {
                [i] = list.get(i).longValue();
            }
        }
    }
New to GrepCode? Check out our FAQ X