All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.javanut.pronghorn.pipe.PipeConfigManager Maven / Gradle / Ivy

Go to download

Ring buffer based queuing utility for applications that require high performance and/or a small footprint. Well suited for embedded and stream based processing.

There is a newer version: 1.1.27
Show newest version
package com.javanut.pronghorn.pipe;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class PipeConfigManager {

	private PipeConfig[] configs;
	private int configCount;
	private int defaultMinimumFragmentsOnPipe;
	private int defaultMaximumLengthOfVariableLengthFields;
	private Logger logger = LoggerFactory.getLogger(PipeConfigManager.class);
			
	public PipeConfigManager() {
		this(4, 2, 512);
	}
	
	public PipeConfigManager(int initialCount, int defaultMinimumFragmentsOnPipe, int defaultMaximumLengthOfVariableLengthFields) {
		this.configs = new PipeConfig[initialCount];
		this.configCount = 0;
		this.defaultMinimumFragmentsOnPipe = defaultMinimumFragmentsOnPipe;
		this.defaultMaximumLengthOfVariableLengthFields = defaultMaximumLengthOfVariableLengthFields;
		
	}
	
	public > PipeConfig addConfig(int minimumFragmentsOnPipe,final int maximumLengthOfVariableLengthFields, Class clazz) {
		
		PipeConfig newConfig = MessageSchema
								.findInstance(clazz)
								.newPipeConfig(minimumFragmentsOnPipe, maximumLengthOfVariableLengthFields);
		
		return addConfig(newConfig);
	}

	public > PipeConfig addConfig(PipeConfig newConfig) {
		int idx = findIndex(newConfig.schema);   
		if (idx<0) {

			if (configCount >= configs.length) {
				//grow, we are out of room
				PipeConfig[] newConfigs = new PipeConfig[configs.length*2];
				System.arraycopy(configs, 0, newConfigs, 0, configs.length);
				configs = newConfigs;
			}			
			configs[configCount++] = newConfig;
			
		} else {
			//if (configs[idx].minimumFragmentsOnPipe()>newConfig.minimumFragmentsOnPipe()) {
			//	throw new UnsupportedOperationException("Already ensured size larger than new assignment, use ensure not add.");
			//}
			configs[idx] = newConfig;
		}
		return newConfig;
	}
	

	public > void ensureSize(Class clazz, final int queueLength, final int maxMessageSize) {
		
		int oldQueueLen = 0;
		int oldMaxVarLenSize = 0;
		int idx = 0;
		try {
			idx = findIndex(clazz);
			if (idx>=0) {
				//we found it 
				PipeConfig oldConfig = (PipeConfig)configs[idx];
				
				oldQueueLen = oldConfig.minimumFragmentsOnPipe();
				oldMaxVarLenSize = oldConfig.maxVarLenSize();
	
				if (queueLength>oldQueueLen || maxMessageSize>oldMaxVarLenSize) {
					addConfig(Math.max(oldQueueLen,queueLength), Math.max(oldMaxVarLenSize, maxMessageSize), clazz);
				}
			} else {
				//add it was not found
				addConfig(Math.max(queueLength,defaultMinimumFragmentsOnPipe),
						  Math.max(maxMessageSize, defaultMaximumLengthOfVariableLengthFields),clazz);
			}
		} catch (UnsupportedOperationException t) {
			//report where these values came from
			if (idx >= 0) {
				logger.warn("Max of len from old:{} new:{} ", oldQueueLen, queueLength);
				logger.warn("Max of payload from old:{} new:{} ", oldMaxVarLenSize, maxMessageSize);
			} else {
				logger.warn("Max of len from default:{} new:{} ", defaultMinimumFragmentsOnPipe, queueLength);
				logger.warn("Max of payload from default:{} new:{} ", defaultMaximumLengthOfVariableLengthFields, maxMessageSize);
			}

        	throw(t);
        }
		
	}	
	
    public > PipeConfig getConfig(Class clazz) {
    	
    	S instance = MessageSchema.findInstance(clazz);
		final int idx = findIndex(instance);    	
    	if (idx>=0) {
    		return (PipeConfig)configs[idx];
    	}
		return buildNewConfig(instance);    	
    }

	private > PipeConfig buildNewConfig(S instance) {
		final int maximumLengthOfVariableLengthFields = defaultMaximumLengthOfVariableLengthFields;
    	//when undefined build store and return the default
    	PipeConfig newConfig = instance.newPipeConfig(defaultMinimumFragmentsOnPipe, maximumLengthOfVariableLengthFields);

		if (configCount >= configs.length) {
			//grow, we are out of room
			PipeConfig[] newConfigs = new PipeConfig[configs.length*2];
			System.arraycopy(configs, 0, newConfigs, 0, configs.length);
			configs = newConfigs;
		}			
		configs[configCount++] = newConfig;
		
		return newConfig;
	}

	private > int findIndex(Class clazz) {
		S goal = MessageSchema.findInstance(clazz);
    	return findIndex(goal);
	}

	private > int findIndex(S goal) {
		//this is a simple linear search, this code is normally called with
    	//  1. short lists of configs
    	//  2. on startup
    	//so this is not going to be a problem.
    	int i = configCount;
    	while (--i>=0) {
    		if (configs[i].schema == goal) {
    			break;
    		}
    	}
    	return i;
	}

	public > Pipe newPipe(Class clazz) {		
		return new Pipe(getConfig(clazz));
	}

}