private long _weightBalanceThreshold = 0 ; //at what weight should the node be treated as contributor to incoming nodes. public DistributionMatrix(ArrayList weightIdList, Address address, DistributionData distData, ILogger NCacheLog) { _address = address; _distData = distData; _filteredWeightIdList = new ArrayList(); _itemsCount = weightIdList.Count; _totalWeight = 1; _weightToSacrifice = 0; _cushionFactor = 10; _percentWeightToSacrifice = 0; _weightBalanceThreshold = Convert.ToInt32((_maxCacheSize * WeightBalanceThresholdPercent) / 100); //10%, threshold at which we feel to balance weight for incoming nodes. its value is percent of MaxCacheSize if (NCacheLog.IsInfoEnabled) NCacheLog.Error("DistributionMatrix.ctor", "Address->" + address.ToString() + ", DistributionData->" + distData.ToString()); //muds: //this is the temp code just to put some trace... int bucketCount = 0; foreach (WeightIdPair wiPair in weightIdList) { if (wiPair.Address.compare(address) == 0) { if(NCacheLog.IsInfoEnabled) NCacheLog.Info("DistributionMatrix.ctor", "waitPair" + wiPair.Address.ToString() + ", wiPait->" + wiPair.BucketId); _filteredWeightIdList.Add(wiPair); bucketCount++; } } if (NCacheLog.IsInfoEnabled) NCacheLog.Info("DistributionMatrix..ctor", address + " owns " + bucketCount + " buckets"); _filteredWeightIdList.Sort(); if (NCacheLog.IsInfoEnabled) NCacheLog.Info("DistributionMatrix.ctor", "_filterWeightIdList.Count:" + _filteredWeightIdList.Count + ", distData.BucketPerNode: " + distData.BucketsPerNode); //Current bucket count - bucketss count after division gives buckets count to be sacrificed. _bucketsToSacrifice = _filteredWeightIdList.Count - distData.BucketsPerNode; if (_bucketsToSacrifice <= 0) { NCacheLog.Error("DistributionMatrix", "Address::" + address.ToString() + " cant sacrifice any bucket. Buckets/Node = " + distData.BucketsPerNode + " My Buckets Count = " + _filteredWeightIdList.Count); return; } int rows = Convert.ToInt32(Math.Ceiling((double)((decimal)_filteredWeightIdList.Count /(decimal)_bucketsToSacrifice))); int cols = _bucketsToSacrifice; InitializeMatrix(rows, cols); }
public static ArrayList BalanceBuckets(DistributionInfoData distInfo, ArrayList hashMap, Hashtable bucketStats, ArrayList members,long cacheSizePerNode ,ILogger NCacheLog) { DistributionData distData = new DistributionData(hashMap, bucketStats, members, NCacheLog, cacheSizePerNode); Boolean bShouldBalanceWeight = false; if (distInfo.DistribMode == DistributionMode.AvgWeightTime) //If weight and time to move has to be avg. Cut the weight to half. { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request comes with DistributionMode.AvgWeightTime"); distData.WeightPerNode/= 2; } ArrayList distMatrix = distData.DistributionMatrixForNodes; ArrayList finalBuckets = new ArrayList(); //We need to cater for the cases where we dont need to actually balance the data over nodes, as cluster itself is starting //and no actual load is present within a cluster and on each node. foreach (DistributionMatrix dMatrix in distMatrix) { if (dMatrix.DoWeightBalance == true) { bShouldBalanceWeight = true; break; } } //If cluster is not loaded only shuffled disribution is required. No need to balance any weight. if (bShouldBalanceWeight == false) { if (NCacheLog.IsInfoEnabled) NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Cluster is not loaded only shuffled disribution is required. No need to balance any weight."); distInfo.DistribMode = DistributionMode.ShuffleBuckets; } //For cases below we also need to calculate Weight to be balanced along with buckets sacrifices. switch (distInfo.DistribMode) { case DistributionMode.OptimalTime: foreach (DistributionMatrix dMatrix in distMatrix) { int [,] IdMatrix = dMatrix.IdMatrix; for (int i = 0; i < dMatrix.MatrixDimension.Cols; i++) finalBuckets.Add(IdMatrix[0, i]); //Always first row of the matrix to be given } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.OptimalTime"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) NCacheLog.Info(finalBuckets[i].ToString()); } return finalBuckets; case DistributionMode.ShuffleBuckets: //Although code replication is observed here. Still I prefer to make its copy rather puting fewer if-else to control. I need some time efficiency here. foreach (DistributionMatrix dMatrix in distMatrix) { int[,] IdMatrix = dMatrix.IdMatrix; int[] resultIndices; RowsBalanceResult rbResult = DistributionCore.ShuffleSelect(dMatrix); resultIndices = rbResult.ResultIndicies; for (int i = 0, j = 0; i < resultIndices.Length; i++) { int index = resultIndices[i]; //Index would never be zero, rather the value corresponding in the Matrix be zero. //Get row and col on the basis of matrix index (index of one-D array). int row = index / dMatrix.MatrixDimension.Cols; int col = index % dMatrix.MatrixDimension.Cols; if (IdMatrix[row, col] == -1) //dealing with exceptional case when last row is selected and it got few non-indices.So replace those with lowest most indices in the matrix. { finalBuckets.Add(IdMatrix[0, j]); j++; } else { finalBuckets.Add(IdMatrix[row, col]); } } } if (NCacheLog.IsInfoEnabled ) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.ShuffleBuckets"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) NCacheLog.Info(finalBuckets[i].ToString()); } return finalBuckets; case DistributionMode.OptimalWeight: //For both same code works. Change is only in weight that is modified above . it is called FallThrough in switch statements. case DistributionMode.AvgWeightTime: foreach (DistributionMatrix dMatrix in distMatrix) { int[,] IdMatrix = dMatrix.IdMatrix; int[] resultIndices; RowsBalanceResult rbResult = DistributionCore.CompareAndSelect(dMatrix); resultIndices = rbResult.ResultIndicies; for (int i = 0,j=0; i < resultIndices.Length; i++) { int index = resultIndices[i]; //Index would never be zero, rather the value corresponding in the Matrix be zero. //Get row and col on the basis of matrix index (index of one-D array). int row = index / dMatrix.MatrixDimension.Cols; int col = index % dMatrix.MatrixDimension.Cols; if (IdMatrix[row, col] == -1) //dealing with exceptional case when last row is selected and it got few non-indices.So replace those with lowest most indices in the matrix. { finalBuckets.Add(IdMatrix[0,j]); j++; } else { finalBuckets.Add(IdMatrix[row, col]); } } } if (NCacheLog.IsInfoEnabled ) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.AvgWeightTime/ DistributionMode.OptimalWeight"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) NCacheLog.Info(finalBuckets[i].ToString()); } return finalBuckets; default: break; } //end switch return null; } //end func.
public static ArrayList BalanceBuckets(DistributionInfoData distInfo, ArrayList hashMap, Hashtable bucketStats, ArrayList members, long cacheSizePerNode, ILogger NCacheLog) { DistributionData distData = new DistributionData(hashMap, bucketStats, members, NCacheLog, cacheSizePerNode); Boolean bShouldBalanceWeight = false; if (distInfo.DistribMode == DistributionMode.AvgWeightTime) //If weight and time to move has to be avg. Cut the weight to half. { if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request comes with DistributionMode.AvgWeightTime"); } distData.WeightPerNode /= 2; } ArrayList distMatrix = distData.DistributionMatrixForNodes; ArrayList finalBuckets = new ArrayList(); //We need to cater for the cases where we don't need to actually balance the data over nodes, as cluster itself is starting //and no actual load is present within a cluster and on each node. foreach (DistributionMatrix dMatrix in distMatrix) { if (dMatrix.DoWeightBalance == true) { bShouldBalanceWeight = true; break; } } //If cluster is not loaded only shuffled distribution is required. No need to balance any weight. if (bShouldBalanceWeight == false) { if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Cluster is not loaded only shuffled distribution is required. No need to balance any weight."); } distInfo.DistribMode = DistributionMode.ShuffleBuckets; } //For cases below we also need to calculate Weight to be balanced along with buckets sacrifices. switch (distInfo.DistribMode) { case DistributionMode.OptimalTime: foreach (DistributionMatrix dMatrix in distMatrix) { int [,] IdMatrix = dMatrix.IdMatrix; for (int i = 0; i < dMatrix.MatrixDimension.Cols; i++) { finalBuckets.Add(IdMatrix[0, i]); //Always first row of the matrix to be given } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.OptimalTime"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) { NCacheLog.Info(finalBuckets[i].ToString()); } } return(finalBuckets); case DistributionMode.ShuffleBuckets: //Although code replication is observed here. Still I prefer to make its copy rather putting fewer if-else to control. I need some time efficiency here. foreach (DistributionMatrix dMatrix in distMatrix) { int[,] IdMatrix = dMatrix.IdMatrix; int[] resultIndices; RowsBalanceResult rbResult = DistributionCore.ShuffleSelect(dMatrix); resultIndices = rbResult.ResultIndicies; for (int i = 0, j = 0; i < resultIndices.Length; i++) { int index = resultIndices[i]; //Index would never be zero, rather the value corresponding in the Matrix be zero. //Get row and col on the basis of matrix index (index of one-D array). int row = index / dMatrix.MatrixDimension.Cols; int col = index % dMatrix.MatrixDimension.Cols; if (IdMatrix[row, col] == -1) //dealing with exceptional case when last row is selected and it got few non-indices.So replace those with lowest most indices in the matrix. { finalBuckets.Add(IdMatrix[0, j]); j++; } else { finalBuckets.Add(IdMatrix[row, col]); } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.ShuffleBuckets"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) { NCacheLog.Info(finalBuckets[i].ToString()); } } return(finalBuckets); case DistributionMode.OptimalWeight: //For both same code works. Change is only in weight that is modified above . it is called FallThrough in switch statements. case DistributionMode.AvgWeightTime: foreach (DistributionMatrix dMatrix in distMatrix) { int[,] IdMatrix = dMatrix.IdMatrix; int[] resultIndices; RowsBalanceResult rbResult = DistributionCore.CompareAndSelect(dMatrix); resultIndices = rbResult.ResultIndicies; for (int i = 0, j = 0; i < resultIndices.Length; i++) { int index = resultIndices[i]; //Index would never be zero, rather the value corresponding in the Matrix be zero. //Get row and col on the basis of matrix index (index of one-D array). int row = index / dMatrix.MatrixDimension.Cols; int col = index % dMatrix.MatrixDimension.Cols; if (IdMatrix[row, col] == -1) //dealing with exceptional case when last row is selected and it got few non-indices.So replace those with lowest most indices in the matrix. { finalBuckets.Add(IdMatrix[0, j]); j++; } else { finalBuckets.Add(IdMatrix[row, col]); } } } if (NCacheLog.IsInfoEnabled) { NCacheLog.Info("DistributionImpl.BalanceBuckets()", "Request is DistributionMode.AvgWeightTime/ DistributionMode.OptimalWeight"); NCacheLog.Info("Selected Buckets are: -"); for (int i = 0; i < finalBuckets.Count; i++) { NCacheLog.Info(finalBuckets[i].ToString()); } } return(finalBuckets); default: break; } //end switch return(null); } //end func.