)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db0559dedf00596da7bed719f6dc460e1e0a2aaf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"59de62e9_89b34c13","updated":"2022-07-11 06:06:28.000000000","message":"This is a reworked version that has been moved to _before_ serialization classes POC changes. ","commit_id":"4ec7337374516fdd49d3588adb7f65eabdd85eac"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7e354c72ced90ee6c41b3cecf1e0e5b10881fc6c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"3c8114e5_ee7dc12c","updated":"2022-07-11 22:12:45.000000000","message":"Just fixing up the docstring and rebasing on an update of the parent patch.","commit_id":"a5dfc19ab37aba4a8c5d6e47d216eaaef90a2a6c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"d16f6e05_4bcf0d9d","updated":"2022-07-29 22:11:36.000000000","message":"-1 for the none_dev_id in the indexes and the potential loss of the \u0027swift/ring/assignments\u0027 section. I think it\u0027s making sense, though.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fb0d45a3ebe66ebe595ca236cbc982cc1b5fad3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"81b2f22a_86f06597","updated":"2022-09-01 20:04:37.000000000","message":"Put some fixes in https://review.opendev.org/c/openstack/swift/+/855548","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e5ee20e87bf624339e06ed1a46cbbc2020dd16c7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":30,"id":"4cb18d9d_05bd1fb8","updated":"2025-08-19 07:04:12.000000000","message":"yeah ok, so there is a still come work. When we were only keeping history_size of 1, we don\u0027t have to worry about cleaning up the old history arrays.. but now that we can keep more we\u0027ll need to remove failed devices from history (so a new device doesn\u0027t get inserted and if it recuses a dev_id doesn\u0027t because an old primary) and we need to trucate/resize history arrays (or should we :hmm:)","commit_id":"37f6b36410bcaf6bdbb5bb2a7764f5638430d670"}],"swift/cli/ringbuilder.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":1423,"context_line":"        exit(EXIT_SUCCESS)"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"    @staticmethod"},{"line_number":1426,"context_line":"    def set_replicas():"},{"line_number":1427,"context_line":"        \"\"\""},{"line_number":1428,"context_line":"swift-ring-builder \u003cbuilder_file\u003e set_replicas \u003creplicas\u003e"},{"line_number":1429,"context_line":"    Changes the replica count to the given \u003creplicas\u003e. \u003creplicas\u003e may"}],"source_content_type":"text/x-python","patch_set":10,"id":"ec6f23bc_2ca2bca2","line":1426,"updated":"2022-07-29 22:11:36.000000000","message":"Should we add a set_history_count command? Or leave it as future work?","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":false,"context_lines":[{"line_number":1423,"context_line":"        exit(EXIT_SUCCESS)"},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"    @staticmethod"},{"line_number":1426,"context_line":"    def set_replicas():"},{"line_number":1427,"context_line":"        \"\"\""},{"line_number":1428,"context_line":"swift-ring-builder \u003cbuilder_file\u003e set_replicas \u003creplicas\u003e"},{"line_number":1429,"context_line":"    Changes the replica count to the given \u003creplicas\u003e. \u003creplicas\u003e may"}],"source_content_type":"text/x-python","patch_set":10,"id":"5db0495d_ecd0b794","line":1426,"in_reply_to":"ec6f23bc_2ca2bca2","updated":"2025-08-18 09:09:01.000000000","message":"Done in a follow up","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"}],"swift/common/ring/builder.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":103,"context_line":"        self.devs_changed \u003d False"},{"line_number":104,"context_line":"        self.version \u003d 0"},{"line_number":105,"context_line":"        self.overload \u003d 0.0"},{"line_number":106,"context_line":"        self.history_count \u003d 1"},{"line_number":107,"context_line":"        self._id \u003d None"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"        # _replica2part2dev maps from replica number to partition number to"}],"source_content_type":"text/x-python","patch_set":10,"id":"a4801917_3ab10281","line":106,"updated":"2022-07-29 22:11:36.000000000","message":"Here\u0027s the default for new builders.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":312,"context_line":"            self._id \u003d builder.get(\u0027id\u0027)"},{"line_number":313,"context_line":"            self.history_count \u003d builder.get(\u0027history_count\u0027, 1)"},{"line_number":314,"context_line":"            self._past2part2index \u003d builder.get(\u0027_past2part2index\u0027)"},{"line_number":315,"context_line":"            self._past2part2dev_id \u003d builder.get(\u0027_past2part2dev_id\u0027)"},{"line_number":316,"context_line":"        self._ring \u003d None"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        # Old builders may not have a region defined for their devices, in"}],"source_content_type":"text/x-python","patch_set":10,"id":"99309fef_aaaab0c1","line":315,"updated":"2022-07-29 22:11:36.000000000","message":"...and these are how we seamlessly upgrade existing builders.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":false,"context_lines":[{"line_number":312,"context_line":"            self._id \u003d builder.get(\u0027id\u0027)"},{"line_number":313,"context_line":"            self.history_count \u003d builder.get(\u0027history_count\u0027, 1)"},{"line_number":314,"context_line":"            self._past2part2index \u003d builder.get(\u0027_past2part2index\u0027)"},{"line_number":315,"context_line":"            self._past2part2dev_id \u003d builder.get(\u0027_past2part2dev_id\u0027)"},{"line_number":316,"context_line":"        self._ring \u003d None"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        # Old builders may not have a region defined for their devices, in"}],"source_content_type":"text/x-python","patch_set":10,"id":"22c103d2_2553ff13","line":315,"in_reply_to":"7e8b996b_716bc43e","updated":"2025-08-18 09:09:01.000000000","message":"Done","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fb0d45a3ebe66ebe595ca236cbc982cc1b5fad3","unresolved":true,"context_lines":[{"line_number":312,"context_line":"            self._id \u003d builder.get(\u0027id\u0027)"},{"line_number":313,"context_line":"            self.history_count \u003d builder.get(\u0027history_count\u0027, 1)"},{"line_number":314,"context_line":"            self._past2part2index \u003d builder.get(\u0027_past2part2index\u0027)"},{"line_number":315,"context_line":"            self._past2part2dev_id \u003d builder.get(\u0027_past2part2dev_id\u0027)"},{"line_number":316,"context_line":"        self._ring \u003d None"},{"line_number":317,"context_line":""},{"line_number":318,"context_line":"        # Old builders may not have a region defined for their devices, in"}],"source_content_type":"text/x-python","patch_set":10,"id":"7e8b996b_716bc43e","line":315,"in_reply_to":"99309fef_aaaab0c1","updated":"2022-09-01 20:04:37.000000000","message":"Do we want them defaulting to None, though, or empty lists? If we leave it at None, we\u0027ll have to watch for it later, in get_ring() and _build_dispersion_graph()...","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fb0d45a3ebe66ebe595ca236cbc982cc1b5fad3","unresolved":true,"context_lines":[{"line_number":694,"context_line":"        # also count up changed_parts if old_replica2part2dev is passed in"},{"line_number":695,"context_line":"        old_replica2part2dev \u003d old_replica2part2dev or []"},{"line_number":696,"context_line":"        if old_replica2part2dev:"},{"line_number":697,"context_line":"            # we\u0027re going to store a new past2part row"},{"line_number":698,"context_line":"            self._past2part2index.insert("},{"line_number":699,"context_line":"                0, array(\u0027H\u0027, itertools.repeat(self.none_dev_id, self.parts)))"},{"line_number":700,"context_line":"            self._past2part2dev_id.insert("}],"source_content_type":"text/x-python","patch_set":10,"id":"99df8683_8b790619","line":697,"updated":"2022-09-01 20:04:37.000000000","message":"This feels like a bit of a weird side effect for a method named _build_dispersion_graph()...","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":696,"context_line":"        if old_replica2part2dev:"},{"line_number":697,"context_line":"            # we\u0027re going to store a new past2part row"},{"line_number":698,"context_line":"            self._past2part2index.insert("},{"line_number":699,"context_line":"                0, array(\u0027H\u0027, itertools.repeat(self.none_dev_id, self.parts)))"},{"line_number":700,"context_line":"            self._past2part2dev_id.insert("},{"line_number":701,"context_line":"                0, array(self.dev_id_type_code,"},{"line_number":702,"context_line":"                         itertools.repeat(self.none_dev_id, self.parts)))"}],"source_content_type":"text/x-python","patch_set":10,"id":"70d023cd_24a5fd6a","line":699,"range":{"start_line":699,"start_character":26,"end_line":699,"end_character":27},"updated":"2022-07-29 22:11:36.000000000","message":"We could probably get away with B here -- seems perfectly reasonable to limit ourselves to 250 replicas -- pretty sure liberasurecode caps out at like 32 or 64. Though I suppose if we ever start supporting QuadIron or something, we\u0027ll appreciate the extra bits -- looks like they support on the order of a thousand frags.\n\nI don\u0027t think self.none_dev_id is appropriate here, though -- this is going to throw an OverflowError if dev_id_bytes is 4.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":704,"context_line":"                self._past2part2index \u003d \\"},{"line_number":705,"context_line":"                    self._past2part2index[:self.history_count]"},{"line_number":706,"context_line":"                self._past2part2dev_id \u003d \\"},{"line_number":707,"context_line":"                    self._past2part2dev_id[:self.history_count]"},{"line_number":708,"context_line":"        # Compare the partition allocation before and after the rebalance"},{"line_number":709,"context_line":"        # Only changed device ids are taken into account; devices might be"},{"line_number":710,"context_line":"        # \"touched\" during the rebalance, but actually not really moved"}],"source_content_type":"text/x-python","patch_set":10,"id":"a87cf093_2399b2f5","line":707,"updated":"2022-07-29 22:11:36.000000000","message":"I wonder if it would be worth trying to do some compaction here, instead -- something like\n\n old_indexes \u003d self._past2part2index.pop()\n old_devs \u003d self._past2part2dev_id.pop()\n for p, (next_oldest, oldest, oldest_index) in enumerate(zip(\n         self._past2part2dev_id[-1], old_devs, old_indexes)):\n     if next_oldest \u003d\u003d NONE_DEV_ID:\n         self._past2part2dev_id[-1][p] \u003d oldest\n         self._past2part2index[-1][p] \u003d oldest_index\n\nThough I suppose we\u0027d still want it to age out eventually...\n\nProbably better to have it as-is to start, anyway.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":true,"context_lines":[{"line_number":704,"context_line":"                self._past2part2index \u003d \\"},{"line_number":705,"context_line":"                    self._past2part2index[:self.history_count]"},{"line_number":706,"context_line":"                self._past2part2dev_id \u003d \\"},{"line_number":707,"context_line":"                    self._past2part2dev_id[:self.history_count]"},{"line_number":708,"context_line":"        # Compare the partition allocation before and after the rebalance"},{"line_number":709,"context_line":"        # Only changed device ids are taken into account; devices might be"},{"line_number":710,"context_line":"        # \"touched\" during the rebalance, but actually not really moved"}],"source_content_type":"text/x-python","patch_set":10,"id":"42b5db27_fc62b786","line":707,"in_reply_to":"a87cf093_2399b2f5","updated":"2025-08-18 09:09:01.000000000","message":"yeah OK, I\u0027ll give this another spin and see if that makes more sense. Maybe in the next patchset after I push these first set of fixes.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fb0d45a3ebe66ebe595ca236cbc982cc1b5fad3","unresolved":true,"context_lines":[{"line_number":726,"context_line":"                for tier in (dev.get(\u0027tiers\u0027) or tiers_for_dev(dev)):"},{"line_number":727,"context_line":"                    replicas_at_tier[tier] +\u003d 1"},{"line_number":728,"context_line":"                # IndexErrors will be raised if the replicas are increased or"},{"line_number":729,"context_line":"                # decreased, and that actually means the partition has changed"},{"line_number":730,"context_line":"                try:"},{"line_number":731,"context_line":"                    old_device \u003d old_replica2part2dev[rep_id][part_id]"},{"line_number":732,"context_line":"                except IndexError:"}],"source_content_type":"text/x-python","patch_set":10,"id":"2a929021_92dd8cce","line":729,"updated":"2022-09-01 20:04:37.000000000","message":"Side note: I think IndexErrors are only actually raised when replica count is *increased*. For better or worse, *decreasing* replica count on master doesn\u0027t seem to identify any parts as having changed (except for ones which happened to get picked up and moved anyway).","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5fb0d45a3ebe66ebe595ca236cbc982cc1b5fad3","unresolved":true,"context_lines":[{"line_number":754,"context_line":"        self._dispersion_graph \u003d dispersion_graph"},{"line_number":755,"context_line":"        self.dispersion \u003d 100.0 * parts_at_risk / (self.parts * self.replicas)"},{"line_number":756,"context_line":"        self.version +\u003d 1"},{"line_number":757,"context_line":"        return changed_parts"},{"line_number":758,"context_line":""},{"line_number":759,"context_line":"    def validate(self, stats\u003dFalse):"},{"line_number":760,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"91fab2eb_7e4b5ba9","line":757,"updated":"2022-09-01 20:04:37.000000000","message":"The history-rotation side effect feels even stranger when you realize we\u0027ll do it even if this returns 0!","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":true,"context_lines":[{"line_number":754,"context_line":"        self._dispersion_graph \u003d dispersion_graph"},{"line_number":755,"context_line":"        self.dispersion \u003d 100.0 * parts_at_risk / (self.parts * self.replicas)"},{"line_number":756,"context_line":"        self.version +\u003d 1"},{"line_number":757,"context_line":"        return changed_parts"},{"line_number":758,"context_line":""},{"line_number":759,"context_line":"    def validate(self, stats\u003dFalse):"},{"line_number":760,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"7e5eea13_ba295b3d","line":757,"in_reply_to":"91fab2eb_7e4b5ba9","updated":"2025-08-18 09:09:01.000000000","message":"I guess a reblance ago nothing changed.. thats interesting maybe :P","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee50976d72496fd55176d498bec34b93a169f380","unresolved":true,"context_lines":[{"line_number":1079,"context_line":"        while self._remove_devs:"},{"line_number":1080,"context_line":"            remove_dev_id \u003d self._remove_devs.pop()[\u0027id\u0027]"},{"line_number":1081,"context_line":"            self.logger.debug(\"Removing dev %d\", remove_dev_id)"},{"line_number":1082,"context_line":"            self.devs[remove_dev_id] \u003d None"},{"line_number":1083,"context_line":"            removed_devs +\u003d 1"},{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"        # Trim the dev list"}],"source_content_type":"text/x-python","patch_set":10,"id":"2c8e136d_bc315b30","line":1082,"updated":"2022-09-01 00:31:37.000000000","message":"We should set any last2part2dev references to self.none_dev_id before doing this. Otherwise, we can get into a situation where we rebalance a part away from a disk, remove the disk, add a new disk that gets the old dev_id, and find ourselves asking the new disk about some phantom old assignments.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":true,"context_lines":[{"line_number":1079,"context_line":"        while self._remove_devs:"},{"line_number":1080,"context_line":"            remove_dev_id \u003d self._remove_devs.pop()[\u0027id\u0027]"},{"line_number":1081,"context_line":"            self.logger.debug(\"Removing dev %d\", remove_dev_id)"},{"line_number":1082,"context_line":"            self.devs[remove_dev_id] \u003d None"},{"line_number":1083,"context_line":"            removed_devs +\u003d 1"},{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"        # Trim the dev list"}],"source_content_type":"text/x-python","patch_set":10,"id":"7f560ac7_e218da84","line":1082,"in_reply_to":"2c8e136d_bc315b30","updated":"2025-08-18 09:09:01.000000000","message":"I think that\u0027s been taken care of now with the code above.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e5ee20e87bf624339e06ed1a46cbbc2020dd16c7","unresolved":true,"context_lines":[{"line_number":1079,"context_line":"        while self._remove_devs:"},{"line_number":1080,"context_line":"            remove_dev_id \u003d self._remove_devs.pop()[\u0027id\u0027]"},{"line_number":1081,"context_line":"            self.logger.debug(\"Removing dev %d\", remove_dev_id)"},{"line_number":1082,"context_line":"            self.devs[remove_dev_id] \u003d None"},{"line_number":1083,"context_line":"            removed_devs +\u003d 1"},{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"        # Trim the dev list"}],"source_content_type":"text/x-python","patch_set":10,"id":"434a7fc2_3fea89f5","line":1082,"in_reply_to":"7f560ac7_e218da84","updated":"2025-08-19 07:04:12.000000000","message":"oh i see.. hmm, might have to go through old history and blot them out so in that usecase we don\u0027t get the wrong answer","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee50976d72496fd55176d498bec34b93a169f380","unresolved":true,"context_lines":[{"line_number":1150,"context_line":"                    for part in range(desired_length, len(part2dev)):"},{"line_number":1151,"context_line":"                        dev_losing_part \u003d self.devs[part2dev[part]]"},{"line_number":1152,"context_line":"                        dev_losing_part[\u0027parts\u0027] -\u003d 1"},{"line_number":1153,"context_line":"                        removed_parts -\u003d 1"},{"line_number":1154,"context_line":"                    self._replica2part2dev[replica] \u003d part2dev[:desired_length]"},{"line_number":1155,"context_line":"            else:"},{"line_number":1156,"context_line":"                # Mapping not present at all: make one up and assign"}],"source_content_type":"text/x-python","patch_set":10,"id":"d0680358_15df822d","line":1153,"updated":"2022-09-01 00:31:37.000000000","message":"We should update last2part2dev when reducing replica count.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ee50976d72496fd55176d498bec34b93a169f380","unresolved":true,"context_lines":[{"line_number":1954,"context_line":"            return False"},{"line_number":1955,"context_line":""},{"line_number":1956,"context_line":"        new_replica2part2dev \u003d []"},{"line_number":1957,"context_line":"        for replica in self._replica2part2dev:"},{"line_number":1958,"context_line":"            new_replica \u003d array(self.dev_id_type_code)"},{"line_number":1959,"context_line":"            for device in replica:"},{"line_number":1960,"context_line":"                new_replica.append(device)"}],"source_content_type":"text/x-python","patch_set":10,"id":"9f7b7478_ce2e2d9b","line":1957,"updated":"2022-09-01 00:31:37.000000000","message":"This function needs to resize the last2part2dev arrays as well.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":true,"context_lines":[{"line_number":1954,"context_line":"            return False"},{"line_number":1955,"context_line":""},{"line_number":1956,"context_line":"        new_replica2part2dev \u003d []"},{"line_number":1957,"context_line":"        for replica in self._replica2part2dev:"},{"line_number":1958,"context_line":"            new_replica \u003d array(self.dev_id_type_code)"},{"line_number":1959,"context_line":"            for device in replica:"},{"line_number":1960,"context_line":"                new_replica.append(device)"}],"source_content_type":"text/x-python","patch_set":10,"id":"e6b34da2_f98c551b","line":1957,"in_reply_to":"9f7b7478_ce2e2d9b","updated":"2025-08-18 09:09:01.000000000","message":"hmm, yeah, good point.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"}],"swift/common/ring/ring.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"786f25b8f44e5f5206c98118ec61d09126a7b13e","unresolved":true,"context_lines":[{"line_number":168,"context_line":"                ring_dict[\u0027replica2part2dev_id\u0027].append("},{"line_number":169,"context_line":"                    read_network_order_array(type_code, row))"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        with reader.open_section(\u0027swift/last_replica2part\u0027) as r:"},{"line_number":172,"context_line":"            index_row_len \u003d 2 * partition_count"},{"line_number":173,"context_line":"            # First comes the index array"},{"line_number":174,"context_line":"            ring_dict[\u0027last_primary2dev_id\u0027].append("}],"source_content_type":"text/x-python","patch_set":1,"id":"fc67f040_b1f5a0d7","line":171,"updated":"2022-03-28 06:21:23.000000000","message":"We ought to check that the builder actually has this section. At least, assuming we keep them as separate patches (which I think is valuable if only for demonstrating how one extends the v2 format without breaking backwards compatibility).","commit_id":"659623616c0f359472eda9d28c2f28e0e5da9e44"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"d3f4369f4c38c3bd30e76eade97a1fa4eb1acf5c","unresolved":true,"context_lines":[{"line_number":168,"context_line":"                ring_dict[\u0027replica2part2dev_id\u0027].append("},{"line_number":169,"context_line":"                    read_network_order_array(type_code, row))"},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        with reader.open_section(\u0027swift/last_replica2part\u0027) as r:"},{"line_number":172,"context_line":"            index_row_len \u003d 2 * partition_count"},{"line_number":173,"context_line":"            # First comes the index array"},{"line_number":174,"context_line":"            ring_dict[\u0027last_primary2dev_id\u0027].append("}],"source_content_type":"text/x-python","patch_set":1,"id":"8d60491b_bb53a592","line":171,"in_reply_to":"fc67f040_b1f5a0d7","updated":"2022-03-29 00:04:05.000000000","message":"good idea. From earlier dicussions with you, I\u0027m thinking about changing this somewhat anyway. Might have a and index array seperate from the last part array. By default it\u0027ll be 1 and 1, so same size as in this patch. But allow us to ask how much history to keep, means we could sture x amount of rebalances.\nAs the patch stands the current data structure would only handle 1, that isn\u0027t very future proof.\n\nSo am going to respon this. Maybe call them something like:\npast2part2index and past2part2dev or something :)","commit_id":"659623616c0f359472eda9d28c2f28e0e5da9e44"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        self.devs \u003d devs"},{"line_number":76,"context_line":"        for i, part2dev_id in enumerate(replica2part2dev_id):"},{"line_number":77,"context_line":"            if not isinstance(part2dev_id, array.array):"},{"line_number":78,"context_line":"                replica2part2dev_id[i] \u003d array.array(\u0027I\u0027, part2dev_id)"},{"line_number":79,"context_line":"        self._replica2part2dev_id \u003d replica2part2dev_id"},{"line_number":80,"context_line":"        self._part_shift \u003d part_shift"},{"line_number":81,"context_line":"        self.next_part_power \u003d next_part_power"}],"source_content_type":"text/x-python","patch_set":10,"id":"838c761d_14e283e1","line":78,"updated":"2022-07-29 22:11:36.000000000","message":"I wonder if we\u0027ll want some coercion-to-array down below, too.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":179,"context_line":"        ring_dict[\u0027dev_id_bytes\u0027] \u003d 2"},{"line_number":180,"context_line":"        ring_dict[\u0027past2part2index\u0027] \u003d []"},{"line_number":181,"context_line":"        ring_dict[\u0027past2part2dev_id\u0027] \u003d []"},{"line_number":182,"context_line":"        ring_dict[\u0027history_count\u0027] \u003d 1"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        if metadata_only:"},{"line_number":185,"context_line":"            return ring_dict"}],"source_content_type":"text/x-python","patch_set":10,"id":"3c16951f_3876f879","line":182,"updated":"2022-07-29 22:11:36.000000000","message":"I wonder if 0 would be more appropriate for a v1 ring.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":true,"context_lines":[{"line_number":179,"context_line":"        ring_dict[\u0027dev_id_bytes\u0027] \u003d 2"},{"line_number":180,"context_line":"        ring_dict[\u0027past2part2index\u0027] \u003d []"},{"line_number":181,"context_line":"        ring_dict[\u0027past2part2dev_id\u0027] \u003d []"},{"line_number":182,"context_line":"        ring_dict[\u0027history_count\u0027] \u003d 1"},{"line_number":183,"context_line":""},{"line_number":184,"context_line":"        if metadata_only:"},{"line_number":185,"context_line":"            return ring_dict"}],"source_content_type":"text/x-python","patch_set":10,"id":"def89f55_c28845bb","line":182,"in_reply_to":"3c16951f_3876f879","updated":"2025-08-18 09:09:01.000000000","message":"Sure, that makes sense. Although if we deserialize a v1 and then serialise it as a v2 ring we may want it to be 1... but I guess when we deserialise we wont have any history :shrug:","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":286,"context_line":"                   ring_data.get(\u0027version\u0027),"},{"line_number":287,"context_line":"                   ring_data.get(\u0027past2part2index\u0027),"},{"line_number":288,"context_line":"                   ring_data.get(\u0027past2part2dev_id\u0027),"},{"line_number":289,"context_line":"                   ring_data.get(\u0027history_count\u0027))"},{"line_number":290,"context_line":"        # For loading with metadata_only\u003dTrue"},{"line_number":291,"context_line":"        if \u0027replica_count\u0027 in ring_data:"},{"line_number":292,"context_line":"            ring._replica_count \u003d ring_data[\u0027replica_count\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"3a7c4280_53aa00c8","line":289,"updated":"2022-07-29 22:11:36.000000000","message":"Maybe better as\n\n .get(\u0027history_count\u0027, 0)\n\n? Getting Nones for the other two are fine/expected... but IDK about the count.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":false,"context_lines":[{"line_number":286,"context_line":"                   ring_data.get(\u0027version\u0027),"},{"line_number":287,"context_line":"                   ring_data.get(\u0027past2part2index\u0027),"},{"line_number":288,"context_line":"                   ring_data.get(\u0027past2part2dev_id\u0027),"},{"line_number":289,"context_line":"                   ring_data.get(\u0027history_count\u0027))"},{"line_number":290,"context_line":"        # For loading with metadata_only\u003dTrue"},{"line_number":291,"context_line":"        if \u0027replica_count\u0027 in ring_data:"},{"line_number":292,"context_line":"            ring._replica_count \u003d ring_data[\u0027replica_count\u0027]"}],"source_content_type":"text/x-python","patch_set":10,"id":"61cce826_1646f09a","line":289,"in_reply_to":"3a7c4280_53aa00c8","updated":"2025-08-18 09:09:01.000000000","message":"Acknowledged","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e43696ec8bf937caec4e2e38a1b6403655fccea0","unresolved":true,"context_lines":[{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    @staticmethod"},{"line_number":363,"context_line":"    def v2_write_ringlike(section, writer, ringlike, dev_id_bytes):"},{"line_number":364,"context_line":"        if ringlike:"},{"line_number":365,"context_line":"            with writer.section(section):"},{"line_number":366,"context_line":"                assignments \u003d sum(len(a) for a in ringlike)"},{"line_number":367,"context_line":"                writer.write_size(assignments * dev_id_bytes)"}],"source_content_type":"text/x-python","patch_set":10,"id":"e646a529_79da03de","line":364,"updated":"2022-07-29 22:11:36.000000000","message":"We\u0027re no longer guaranteed to write a \u0027swift/ring/assignments\u0027 section now...\n\nOn the parent patch, you might trip\n\n Warning: Writing a ring with no partition assignments but with devices; did you forget to run \"rebalance\"?\n\nbut the section will still get written (as a (0, b\u0027\u0027) length-value pair). Without it, we\u0027re going to trip errors on read, up around L239.","commit_id":"707b850981a0423f3cad86ef6619aae489a61baf"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"74aca2a6db461ea6acbf903a0ac96671759ed09a","unresolved":true,"context_lines":[{"line_number":596,"context_line":"        \"\"\""},{"line_number":597,"context_line":"        return getmtime(self.serialized_path) !\u003d self._mtime"},{"line_number":598,"context_line":""},{"line_number":599,"context_line":"    def get_last_part_node(self, part, rebalances_ago\u003d1):"},{"line_number":600,"context_line":"        \"\"\""},{"line_number":601,"context_line":"        Return the node that was a primary for the given part up to x"},{"line_number":602,"context_line":"        rebalances ago. So long as x is \u003c\u003d the history_count stored in the"}],"source_content_type":"text/x-python","patch_set":12,"id":"732d5778_0bb3b355","line":599,"range":{"start_line":599,"start_character":12,"end_line":599,"end_character":16},"updated":"2022-09-26 20:54:46.000000000","message":"I feel like we ought to choose between \"last\" or \"past\" -- I keep getting confused about which one to use.","commit_id":"e8952a8d20aa143ce003be1cb47b16209dcef7ba"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"25e0a8221b8d6ab5d1323a49fa8d31e4241e9097","unresolved":false,"context_lines":[{"line_number":596,"context_line":"        \"\"\""},{"line_number":597,"context_line":"        return getmtime(self.serialized_path) !\u003d self._mtime"},{"line_number":598,"context_line":""},{"line_number":599,"context_line":"    def get_last_part_node(self, part, rebalances_ago\u003d1):"},{"line_number":600,"context_line":"        \"\"\""},{"line_number":601,"context_line":"        Return the node that was a primary for the given part up to x"},{"line_number":602,"context_line":"        rebalances ago. So long as x is \u003c\u003d the history_count stored in the"}],"source_content_type":"text/x-python","patch_set":12,"id":"80729776_4149efa3","line":599,"range":{"start_line":599,"start_character":12,"end_line":599,"end_character":16},"in_reply_to":"732d5778_0bb3b355","updated":"2025-08-18 09:09:01.000000000","message":"hmm, last kinda just means the last one.. where as past feels like I can get any from the past.. so I might go with past.","commit_id":"e8952a8d20aa143ce003be1cb47b16209dcef7ba"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e5ee20e87bf624339e06ed1a46cbbc2020dd16c7","unresolved":true,"context_lines":[{"line_number":206,"context_line":""},{"line_number":207,"context_line":"            with reader.open_section(\u0027swift/ring/history/index\u0027) as section:"},{"line_number":208,"context_line":"                ring_dict[\u0027past2part2index\u0027] \u003d section.read_ring_table("},{"line_number":209,"context_line":"                    2, partition_count)"},{"line_number":210,"context_line":"        except KeyError:"},{"line_number":211,"context_line":"            # history tables are not in the index of this ringv2. Just"},{"line_number":212,"context_line":"            # an older ring."}],"source_content_type":"text/x-python","patch_set":30,"id":"5d2c0d0a_173408ca","line":209,"range":{"start_line":209,"start_character":20,"end_line":209,"end_character":21},"updated":"2025-08-19 07:04:12.000000000","message":"Hmm yeah should I keep this as 2, or make index a single byte array. Noting what Tim said earlier about 255 replicas might be more then enough (or is that some of those famous last words)","commit_id":"37f6b36410bcaf6bdbb5bb2a7764f5638430d670"}]}
