public NodeBalanceData(ArrayList hashMap, Hashtable bucketStatistics, ArrayList members) { _percentWeightPerNode = 100 / members.Count; _members = members; int memberCount = _members.Count; _hashMapData = new ArrayList(memberCount); _cacheDataSum = 1; ArrayList _weightIdList = new ArrayList(); for (int i = 0; i < DistributionManager.TotalBuckets; i++) { HashMapBucket hmapBuck = (HashMapBucket)hashMap[i]; BucketStatistics buckStats = (BucketStatistics)bucketStatistics[i]; if (hmapBuck.Status != BucketStatus.UnderStateTxfr) //include only those buckets that are Functional { WeightIdPair listItem = new WeightIdPair(hmapBuck.BucketId, buckStats.DataSize, hmapBuck.PermanentAddress); _weightIdList.Add(listItem); } _cacheDataSum += buckStats.DataSize; //Lets get the TOTAL weight of the cluster. } _weightPerNode = _cacheDataSum / memberCount; _balanceDataListForNodes = new ArrayList(memberCount); foreach (Address mbr in _members) { BalanceDataForNode balanceData = new BalanceDataForNode(_weightIdList, mbr, _cacheDataSum); _balanceDataListForNodes.Add(balanceData); } }
public NodeBalanceData(ArrayList hashMap, Hashtable bucketStatistics, ArrayList members) { _percentWeightPerNode = 100/members.Count; _members = members; int memberCount = _members.Count; _hashMapData = new ArrayList(memberCount); _cacheDataSum = 1; ArrayList _weightIdList = new ArrayList(); for (int i = 0; i < DistributionManager.TotalBuckets; i++) { HashMapBucket hmapBuck = (HashMapBucket)hashMap[i]; BucketStatistics buckStats = (BucketStatistics)bucketStatistics[i]; if (hmapBuck.Status != BucketStatus.UnderStateTxfr) //include only those buckets that are Functional { WeightIdPair listItem = new WeightIdPair(hmapBuck.BucketId, buckStats.DataSize, hmapBuck.PermanentAddress); _weightIdList.Add(listItem); } _cacheDataSum += buckStats.DataSize; //Lets get the TOTAL weight of the cluster. } _weightPerNode = _cacheDataSum / memberCount; _balanceDataListForNodes = new ArrayList(memberCount); foreach (Address mbr in _members) { BalanceDataForNode balanceData = new BalanceDataForNode(_weightIdList, mbr,_cacheDataSum); _balanceDataListForNodes.Add(balanceData); } }
private void ApplyChangesInHashMap(BalanceDataForNode secNode) { ArrayList weightIdPair = secNode.WeightIdList; Address newAddr = secNode.NodeAddress; HashMapBucket bucket = null; foreach (WeightIdPair widPair in weightIdPair) { bucket = (HashMapBucket)_hashMap[widPair.BucketId]; if (!newAddr.Equals(bucket.TempAddress)) { bucket.Status = BucketStatus.NeedTransfer; } bucket.TempAddress = newAddr; } }
//Need to check if the source node really needs any balancing?. If the weight is more then the Avg weight/Node then its true else false. private bool SanityCheckForCandidateNode(Address sourceNode) { ArrayList dataListForNodes = _nodeBalData.BalanceDataListForNodes; foreach (BalanceDataForNode balData in dataListForNodes) { if (balData.NodeAddress.Equals(sourceNode)) { if (balData.PercentData > _nodeBalData.PercentWeightPerNode) { this._weightToMove = balData.TotalWeight - this._nodeBalData.WeightPerNode; //Weight to move is the one that is above the Avg. weight the node Should bear. _primaryNode = balData; return(true); } else { return(false); } } } //end foreach loop return(false); //nothing found. }
public DistributionMaps BalanceNodes(DistributionInfoData distInfo, ArrayList hashMap, Hashtable bucketStats, ArrayList members) { _hashMap = hashMap; _nodeBalData = new NodeBalanceData(hashMap, bucketStats, members); //Check if any other state transfer is not in progress... bool bAllFunctional = this.SanityCheckForAllFunctional(hashMap); //Add some status saying that node balancing is not possible at the moment. if (!bAllFunctional) { DistributionMaps result = new DistributionMaps(BalancingResult.AlreadyInBalancing); return(result); } //Check if really the node needs some balancing or not. bool bShouldBalance = this.SanityCheckForCandidateNode((Address)distInfo.AffectedNode.NodeAddress); if (!bShouldBalance) { DistributionMaps result = new DistributionMaps(BalancingResult.NotRequired); return(result); } ArrayList dataListForNodes = _nodeBalData.BalanceDataListForNodes; ArrayList candidates = FilterCandidateNodes(); foreach (AddressWeightPair awPair in candidates) { BalanceDataForNode secNode = GetBalDataForNode(awPair.NodeAddress); BalanceTwoNodes(_primaryNode, secNode, awPair.WeightShare); ApplyChangesInHashMap(secNode); } ApplyChangesInHashMap(_primaryNode); return(new DistributionMaps(_hashMap, null)); }
//data to be moved from Primary node to the secondary node. //As a result priNode and secNode got updated WeightIdPairLists. private static void BalanceTwoNodes(BalanceDataForNode priNode, BalanceDataForNode secNode, long dataToMove) { int priBucketCount = priNode.ItemsCount; int secBucketCount = secNode.ItemsCount; ArrayList priWIPairList = priNode.WeightIdList; ArrayList secWIPairList = secNode.WeightIdList; int cushionFactor = 10; // 10% cushion for balancing... +- 10% long swapWeightGain = 0; // weight gain for this swap long cushionWeight = Convert.ToInt64(((double)(dataToMove * cushionFactor) / (double)100)); bool bTargetAchieved = false; //loop-invariant, in case we need to exit the loop in middle. long movedSoFar = 0; ArrayList usedIndex = new ArrayList(); //this list would keep all those indicies related to Inner loop that are consumed/used in swap. //Making pivot node to be the secondary one, the one that needs to gain weight. //swapping or try to swap each element of secNode to all elements of priNode. //primary is traversed in Descending order, and secondary is traversed in ascending order. for (int i = 0; i < secBucketCount && !bTargetAchieved; i++) { WeightIdPair secWIPair = (WeightIdPair)secWIPairList[i]; for (int j = priBucketCount - 1; j >= 0; j--) { WeightIdPair priWIPair = (WeightIdPair)priWIPairList[j]; //only move when there is a gain. if (priWIPair.Weight > secWIPair.Weight && !usedIndex.Contains(j)) { swapWeightGain = priWIPair.Weight - secWIPair.Weight; movedSoFar += swapWeightGain; if (movedSoFar <= dataToMove) { if (dataToMove - movedSoFar <= cushionWeight) { //swap the buckets and exit secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; bTargetAchieved = true; break; } else { secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; usedIndex.Add(j); break; //i need to move fwd now } } //end if else { if (movedSoFar - dataToMove <= cushionWeight) { //swap the buckets an exit secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; bTargetAchieved = true; break; } else { movedSoFar -= swapWeightGain; } } //end else } //end if for priWeight > seWeight } //end inner for loop } //end outer for loop //re-assign the WeightIdPairList to respective BalanceDataForNode priNode.WeightIdList = priWIPairList; priNode.WeightIdList.Sort(); secNode.WeightIdList = secWIPairList; secNode.WeightIdList.Sort(); }
} //end func. //data to be moved from Primary node to the secondary node. //As a result priNode and secNode got updated WeightIdPairLists. private static void BalanceTwoNodes(BalanceDataForNode priNode, BalanceDataForNode secNode, long dataToMove) { int priBucketCount = priNode.ItemsCount; int secBucketCount = secNode.ItemsCount; ArrayList priWIPairList = priNode.WeightIdList; ArrayList secWIPairList = secNode.WeightIdList; int cushionFactor = 10; // 10% cushion for balancing... +- 10% long swapWeightGain = 0; // weight gain for this swap long cushionWeight = Convert.ToInt64(((double)(dataToMove * cushionFactor) / (double)100)); bool bTargetAchieved = false; //loop-invariant, in case we need to exit the loop in middle. long movedSoFar = 0; ArrayList usedIndex = new ArrayList(); //this list would keep all those indicies related to Inner loop that are consumed/used in swap. //Making pivot node to be the secondary one, the one that needs to gain weight. //swapping or try to swap each element of secNode to all elements of priNode. //primary is traversed in Descending order, and secondary is traversed in ascending order. for (int i = 0; i < secBucketCount && !bTargetAchieved; i++) { WeightIdPair secWIPair = (WeightIdPair)secWIPairList[i]; for (int j = priBucketCount - 1; j >= 0; j--) { WeightIdPair priWIPair = (WeightIdPair) priWIPairList[j]; //only move when there is a gain. if (priWIPair.Weight > secWIPair.Weight && !usedIndex.Contains(j)) { swapWeightGain = priWIPair.Weight - secWIPair.Weight; movedSoFar+= swapWeightGain; if (movedSoFar <= dataToMove) { if (dataToMove - movedSoFar <= cushionWeight) { //swap the buckets and exit secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; bTargetAchieved = true; break; } else { secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; usedIndex.Add(j); break; //i need to move fwd now } } //end if else { if (movedSoFar - dataToMove <= cushionWeight) { //swap the buckets an exit secWIPairList[i] = priWIPair; priWIPairList[j] = secWIPair; bTargetAchieved = true; break; } else { movedSoFar-=swapWeightGain; } } //end else }//end if for priWeight > seWeight }//end inner for loop }//end outer for loop //re-assign the WeightIdPairList to respective BalanceDataForNode priNode.WeightIdList = priWIPairList; priNode.WeightIdList.Sort(); secNode.WeightIdList = secWIPairList; secNode.WeightIdList.Sort(); }
private void ApplyChangesInHashMap(BalanceDataForNode secNode) { ArrayList weightIdPair = secNode.WeightIdList; Address newAddr = secNode.NodeAddress; HashMapBucket bucket = null; foreach (WeightIdPair widPair in weightIdPair) { bucket = (HashMapBucket)_hashMap[widPair.BucketId]; if (!newAddr.Equals(bucket.TempAddress)) bucket.Status = BucketStatus.NeedTransfer; bucket.TempAddress = newAddr; } }
//Need to check if the source node really needs any balancing?. If the weight is more then the Avg weight/Node then its true else false. private bool SanityCheckForCandidateNode(Address sourceNode) { ArrayList dataListForNodes = _nodeBalData.BalanceDataListForNodes; foreach (BalanceDataForNode balData in dataListForNodes) { if (balData.NodeAddress.Equals(sourceNode)) { if (balData.PercentData > _nodeBalData.PercentWeightPerNode) { this._weightToMove = balData.TotalWeight - this._nodeBalData.WeightPerNode; //Weight to move is the one that is above the Avg. weight the node Should bear. _primaryNode = balData; return true; } else return false; } } //end foreach loop return false; //nothing found. }