private void computeSharesByClass(ClassInfo classInfo) {
		ArrayList<DatanodeInfo> datanodes = new ArrayList<DatanodeInfo>(this.classToDatanodes.get(classInfo));
		Collections.sort(datanodes, this.datanodeInfoComparator);
		
		// Optimization algorithm per se
		//sub_total_mins = sum([yj*min_coeff for _, _, _, yj, _, _ in marginals])
		BigDecimal sub_total_mins = BigDecimal.ZERO;
		for (DatanodeInfo datanode : datanodes) {
			BigDecimal yj = datanode.getTotalWeight();
			sub_total_mins = sub_total_mins.add(yj.multiply(MIN_COEFF));
		}
		BigDecimal budget = classInfo.getWeight();
		BigDecimal sub_total_sqrt_wy = BigDecimal.ZERO;
		BigDecimal sub_total_y = BigDecimal.ZERO;
		BigDecimal last_coeff = BigDecimal.ZERO;
		int k = 0;
		
		for (DatanodeInfo datanode : datanodes) {
			BigDecimal yj = datanode.getTotalWeight(); // total weights on this datanode, price
			BigDecimal cj = datanode.getCapacity(); // capacity for this datanode
			// sqrt_wy = (yj * cj).sqrt()
			BigDecimal sqrt_wy = sqrt(yj.multiply(cj));
			// sub_total_sqrt_wy += sqrt_wy;
			sub_total_sqrt_wy = sub_total_sqrt_wy.add(sqrt_wy);
			// sub_total_y += yj;
			sub_total_y = sub_total_y.add(yj);
			// sub_total_mins -= yj*min_coeff
			sub_total_mins = sub_total_mins.subtract(yj.multiply(MIN_COEFF));
			// coeff = (budget - sub_total_mins + sub_total_y) / sub_total_sqrt_wy;
			BigDecimal coeff = budget.subtract(sub_total_mins)
									.add(sub_total_y)
									.divide(sub_total_sqrt_wy, CONTEXT);
			// t = (sqrt_wy * coeff) - yj
			BigDecimal t = sqrt_wy.multiply(coeff).subtract(yj);
			//tmin = t - ((min_share*yj / (1 - min_share))
			BigDecimal tmin = t.subtract(MIN_SHARE.multiply(yj)
									           .divide(ONE_MINUS_MIN_SHARE, CONTEXT));
			// if tmin >= 0
			if (tmin.compareTo(BigDecimal.ZERO) >= 0) {
				k++;
				last_coeff = coeff;
			}
			else
				break;
		}
		
		// Update weight on each node with xij higher than min_coeff
		for (int i = 0; i < k; i++) {
			DatanodeInfo datanode = datanodes.get(i);
			BigDecimal yj = datanode.getTotalWeight();
			BigDecimal cj = datanode.getCapacity();
			// xij = ((yj*cj).sqrt() * last_coeff) - yj
			BigDecimal xij = sqrt(yj.multiply(cj))
									 .multiply(last_coeff)
									 .subtract(yj);
			datanode.updateClassWeight(classInfo, xij);
		}
		// Update the rest of nodes with an xij = min_coeff
		for (int i = k; i < datanodes.size(); i++) {
			DatanodeInfo datanode = datanodes.get(i);
			BigDecimal yj = datanode.getTotalWeight();
			// xij = yj * min_coeff
			BigDecimal xij = yj.multiply(MIN_COEFF);
			datanode.updateClassWeight(classInfo, xij);
		}
	}