public virtual int Compare(Schedulable s1, Schedulable s2)
            {
                ResourceWeights sharesOfCluster1  = new ResourceWeights();
                ResourceWeights sharesOfCluster2  = new ResourceWeights();
                ResourceWeights sharesOfMinShare1 = new ResourceWeights();
                ResourceWeights sharesOfMinShare2 = new ResourceWeights();

                ResourceType[] resourceOrder1 = new ResourceType[NumResources];
                ResourceType[] resourceOrder2 = new ResourceType[NumResources];
                // Calculate shares of the cluster for each resource both schedulables.
                CalculateShares(s1.GetResourceUsage(), clusterCapacity, sharesOfCluster1, resourceOrder1
                                , s1.GetWeights());
                CalculateShares(s1.GetResourceUsage(), s1.GetMinShare(), sharesOfMinShare1, null,
                                ResourceWeights.Neutral);
                CalculateShares(s2.GetResourceUsage(), clusterCapacity, sharesOfCluster2, resourceOrder2
                                , s2.GetWeights());
                CalculateShares(s2.GetResourceUsage(), s2.GetMinShare(), sharesOfMinShare2, null,
                                ResourceWeights.Neutral);
                // A queue is needy for its min share if its dominant resource
                // (with respect to the cluster capacity) is below its configured min share
                // for that resource
                bool s1Needy = sharesOfMinShare1.GetWeight(resourceOrder1[0]) < 1.0f;
                bool s2Needy = sharesOfMinShare2.GetWeight(resourceOrder2[0]) < 1.0f;
                int  res     = 0;

                if (!s2Needy && !s1Needy)
                {
                    res = CompareShares(sharesOfCluster1, sharesOfCluster2, resourceOrder1, resourceOrder2
                                        );
                }
                else
                {
                    if (s1Needy && !s2Needy)
                    {
                        res = -1;
                    }
                    else
                    {
                        if (s2Needy && !s1Needy)
                        {
                            res = 1;
                        }
                        else
                        {
                            // both are needy below min share
                            res = CompareShares(sharesOfMinShare1, sharesOfMinShare2, resourceOrder1, resourceOrder2
                                                );
                        }
                    }
                }
                if (res == 0)
                {
                    // Apps are tied in fairness ratio. Break the tie by submit time.
                    res = (int)(s1.GetStartTime() - s2.GetStartTime());
                }
                return(res);
            }
        public virtual void TestCalculateShares()
        {
            Org.Apache.Hadoop.Yarn.Api.Records.Resource used = Resources.CreateResource(10, 5
                                                                                        );
            Org.Apache.Hadoop.Yarn.Api.Records.Resource capacity = Resources.CreateResource(100
                                                                                            , 10);
            ResourceType[]  resourceOrder = new ResourceType[2];
            ResourceWeights shares        = new ResourceWeights();

            DominantResourceFairnessPolicy.DominantResourceFairnessComparator comparator = new
                                                                                           DominantResourceFairnessPolicy.DominantResourceFairnessComparator();
            comparator.CalculateShares(used, capacity, shares, resourceOrder, ResourceWeights
                                       .Neutral);
            NUnit.Framework.Assert.AreEqual(.1, shares.GetWeight(ResourceType.Memory), .00001
                                            );
            NUnit.Framework.Assert.AreEqual(.5, shares.GetWeight(ResourceType.Cpu), .00001);
            NUnit.Framework.Assert.AreEqual(ResourceType.Cpu, resourceOrder[0]);
            NUnit.Framework.Assert.AreEqual(ResourceType.Memory, resourceOrder[1]);
        }
 private int CompareShares(ResourceWeights shares1, ResourceWeights shares2, ResourceType
                           [] resourceOrder1, ResourceType[] resourceOrder2)
 {
     for (int i = 0; i < resourceOrder1.Length; i++)
     {
         int ret = (int)Math.Signum(shares1.GetWeight(resourceOrder1[i]) - shares2.GetWeight
                                        (resourceOrder2[i]));
         if (ret != 0)
         {
             return(ret);
         }
     }
     return(0);
 }
 /// <summary>Calculates and orders a resource's share of a pool in terms of two vectors.
 ///     </summary>
 /// <remarks>
 /// Calculates and orders a resource's share of a pool in terms of two vectors.
 /// The shares vector contains, for each resource, the fraction of the pool that
 /// it takes up.  The resourceOrder vector contains an ordering of resources
 /// by largest share.  So if resource=<10 MB, 5 CPU>, and pool=<100 MB, 10 CPU>,
 /// shares will be [.1, .5] and resourceOrder will be [CPU, MEMORY].
 /// </remarks>
 internal virtual void CalculateShares(Org.Apache.Hadoop.Yarn.Api.Records.Resource
                                       resource, Org.Apache.Hadoop.Yarn.Api.Records.Resource pool, ResourceWeights shares
                                       , ResourceType[] resourceOrder, ResourceWeights weights)
 {
     shares.SetWeight(ResourceType.Memory, (float)resource.GetMemory() / (pool.GetMemory
                                                                              () * weights.GetWeight(ResourceType.Memory)));
     shares.SetWeight(ResourceType.Cpu, (float)resource.GetVirtualCores() / (pool.GetVirtualCores
                                                                                 () * weights.GetWeight(ResourceType.Cpu)));
     // sort order vector by resource share
     if (resourceOrder != null)
     {
         if (shares.GetWeight(ResourceType.Memory) > shares.GetWeight(ResourceType.Cpu))
         {
             resourceOrder[0] = ResourceType.Memory;
             resourceOrder[1] = ResourceType.Cpu;
         }
         else
         {
             resourceOrder[0] = ResourceType.Cpu;
             resourceOrder[1] = ResourceType.Memory;
         }
     }
 }