function [xc] = consolidate(x, rmax)
% OBSOLETE
% This function consolidates the allocation matrix x to remove partitions
% without affecting the response time percentiles.
% x: initial non-consolidates matrix
% resources: resources types

	[u, v] = size(x);
	xc = x;
	%maxi = 1;
	
	while (true)
		xc0 = xc;
		
		% reallocate unused rates
		for ii=1:v
			for jj=1:u
				if x(jj,ii)>0
					if excessfree(xc, jj, ii, rmax)>=x(jj,ii)
						xc = reallocatefree(xc, jj, ii, rmax);
					end
				end
			end
		end
	
		% perform swaps
		for ii1=1:v-1
			for ii2=ii1+1:v
				xc=performswap(xc, ii1, ii2, rmax);
			end
		end
		
		% exit if no more modifications are possible
		if all(xc0==xc)
			break;
		end
		
		%maxi = maxi - 1;
	end
end

function [xnew] = performswap(x, y1, y2, rmax)
	
	[u, ~] = size(x);
	mdn = max([mean(x,2) median(x,2)],[],2);
	xnew = x;
	
	for m1=1:u
		for m2=1:u
			
			if xnew(m1,y2)<=0 || xnew(m2,y1)<=0 || xnew(m1,y1)<=0 || xnew(m2,y2)<=0
				continue;
			end
			
			outgoing1m1 = max([0 xnew(m1,y1)-mdn(m1)]);
			outgoing2m2 = max([0 xnew(m2,y2)-mdn(m2)]);
			
			excess1 = rmax-sum(xnew(:,y1));
			excess2 = rmax-sum(xnew(:,y2));
			
			transfer = min([outgoing1m1+excess2 outgoing2m2+excess1]);
			
			xnew(m1,y1) = xnew(m1,y1) - transfer;
			xnew(m1,y2) = xnew(m1,y2) + transfer;
			xnew(m2,y1) = xnew(m2,y1) + transfer;
			xnew(m2,y2) = xnew(m2,y2) - transfer;
		end
	end

end

function [res] = excessfree(x, m, y, rmax)
	% Calculate the resources excess available for allocating service "m"
	% running on "y" to other non-y resources running "m".

	[~, v] = size(x);
	res = 0;
	
	for ii=1:v
		if ii==y || x(m,ii)==0
			continue;
		end
		
		res = res + rmax - sum(x(:,ii));
	end

end


function [newx] = reallocatefree(x, m, y, rmax)
	[~, v] = size(x);
	newx = x;

	for ii=1:v
		if newx(m,y) <= 0
			return
		end
		
		if ii==y || newx(m,ii)==0
			continue;
		end
		
		excessii = rmax - sum(newx(:,ii));
		transfer = min([excessii newx(m,y)]);
		
		newx(m,y) = newx(m,y) - transfer;
		newx(m,ii) = newx(m,ii) + transfer;
	end
end
	