示例#1
0
文件: route.py 项目: zmyer/elliptics
    def percentages(self):
        """
        Returns parts of DHT ring each node and each node backend occupies (in percents)\n
        print routes.percentages()
        """
        perc = {}
        for group in self.groups():
            routes = self.filter_by_group(group)
            perc[group] = {}
            for i, r in enumerate(routes[1:]):
                prev = routes[i]
                amount = int(str(r.id), 16) - int(str(prev.id), 16)
                if prev.address not in perc[group]:
                    perc[group][prev.address] = {prev.backend_id: amount}
                elif prev.backend_id not in perc[group][prev.address]:
                    perc[group][prev.address][prev.backend_id] = amount
                else:
                    perc[group][prev.address][prev.backend_id] += amount

        max = int(str(Id([255] * 64, 0)), 16)

        for group in perc:
            sum = 0
            for address in perc[group]:
                address_sum = 0
                for backend in perc[group][address]:
                    sum += perc[group][address][backend]
                    address_sum += perc[group][address][backend]
                    perc[group][address][
                        backend] = perc[group][address][backend] * 100.0 / max
                perc[group][address]['total'] = address_sum * 100.0 / max
            assert (sum == max)

        return perc
示例#2
0
    def percentages(self):
        """
        Returns parts of DHT ring each node occupies (in percents)
        """
        perc = {}
        for g in self.groups():
            routes = self.filter_by_group_id(g)
            prev = None
            perc[g] = {}
            for r in routes:
                if prev:
                    amount = int(str(r.key), 16) - int(str(prev.key), 16)
                    if prev.address not in perc[g]:
                        perc[g][prev.address] = amount
                    else:
                        perc[g][prev.address] += amount

                prev = r

        max = int(str(Id([255] * 64, 0)), 16)

        for g in perc:
            sum = 0
            for p in perc[g]:
                sum += perc[g][p]
                perc[g][p] = perc[g][p] * 100.0 / max
            assert(sum == max)

        return perc
示例#3
0
文件: route.py 项目: zmyer/elliptics
    def from_routes(cls, routes):
        """
        Create RouteList from elliptics route table.

        It slightly mangles route list by explicitly inserting start and end of
        hash-ring and also merging adj. routes for the same into one.
        """
        routes_dict = dict()

        # splits all routes between groups
        for r in routes:
            if r.id.group_id in routes_dict:
                routes_dict[r.id.group_id].append(
                    Route(r.id, r.address, r.backend_id))
            else:
                routes_dict[r.id.group_id] = [
                    Route(r.id, r.address, r.backend_id)
                ]

        # merges adj. ids for same address
        smallest_id = [0] * 64
        biggest_id = [255] * 64
        merged_routes = []
        for group in routes_dict:
            # sorts routes inside one group
            group_routes = sorted(routes_dict[group],
                                  key=lambda route: route.id)
            last = (group_routes[-1].address, group_routes[-1].backend_id)

            # Insert implicit first route if needed
            if group_routes[0].id.id != smallest_id:
                route = Route(Id(smallest_id, group), *last)
                group_routes.insert(0, route)

            # Insert implicit last route if needed
            if group_routes[-1].id.id != biggest_id:
                route = Route(Id(biggest_id, group), *last)
                group_routes.append(route)

            # Extend route list
            merged_routes.extend(group_routes)

        # Sort results by key
        merged_routes.sort(key=lambda route: route.id)

        # Return RouteList from sorted and merged routes
        return cls(merged_routes)
示例#4
0
    def from_routes(cls, routes):
        """
        Create RouteList from elliptics route table.

        It slightly mangles route list by explicitly inserting start and end of
        hash-ring and also merging adj. routes for the same into one.
        """
        sorted_routes = []

        # First pass - sort keys and construct addresses from text routes
        for key, str_address in sorted(routes, key=lambda route: route[0].id):
            address = Address.from_host_port(str_address, key.group_id)
            sorted_routes.append(Route(key, address))

        # Merge adj. keys for same address
        merged_routes = []
        for group in cls(sorted_routes).groups():
            group_routes = cls(sorted_routes).filter_by_group_id(group)
            last_address = group_routes[-1].address
            merged_group = []

            # Insert implicit first route
            group_routes.insert(0, Route(Id([0]*64, group), last_address))

            # For each Route in list left only first one for each route
            for _, g in groupby(group_routes, attrgetter('address')):
                merged_group.append(list(g)[0])
            assert(all(r1.address != r2.address
                       for r1, r2 in izip(merged_group, merged_group[1:])))
            assert(all(r1.key < r2.key
                       for r1, r2 in izip(merged_group, merged_group[1:])))

            # Insert implicit last route
            merged_group.append(Route(Id([255]*64, group), last_address))

            # Extend route list
            merged_routes.extend(merged_group)

        # Sort results by key
        merged_routes.sort(key=itemgetter(0))

        # Return RouteList from sorted and merged routes
        return cls(merged_routes)
