// Path: src/com/ibm/config/PropertiesStore.java
// public class PropertiesStore {
// 	
// 	@PropertiesHolder(file="application.properties", autoLoad=true)
// 	private static Properties appProperties;
// 
// 	public static String getString(String propName) {
// 		return getAppProperties().getProperty(propName);
// 	}
// 	
// 	public static int getInt(String propName) {
// 		return Integer.valueOf(getAppProperties().getProperty(propName));
// 	}
// 	
// 	public static double getDouble(String propName) {
// 		return Double.valueOf(getAppProperties().getProperty(propName));
// 	}
// 
// 	public static boolean getBoolean(String propName) {
// 		return Boolean.valueOf(getAppProperties().getProperty(propName));
// 	}
// 	
// 	public static String[] getStrings(String propName) {
// 		return getAppProperties().getProperty(propName).split(",");
// 	}
// 	
// 	public static Properties getAppProperties() {
// 		if (appProperties==null){
// 			try {
// 				PropertiesLoader.load();
// 			} catch (Exception e) {
// 				e.printStackTrace();
// 			}
// 		}
// 		return appProperties;
// 	}
// 	protected static void setAppProperties(Properties appProperties) {
// 		PropertiesStore.appProperties = appProperties;
// 	}
// }
// 
// Path: src/com/ibm/config/PropertyNames.java
// public class PropertyNames {
// 	
// 	public static final String SAMPLING = "SAMPLING";
// 	public static final String SCAN_COMP_ALG = "SCAN_COMP_ALG";
// 	public static final String ACCURACY = "ACCURACY";
// 	public static final String CONFIDENCE = "CONFIDENCE";
// 	public static final String SCAN_CHUNK_SIZE = "SCAN_CHUNK_SIZE";
// 	public static final String DATA_GENERATION = "DATA_GENERATION";
// 	public static final String T_MIN = "T_MIN";
// 	public static final String T_MAX = "T_MAX";
// 	public static final String RABIN_WINDOW_SIZE = "RABIN_WINDOW_SIZE";
// 	public static final String GENERATION_CHUNK_SIZE = "GENERATION_CHUNK_SIZE";
// 	public static final String ENABLE_DEDUP = "ENABLE_DEDUP";
// 	public static final String CHUNK_SCANNERS = "CHUNK_SCANNERS";
// 	public static final String CHUNK_CHARACTERIZATION = "CHUNK_CHARACTERIZATION";
// 	public static final String TEST_COMPRESSORS = "TEST_COMPRESSORS";
// 	
// }


import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.rabinfingerprint.fingerprint.RabinFingerprintLong;
import org.rabinfingerprint.fingerprint.RabinFingerprintLongWindowed;
import org.rabinfingerprint.handprint.BoundaryDetectors;
import org.rabinfingerprint.handprint.FingerFactory.ChunkBoundaryDetector;
import org.rabinfingerprint.polynomial.Polynomial;
import com.ibm.config.PropertiesStore;
import com.ibm.config.PropertyNames;
/*
 * Copyright (C) 2014 Raul Gracia-Tinedo
 * 
 * This program is free software: you can redistribute it and/or modify it under 
 * the terms of the GNU 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with 
 * this program. If not, see http://www.gnu.org/licenses/.
 */
package com.ibm.deduplication;




/**
 * Content-based chunking mechanisms based on Rabin fingerprint to detect the
 * deduplication ratio of data. 
 * 
 * @author Raul Gracia-Tinedo (raulgraciatinedo@gmail.com)
 *
 */
public class ContentBasedChunking {

