dubbo.apache.org/dubbo-go/v3@v3.1.1/xds/utils/hierarchy/hierarchy.go (about)

     1  /*
     2   * Licensed to the Apache Software Foundation (ASF) under one or more
     3   * contributor license agreements.  See the NOTICE file distributed with
     4   * this work for additional information regarding copyright ownership.
     5   * The ASF licenses this file to You under the Apache License, Version 2.0
     6   * (the "License"); you may not use this file except in compliance with
     7   * the License.  You may obtain a copy of the License at
     8   *
     9   *     http://www.apache.org/licenses/LICENSE-2.0
    10   *
    11   * Unless required by applicable law or agreed to in writing, software
    12   * distributed under the License is distributed on an "AS IS" BASIS,
    13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    14   * See the License for the specific language governing permissions and
    15   * limitations under the License.
    16   */
    17  
    18  /*
    19   *
    20   * Copyright 2020 gRPC authors.
    21   *
    22   */
    23  
    24  // Package hierarchy contains functions to set and get hierarchy string from
    25  // addresses.
    26  //
    27  // This package is experimental.
    28  package hierarchy
    29  
    30  import (
    31  	"google.golang.org/grpc/resolver"
    32  )
    33  
    34  type pathKeyType string
    35  
    36  const pathKey = pathKeyType("grpc.internal.address.hierarchical_path")
    37  
    38  type pathValue []string
    39  
    40  func (p pathValue) Equal(o interface{}) bool {
    41  	op, ok := o.(pathValue)
    42  	if !ok {
    43  		return false
    44  	}
    45  	if len(op) != len(p) {
    46  		return false
    47  	}
    48  	for i, v := range p {
    49  		if v != op[i] {
    50  			return false
    51  		}
    52  	}
    53  	return true
    54  }
    55  
    56  // Get returns the hierarchical path of addr.
    57  func Get(addr resolver.Address) []string {
    58  	attrs := addr.BalancerAttributes
    59  	if attrs == nil {
    60  		return nil
    61  	}
    62  	path, _ := attrs.Value(pathKey).(pathValue)
    63  	return ([]string)(path)
    64  }
    65  
    66  // Set overrides the hierarchical path in addr with path.
    67  func Set(addr resolver.Address, path []string) resolver.Address {
    68  	addr.BalancerAttributes = addr.BalancerAttributes.WithValue(pathKey, pathValue(path))
    69  	return addr
    70  }
    71  
    72  // Group splits a slice of addresses into groups based on
    73  // the first hierarchy path. The first hierarchy path will be removed from the
    74  // result.
    75  //
    76  // Input:
    77  // [
    78  //
    79  //	{addr0, path: [p0, wt0]}
    80  //	{addr1, path: [p0, wt1]}
    81  //	{addr2, path: [p1, wt2]}
    82  //	{addr3, path: [p1, wt3]}
    83  //
    84  // ]
    85  //
    86  // Addresses will be split into p0/p1, and the p0/p1 will be removed from the
    87  // path.
    88  //
    89  // Output:
    90  //
    91  //	{
    92  //	  p0: [
    93  //	    {addr0, path: [wt0]},
    94  //	    {addr1, path: [wt1]},
    95  //	  ],
    96  //	  p1: [
    97  //	    {addr2, path: [wt2]},
    98  //	    {addr3, path: [wt3]},
    99  //	  ],
   100  //	}
   101  //
   102  // If hierarchical path is not set, or has no path in it, the address is
   103  // dropped.
   104  func Group(addrs []resolver.Address) map[string][]resolver.Address {
   105  	ret := make(map[string][]resolver.Address)
   106  	for _, addr := range addrs {
   107  		oldPath := Get(addr)
   108  		if len(oldPath) == 0 {
   109  			continue
   110  		}
   111  		curPath := oldPath[0]
   112  		newPath := oldPath[1:]
   113  		newAddr := Set(addr, newPath)
   114  		ret[curPath] = append(ret[curPath], newAddr)
   115  	}
   116  	return ret
   117  }