示例#5
0
    def from_routes(cls, routes):
        """
        Create RouteList from elliptics route table.

        It slightly mangles route list by explicitly inserting start and end of
        hash-ring and also merging adj. routes for the same into one.
        """
        sorted_routes = []

        # First pass - sort ids and construct addresses from text routes
        for route in sorted(routes, key=lambda route: route.id):
            sorted_routes.append(Route(route.id, route.address, route.backend_id))

        # Merge adj. ids for same address
        smallest_id = [0] * 64
        biggest_id = [255] * 64
        merged_routes = []
        for group in cls(sorted_routes).groups():
            group_routes = cls(sorted_routes).filter_by_group(group).routes
            last = (group_routes[-1].address,
                    group_routes[-1].backend_id)

            # Insert implicit first route if needed
            if group_routes[0].id.id != smallest_id:
                route = Route(Id(smallest_id, group), *last)
                group_routes.insert(0, route)

            # Insert implicit last route if needed
            if group_routes[-1].id.id != biggest_id:
                route = Route(Id(biggest_id, group), *last)
                group_routes.append(route)

            # Extend route list
            merged_routes.extend(group_routes)

        # Sort results by key
        merged_routes.sort(key=itemgetter(0))

        # Return RouteList from sorted and merged routes
        return cls(merged_routes)
示例#6
0
    def get_address_ranges(self, address):
        """
        Returns key ranges which belong to specified address
        """
        ranges = []
        group_id = self.get_address_group_id(address)
        key = None
        for route in self.filter_by_group_id(group_id):
            if route.address == address:
                if not key is None:
                    key = route.key
            elif key:
                ranges.append((key, route.key))
                key = None

        if key:
            ranges.append((key, Id([255]*64, group_id)))

        return ranges
示例#7
0
 def get_address_backend_ranges(self, address, backend_id):
     """
     Returns id ranges which belong to specified @backend_id at @address\n
     ranges = routes.get_address_backend_ranges(
         Address.from_host_port_family('host.com:1025:2', 0))
     """
     ranges = []
     group = self.get_address_backend_group(address, backend_id)
     id = None
     for route in self.filter_by_groups([group]):
         if (route.address, route.backend_id) == (address, backend_id):
             if id is None:
                 id = route.id
         elif id:
             ranges.append((id, route.id))
             id = None
     if id:
         ranges.append((id, Id([255] * 64, id.group_id)))
     return ranges
示例#8
0
    def get_address_ranges(self, address):
        """
        Returns id ranges which belong to specified @address\n
        ranges = routes.get_address_ranges(
            Address.from_host_port_family('host.com:1025:2'))
        """
        ranges = []
        groups = self.get_address_groups(address)
        id = None
        for route in self.filter_by_groups(groups):
            if route.address == address:
                if id is None:
                    id = route.id
            elif id:
                ranges.append((id, route.id))
                id = None

        if id:
            ranges.append((id, Id([255] * 64, id.group_id)))

        return ranges
示例#9
0
    def get_address_ranges(self, address):
        """
        Returns key ranges which belong to specified address\n
        ranges = routes.get_address_ranges(
            Address.from_host_port_family('host.com:1025:2'))
        """
        ranges = []
        group_id = self.get_address_group_id(address)
        key = None
        for route in self.filter_by_group_id(group_id):
            if route.address == address:
                if key is None:
                    key = route.key
            elif key:
                ranges.append((key, route.key))
                key = None

        if key:
            ranges.append((key, Id([255] * 64, group_id)))

        return ranges