	static long bytesPerWindow = PropertiesStore.getInt(PropertyNames.RABIN_WINDOW_SIZE);
	static Polynomial p = Polynomial.createFromLong(10923124345206883L);
	private RabinFingerprintLong fingerHash = new RabinFingerprintLong(p);
	private RabinFingerprintLongWindowed fingerWindow = new RabinFingerprintLongWindowed(p, bytesPerWindow);
	private ChunkBoundaryDetector boundaryDetector = BoundaryDetectors.DEFAULT_BOUNDARY_DETECTOR;
// Path: src/com/ibm/config/PropertiesStore.java
// public class PropertiesStore {
// 	
// 	@PropertiesHolder(file="application.properties", autoLoad=true)
// 	private static Properties appProperties;
// 
// 	public static String getString(String propName) {
// 		return getAppProperties().getProperty(propName);
// 	}
// 	
// 	public static int getInt(String propName) {
// 		return Integer.valueOf(getAppProperties().getProperty(propName));
// 	}
// 	
// 	public static double getDouble(String propName) {
// 		return Double.valueOf(getAppProperties().getProperty(propName));
// 	}
// 
// 	public static boolean getBoolean(String propName) {
// 		return Boolean.valueOf(getAppProperties().getProperty(propName));
// 	}
// 	
// 	public static String[] getStrings(String propName) {
// 		return getAppProperties().getProperty(propName).split(",");
// 	}
// 	
// 	public static Properties getAppProperties() {
// 		if (appProperties==null){
// 			try {
// 				PropertiesLoader.load();
// 			} catch (Exception e) {
// 				e.printStackTrace();
// 			}
// 		}
// 		return appProperties;
// 	}
// 	protected static void setAppProperties(Properties appProperties) {
// 		PropertiesStore.appProperties = appProperties;
// 	}
// }
// 
// Path: src/com/ibm/config/PropertyNames.java
// public class PropertyNames {
// 	
// 	public static final String SAMPLING = "SAMPLING";
// 	public static final String SCAN_COMP_ALG = "SCAN_COMP_ALG";
// 	public static final String ACCURACY = "ACCURACY";
// 	public static final String CONFIDENCE = "CONFIDENCE";
// 	public static final String SCAN_CHUNK_SIZE = "SCAN_CHUNK_SIZE";
// 	public static final String DATA_GENERATION = "DATA_GENERATION";
// 	public static final String T_MIN = "T_MIN";
// 	public static final String T_MAX = "T_MAX";
// 	public static final String RABIN_WINDOW_SIZE = "RABIN_WINDOW_SIZE";
// 	public static final String GENERATION_CHUNK_SIZE = "GENERATION_CHUNK_SIZE";
// 	public static final String ENABLE_DEDUP = "ENABLE_DEDUP";
// 	public static final String CHUNK_SCANNERS = "CHUNK_SCANNERS";
// 	public static final String CHUNK_CHARACTERIZATION = "CHUNK_CHARACTERIZATION";
// 	public static final String TEST_COMPRESSORS = "TEST_COMPRESSORS";
// 	
// }


// Path: src/com/ibm/deduplication/ContentBasedChunking.java
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.rabinfingerprint.fingerprint.RabinFingerprintLong;
import org.rabinfingerprint.fingerprint.RabinFingerprintLongWindowed;
import org.rabinfingerprint.handprint.BoundaryDetectors;
import org.rabinfingerprint.handprint.FingerFactory.ChunkBoundaryDetector;
import org.rabinfingerprint.polynomial.Polynomial;
import com.ibm.config.PropertiesStore;
import com.ibm.config.PropertyNames;

/*
 * Copyright (C) 2014 Raul Gracia-Tinedo
 * 
 * This program is free software: you can redistribute it and/or modify it under 
 * the terms of the GNU 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with 
 * this program. If not, see http://www.gnu.org/licenses/.
 */
package com.ibm.deduplication;




/**
 * Content-based chunking mechanisms based on Rabin fingerprint to detect the
 * deduplication ratio of data. 
 * 
 * @author Raul Gracia-Tinedo (raulgraciatinedo@gmail.com)
 *
 */
public class ContentBasedChunking {

	static long bytesPerWindow = PropertiesStore.getInt(PropertyNames.RABIN_WINDOW_SIZE);
	static Polynomial p = Polynomial.createFromLong(10923124345206883L);
	private RabinFingerprintLong fingerHash = new RabinFingerprintLong(p);
	private RabinFingerprintLongWindowed fingerWindow = new RabinFingerprintLongWindowed(p, bytesPerWindow);
	private ChunkBoundaryDetector boundaryDetector = BoundaryDetectors.DEFAULT_BOUNDARY_DETECTOR;
	private final static int MIN_CHUNK_SIZE = PropertiesStore.getInt(PropertyNames.T_MIN);