Example #1
0
        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);
            }
        }
Example #2
0
        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);
            }
        }
Example #3
0
        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;
            }
        }
Example #4
0
        //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.
        }
Example #5
0
        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));
        }
Example #6
0
        //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();
        }
Example #7
0
 } //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();
 }
Example #8
0
 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;
     }
 }
Example #9
0
 //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.
 }