示例#1
0
 public void ProcessFilters(PlacementPolicy policy)
 {
     foreach (var filter in policy.Filters)
     {
         ProcessFilter(filter, true);
     }
 }
 public void ProcessSelectors(PlacementPolicy policy)
 {
     foreach (var selector in policy.Selectors)
     {
         if (selector is null)
         {
             throw new ArgumentException($"{ErrMissingField}: SELECT");
         }
         if (selector.Filter != MainFilterName && !Filters.ContainsKey(selector.Filter))
         {
             throw new ArgumentException($"{ErrFilterNotFound}: SELECT FROM {selector.Filter}");
         }
         Selectors[selector.Name] = selector;
         var results = GetSelection(policy, selector);
         Selections[selector.Name] = results;
     }
 }
示例#3
0
        public List <List <Node> > GetContainerNodes(PlacementPolicy policy, byte[] pivot)
        {
            if (policy is null)
            {
                throw new ArgumentNullException(nameof(policy));
            }
            var context = new Context(this);

            context.SetPivot(pivot);
            context.SetCBF(policy.ContainerBackupFactor);
            context.ProcessFilters(policy);
            context.ProcessSelectors(policy);
            var result = new List <List <Node> >();

            foreach (var replica in policy.Replicas)
            {
                if (replica is null)
                {
                    throw new ArgumentException(nameof(GetContainerNodes) + " missing Replicas");
                }
                var r = new List <Node>();
                if (replica.Selector == "")
                {
                    if (policy.Selectors.Count == 0)
                    {
                        var s = new Selector
                        {
                            Count  = replica.Count,
                            Filter = Context.MainFilterName,
                        };
                        var ns = context.GetSelection(policy, s);
                        r = ns.Flatten().ToList();
                    }
                    foreach (var selector in policy.Selectors)
                    {
                        r = r.Concat(context.Selections[selector.Name].Flatten()).ToList();
                    }
                    result.Add(r);
                    continue;
                }
                var nodes = context.Selections[replica.Selector];
                r = nodes.Flatten().ToList();
                result.Add(r);
            }
            return(result);
        }
        public List <List <Node> > GetSelection(PlacementPolicy policy, Selector sel)
        {
            int bucket_count    = sel.GetBucketCount();
            int nodes_in_bucket = sel.GetNodesInBucket();
            var buckets         = GetSelectionBase(policy.SubnetId, sel);

            if (buckets.Count < bucket_count)
            {
                throw new InvalidOperationException($"{ErrNotEnoughNodes}: {sel.Name}");
            }
            if (pivot is null)
            {
                if (sel.Attribute == "")
                {
                    buckets.Sort((b1, b2) => b1.Item2[0].ID.CompareTo(b2.Item2[0].ID));
                }
                else
                {
                    buckets.Sort((b1, b2) => b1.Item1.CompareTo(b2.Item1));
                }
            }
            var max_nodes_in_bucket = nodes_in_bucket * (int)Cbf;
            var nodes    = new List <List <Node> >();
            var fallback = new List <List <Node> >();

            foreach (var(_, ns) in buckets)
            {
                if (max_nodes_in_bucket <= ns.Count)
                {
                    nodes.Add(ns.Take(max_nodes_in_bucket).ToList());
                }
                else if (nodes_in_bucket <= ns.Count)
                {
                    fallback.Add(ns);
                }
            }
            if (nodes.Count < bucket_count)
            {
                nodes = nodes.Concat(fallback).ToList();
                if (nodes.Count < bucket_count)
                {
                    throw new InvalidOperationException($"{ErrNotEnoughNodes}: {sel.Name}");
                }
            }
            if (pivot is not null)
            {
                var list = nodes.Select((p, index) =>
                {
                    var agg = newAggregator();
                    foreach (var n in p)
                    {
                        agg.Add(weightFunc(n));
                    }
                    var w    = agg.Compute();
                    var hash = p.Count > 0 ? p[0].Hash : 0;
                    var d    = hash.Distance(pivotHash);
                    return(d, w, p);
                }).ToList();
                var uniform = !list.Skip(1).Any(p => p.w != list[0].w);
                if (uniform)
                {
                    list.Sort((n1, n2) =>
                    {
                        return(n1.d.CompareTo(n2.d));
                    });
                }
                else
                {
                    list.Sort((n1, n2) =>
                    {
                        var w1 = (~0u - n1.d) * n1.w;
                        var w2 = (~0u - n2.d) * n2.w;
                        return(w2.CompareTo(w1));
                    });
                }
                nodes = list.Select(p => p.p).ToList();
            }
            if (sel.Attribute == "")
            {
                fallback = nodes.GetRange(bucket_count, nodes.Count - bucket_count);
                nodes    = nodes.GetRange(0, bucket_count);
                for (int i = 0; i < fallback.Count; i++)
                {
                    var index = i % bucket_count;
                    if (nodes[index].Count >= max_nodes_in_bucket)
                    {
                        break;
                    }
                    nodes[index] = nodes[index].Concat(fallback[i]).ToList();
                }
            }
            return(nodes.GetRange(0, bucket_count));
        }