)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"466a6a50af50fee9d0c36e5a798b315ad8dcfdb2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"f1e71ea9_d550ac91","updated":"2023-01-18 10:44:35.000000000","message":"I\u0027ve only taken a quick first look. We might want to push even harder on compacting the cached blob by dropping the uppers.\n\nShall we move the updating-shard related methods from base.py to obj.py ... before this change? ","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6856032166625d8b83532d0a55b1bc27127e009e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"1afa3d8c_55810128","updated":"2023-01-18 07:36:10.000000000","message":"Still need modify mock cache for several failed tests.","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2716acd4b70fcfe5b822b3f7aa7b0ab758592c4c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"8d9a48ee_5d204c33","in_reply_to":"1afa3d8c_55810128","updated":"2023-01-18 07:38:13.000000000","message":"this is a rework of below patches.\nhttps://review.opendev.org/c/openstack/swift/+/863562/\nhttps://review.opendev.org/c/openstack/swift/+/852203","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"8aaf00c0748aafbd9acb37b8cb9509a2c99f41b7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"0b50e7dc_e584cf6f","in_reply_to":"f1e71ea9_d550ac91","updated":"2023-01-19 03:24:35.000000000","message":"Good point, we should move updating-shard related methods first.","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"a590f294_caa299ff","updated":"2023-01-26 17:09:20.000000000","message":"OK, this is looking better.\n\nI maybe be on one side of a very polarised set of opinions, but I do wonder if a class would help by gathering all the data structure manipulation to one place, rather than a weird getter on one class, a module level find function and some wordy docstrings to keep track of things :shrug: https://review.opendev.org/c/openstack/swift/+/871742","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7c3aa6f42d7ad395bce131ae035e611387fc9d1f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"2293ebd2_416dabc6","updated":"2023-01-26 06:38:39.000000000","message":"isolated the probe failures to the new Namespace class, will need further debugging tomorrow.","commit_id":"9dd9ee4f436c62912e152a7481162ab985846920"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"9d52ce01_aaab3f6c","updated":"2023-01-27 01:18:58.000000000","message":"thanks for the review and help!","commit_id":"9dd9ee4f436c62912e152a7481162ab985846920"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"1343ff217834f58a963b1715fb7d10f4f11f8d67","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"060ec944_97866395","in_reply_to":"2293ebd2_416dabc6","updated":"2023-01-26 06:42:44.000000000","message":"just added the new Namespace class alone to the master branch, those probe tests will pass, but internally the function \"_get_shard_ranges\" will return one more shard and make the list of shard ranges not sequential.\n\n[ShardRange\u003cMinBound to \u0027beta024\u0027 as of 1674699290.06734, (25, 0) as of 1674699290.10576, cleaved as of 1674699290.06734\u003e, ShardRange\u003c\u0027beta024\u0027 to \u0027beta049\u0027 as of 1674699290.06734, (25, 0) as of 1674699290.12442, cleaved as of 1674699290.06734\u003e, ShardRange\u003c\u0027beta049\u0027 to \u0027obj-0024\u0027 as of 1674699290.06734, (25, 0) as of 1674699290.06734, created as of 1674699290.06734\u003e, ShardRange\u003cMinBound to \u0027obj-0024\u0027 as of 1674699287.73845, (75, 0) as of 1674699290.85253, sharding as of 1674699289.77305\u003e, ShardRange\u003c\u0027obj-0024\u0027 to MaxBound as of 1674699287.73845, (25, 0) as of 1674699288.28886, active as of 1674699287.73845\u003e]","commit_id":"9dd9ee4f436c62912e152a7481162ab985846920"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"e9fe3635_9fa2a464","updated":"2023-01-27 18:10:16.000000000","message":"I will try to reproduce the probe test failure next week, but some minor comments in the meantime","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"d3ec1618_8290fbb9","updated":"2023-02-02 15:48:55.000000000","message":"I thought this change was also going to add the part where we split up the huge list of shard ranges into sub-lists that we can bounds check into?  The big hit wasn\u0027t the fact that we did ShardRange.from_dict() and that was \"slow\" - it was that we did ShardRange.from_dict() thousands of times every request?  Does it really make it *that* much faster just to reduce the size of the json if we still have to create objects and call functions thousnads of times?\n\nWhat would it take to put some quantitative numbers around *this* change and demonstrate it\u0027s merit independent of cached-partitioned-sublists change?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"b8086158_ce4446d3","updated":"2023-02-01 15:10:04.000000000","message":"I\u0027m happy with this functionally - I have some queries/suggestions for the class model.\n\nThere\u0027s a bunch of unit tests that should move from TestShardRange to TestNamespace. I did that and addressed some but not all of my nits in https://review.opendev.org/c/openstack/swift/+/872417","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"94a33af6_17f3e6fd","updated":"2023-02-01 22:46:47.000000000","message":"Thanks for the reviews and help!","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"9f2d0ad6_fde1cd57","updated":"2023-02-03 12:25:33.000000000","message":"some proposed docstring and comment clean up here https://review.opendev.org/c/openstack/swift/+/872646","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"d6727e34_825110d6","in_reply_to":"d3ec1618_8290fbb9","updated":"2023-02-03 12:25:33.000000000","message":"\u003e I thought this change was also going to add the part where we split up the huge list of shard ranges into sub-lists that we can bounds check into\n\nI proposed a combination of compact serialisation and smaller blobs here https://review.opendev.org/c/openstack/swift/+/863562, maybe we can evolve towards it?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"955460dc_748d9f85","updated":"2023-03-07 06:15:01.000000000","message":"Thanks all very much for your reviews and comments!","commit_id":"5da09aefdf9222dde45cf6bc80e77af7453cc611"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2d9895aba09b838acda09fb266756230d0f4d946","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"c4e72599_df1c7d0e","updated":"2023-03-10 06:17:45.000000000","message":"This is looking much better! And my only other naming issue is resolved in a follow up from Al, so if that isn\u0027t going to be squashed into this one, I\u0027m happy for the fix to wait until then. Also we\u0027ve been running this in staging and testing it and it works really well, so on that note I think +2.","commit_id":"6ff90ea73ebf4771efba3928ea7667b7ae731c71"}],"swift/common/utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"466a6a50af50fee9d0c36e5a798b315ad8dcfdb2","unresolved":true,"context_lines":[{"line_number":580,"context_line":"    \"\"\""},{"line_number":581,"context_line":"    A tzinfo class for datetime objects that returns a 0 timedelta (UTC time)"},{"line_number":582,"context_line":"    \"\"\""},{"line_number":583,"context_line":""},{"line_number":584,"context_line":"    def dst(self, dt):"},{"line_number":585,"context_line":"        return datetime.timedelta(0)"},{"line_number":586,"context_line":"    utcoffset \u003d dst"}],"source_content_type":"text/x-python","patch_set":1,"id":"f3977f10_35012adc","line":583,"updated":"2023-01-18 10:44:35.000000000","message":"lots of whitespace changes :( - I guess your IDE is doing some auto-formatting?","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":false,"context_lines":[{"line_number":580,"context_line":"    \"\"\""},{"line_number":581,"context_line":"    A tzinfo class for datetime objects that returns a 0 timedelta (UTC time)"},{"line_number":582,"context_line":"    \"\"\""},{"line_number":583,"context_line":""},{"line_number":584,"context_line":"    def dst(self, dt):"},{"line_number":585,"context_line":"        return datetime.timedelta(0)"},{"line_number":586,"context_line":"    utcoffset \u003d dst"}],"source_content_type":"text/x-python","patch_set":1,"id":"f4a64565_be51dcd4","line":583,"in_reply_to":"8840ee98_4297b0cd","updated":"2023-01-26 17:09:20.000000000","message":"IMHO if a style is not enforced by a flake8 check then there isn\u0027t much point incrementally changing - someone may come along and delete the blank lines :/","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"8aaf00c0748aafbd9acb37b8cb9509a2c99f41b7","unresolved":false,"context_lines":[{"line_number":580,"context_line":"    \"\"\""},{"line_number":581,"context_line":"    A tzinfo class for datetime objects that returns a 0 timedelta (UTC time)"},{"line_number":582,"context_line":"    \"\"\""},{"line_number":583,"context_line":""},{"line_number":584,"context_line":"    def dst(self, dt):"},{"line_number":585,"context_line":"        return datetime.timedelta(0)"},{"line_number":586,"context_line":"    utcoffset \u003d dst"}],"source_content_type":"text/x-python","patch_set":1,"id":"8840ee98_4297b0cd","line":583,"in_reply_to":"f3977f10_35012adc","updated":"2023-01-19 03:24:35.000000000","message":"It\u0027s auto-formatting, I found them too, and removed them in the beginning. Then found out a lot of existing classes in this file are following this code style: a blank line between class comments and the first function. So I decided to have them back, to maintain same coding style for all classes in this file. But please let me know if the other way is better(remove all of them).","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":5308,"context_line":""},{"line_number":5309,"context_line":""},{"line_number":5310,"context_line":"@functools.total_ordering"},{"line_number":5311,"context_line":"class Namespace(object):"},{"line_number":5312,"context_line":"    @functools.total_ordering"},{"line_number":5313,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5314,"context_line":"        # singleton for maximum bound"}],"source_content_type":"text/x-python","patch_set":5,"id":"54bd06e7_f3bca850","line":5311,"updated":"2023-01-26 17:09:20.000000000","message":"this class will probably also benefit from having __slots__ \u003d [\u0027name\u0027, \u0027lower\u0027, \u0027upper\u0027]\n\n...and the ShardRange __slots__ should then not have those attribute names\n\n\"The action of a __slots__ declaration is not limited to the class where it is defined. __slots__ declared in parents are available in child classes. However, child subclasses will get a __dict__ and __weakref__ unless they also define __slots__ (which should only contain names of any additional slots).\"\nhttps://docs.python.org/3/reference/datamodel.html#slots","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":5308,"context_line":""},{"line_number":5309,"context_line":""},{"line_number":5310,"context_line":"@functools.total_ordering"},{"line_number":5311,"context_line":"class Namespace(object):"},{"line_number":5312,"context_line":"    @functools.total_ordering"},{"line_number":5313,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5314,"context_line":"        # singleton for maximum bound"}],"source_content_type":"text/x-python","patch_set":5,"id":"4977452a_fc0e1312","line":5311,"in_reply_to":"54bd06e7_f3bca850","updated":"2023-01-27 01:18:58.000000000","message":"Ack","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":5521,"context_line":"    __slots__ \u003d ("},{"line_number":5522,"context_line":"        \u0027account\u0027, \u0027container\u0027,"},{"line_number":5523,"context_line":"        \u0027_timestamp\u0027, \u0027_meta_timestamp\u0027, \u0027_state_timestamp\u0027, \u0027_epoch\u0027,"},{"line_number":5524,"context_line":"        \u0027_lower\u0027, \u0027_upper\u0027, \u0027_deleted\u0027, \u0027_state\u0027, \u0027_count\u0027, \u0027_bytes\u0027,"},{"line_number":5525,"context_line":"        \u0027_tombstones\u0027, \u0027_reported\u0027)"},{"line_number":5526,"context_line":""},{"line_number":5527,"context_line":"    def __init__(self, name, timestamp,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7e738266_b2df2423","line":5524,"range":{"start_line":5524,"start_character":8,"end_line":5524,"end_character":27},"updated":"2023-01-26 17:09:20.000000000","message":"these should move to Namespace.__slots__","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":5521,"context_line":"    __slots__ \u003d ("},{"line_number":5522,"context_line":"        \u0027account\u0027, \u0027container\u0027,"},{"line_number":5523,"context_line":"        \u0027_timestamp\u0027, \u0027_meta_timestamp\u0027, \u0027_state_timestamp\u0027, \u0027_epoch\u0027,"},{"line_number":5524,"context_line":"        \u0027_lower\u0027, \u0027_upper\u0027, \u0027_deleted\u0027, \u0027_state\u0027, \u0027_count\u0027, \u0027_bytes\u0027,"},{"line_number":5525,"context_line":"        \u0027_tombstones\u0027, \u0027_reported\u0027)"},{"line_number":5526,"context_line":""},{"line_number":5527,"context_line":"    def __init__(self, name, timestamp,"}],"source_content_type":"text/x-python","patch_set":5,"id":"32408578_69d5c85f","line":5524,"range":{"start_line":5524,"start_character":8,"end_line":5524,"end_character":27},"in_reply_to":"7e738266_b2df2423","updated":"2023-01-27 01:18:58.000000000","message":"Ack","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":5956,"context_line":"        return (self.lower \u003d\u003d Namespace.MIN and"},{"line_number":5957,"context_line":"                self.upper \u003d\u003d Namespace.MAX)"},{"line_number":5958,"context_line":""},{"line_number":5959,"context_line":"    def lower_bound(self):"},{"line_number":5960,"context_line":"        \"\"\""},{"line_number":5961,"context_line":"        Returns this ShardRange\u0027s lower bound and name in a list."},{"line_number":5962,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"ada73e6f_69594a61","line":5959,"updated":"2023-01-26 17:09:20.000000000","message":"this should be a method of Namespace I think\n\nAlso, IMHO the method name is too similar to lower...\n\n  :param lower: the lower bound","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":5956,"context_line":"        return (self.lower \u003d\u003d Namespace.MIN and"},{"line_number":5957,"context_line":"                self.upper \u003d\u003d Namespace.MAX)"},{"line_number":5958,"context_line":""},{"line_number":5959,"context_line":"    def lower_bound(self):"},{"line_number":5960,"context_line":"        \"\"\""},{"line_number":5961,"context_line":"        Returns this ShardRange\u0027s lower bound and name in a list."},{"line_number":5962,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"2eed82a5_48adc111","line":5959,"in_reply_to":"ada73e6f_69594a61","updated":"2023-01-27 01:18:58.000000000","message":"Done","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":5307,"context_line":"            raise ValueError(\u0027invalid name: %s\u0027 % name)"},{"line_number":5308,"context_line":""},{"line_number":5309,"context_line":""},{"line_number":5310,"context_line":"@functools.total_ordering"},{"line_number":5311,"context_line":"class Namespace(object):"},{"line_number":5312,"context_line":""},{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"d9df8ff0_694c0b10","line":5310,"updated":"2023-01-27 18:10:16.000000000","message":"hmmm, adding this may demand some new unit tests for \u003c\u003d and \u003e\u003d operators","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"27d614500ebd8b94c47fd1f70f5cf839578ed53b","unresolved":false,"context_lines":[{"line_number":5307,"context_line":"            raise ValueError(\u0027invalid name: %s\u0027 % name)"},{"line_number":5308,"context_line":""},{"line_number":5309,"context_line":""},{"line_number":5310,"context_line":"@functools.total_ordering"},{"line_number":5311,"context_line":"class Namespace(object):"},{"line_number":5312,"context_line":""},{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"bcf93079_5a651310","line":5310,"in_reply_to":"d9df8ff0_694c0b10","updated":"2023-02-01 06:55:20.000000000","message":"Done","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":5312,"context_line":""},{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"},{"line_number":5314,"context_line":""},{"line_number":5315,"context_line":"    @functools.total_ordering"},{"line_number":5316,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5317,"context_line":"        # singleton for maximum bound"},{"line_number":5318,"context_line":"        def __ge__(self, other):"},{"line_number":5319,"context_line":"            return True"},{"line_number":5320,"context_line":""},{"line_number":5321,"context_line":"    @functools.total_ordering"},{"line_number":5322,"context_line":"    class MinBound(ShardRangeOuterBound):"},{"line_number":5323,"context_line":"        # singleton for minimum bound"},{"line_number":5324,"context_line":"        def __le__(self, other):"},{"line_number":5325,"context_line":"            return True"},{"line_number":5326,"context_line":""},{"line_number":5327,"context_line":"    MIN \u003d MinBound()"},{"line_number":5328,"context_line":"    MAX \u003d MaxBound()"}],"source_content_type":"text/x-python","patch_set":9,"id":"031bfe9b_698c302d","line":5325,"range":{"start_line":5315,"start_character":4,"end_line":5325,"end_character":23},"updated":"2023-01-27 18:10:16.000000000","message":"I\u0027m not sure these class declarations need to be inside Namespace (I can\u0027t remember why they were inner classes)","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7d94dba1cfbb9b80681376e2127d06327cb54b0","unresolved":false,"context_lines":[{"line_number":5312,"context_line":""},{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"},{"line_number":5314,"context_line":""},{"line_number":5315,"context_line":"    @functools.total_ordering"},{"line_number":5316,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5317,"context_line":"        # singleton for maximum bound"},{"line_number":5318,"context_line":"        def __ge__(self, other):"},{"line_number":5319,"context_line":"            return True"},{"line_number":5320,"context_line":""},{"line_number":5321,"context_line":"    @functools.total_ordering"},{"line_number":5322,"context_line":"    class MinBound(ShardRangeOuterBound):"},{"line_number":5323,"context_line":"        # singleton for minimum bound"},{"line_number":5324,"context_line":"        def __le__(self, other):"},{"line_number":5325,"context_line":"            return True"},{"line_number":5326,"context_line":""},{"line_number":5327,"context_line":"    MIN \u003d MinBound()"},{"line_number":5328,"context_line":"    MAX \u003d MaxBound()"}],"source_content_type":"text/x-python","patch_set":9,"id":"1bf27fb7_c2af5679","line":5325,"range":{"start_line":5315,"start_character":4,"end_line":5325,"end_character":23},"in_reply_to":"031bfe9b_698c302d","updated":"2023-01-28 06:10:58.000000000","message":"because both MinBound and MaxBound are only used for Namespace/ShardRange, then won\u0027t run into conflicts with other kinds of \"MinBound\" or. \"MaxBound\"?","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":6005,"context_line":"            self.meta_timestamp.internal, self.state_text,"},{"line_number":6006,"context_line":"            self.state_timestamp.internal)"},{"line_number":6007,"context_line":""},{"line_number":6008,"context_line":"    def entire_namespace(self):"},{"line_number":6009,"context_line":"        \"\"\""},{"line_number":6010,"context_line":"        Returns True if the ShardRange includes the entire namespace, False"},{"line_number":6011,"context_line":"        otherwise."}],"source_content_type":"text/x-python","patch_set":9,"id":"fa71715f_684eb820","line":6008,"updated":"2023-01-27 18:10:16.000000000","message":"this can move to Namespace","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7d94dba1cfbb9b80681376e2127d06327cb54b0","unresolved":false,"context_lines":[{"line_number":6005,"context_line":"            self.meta_timestamp.internal, self.state_text,"},{"line_number":6006,"context_line":"            self.state_timestamp.internal)"},{"line_number":6007,"context_line":""},{"line_number":6008,"context_line":"    def entire_namespace(self):"},{"line_number":6009,"context_line":"        \"\"\""},{"line_number":6010,"context_line":"        Returns True if the ShardRange includes the entire namespace, False"},{"line_number":6011,"context_line":"        otherwise."}],"source_content_type":"text/x-python","patch_set":9,"id":"35e355ab_a3111ff0","line":6008,"in_reply_to":"fa71715f_684eb820","updated":"2023-01-28 06:10:58.000000000","message":"Done","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":6013,"context_line":"        return (self.lower \u003d\u003d Namespace.MIN and"},{"line_number":6014,"context_line":"                self.upper \u003d\u003d Namespace.MAX)"},{"line_number":6015,"context_line":""},{"line_number":6016,"context_line":"    def overlaps(self, other):"},{"line_number":6017,"context_line":"        \"\"\""},{"line_number":6018,"context_line":"        Returns True if the ShardRange namespace overlaps with the other"},{"line_number":6019,"context_line":"        ShardRange\u0027s namespace."}],"source_content_type":"text/x-python","patch_set":9,"id":"c14f86d1_98a48334","line":6016,"updated":"2023-01-27 18:10:16.000000000","message":"this can move to Namespace","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7d94dba1cfbb9b80681376e2127d06327cb54b0","unresolved":false,"context_lines":[{"line_number":6013,"context_line":"        return (self.lower \u003d\u003d Namespace.MIN and"},{"line_number":6014,"context_line":"                self.upper \u003d\u003d Namespace.MAX)"},{"line_number":6015,"context_line":""},{"line_number":6016,"context_line":"    def overlaps(self, other):"},{"line_number":6017,"context_line":"        \"\"\""},{"line_number":6018,"context_line":"        Returns True if the ShardRange namespace overlaps with the other"},{"line_number":6019,"context_line":"        ShardRange\u0027s namespace."}],"source_content_type":"text/x-python","patch_set":9,"id":"201d6904_1f499d26","line":6016,"in_reply_to":"c14f86d1_98a48334","updated":"2023-01-28 06:10:58.000000000","message":"Done","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":6024,"context_line":"            return False"},{"line_number":6025,"context_line":"        return max(self.lower, other.lower) \u003c min(self.upper, other.upper)"},{"line_number":6026,"context_line":""},{"line_number":6027,"context_line":"    def includes(self, other):"},{"line_number":6028,"context_line":"        \"\"\""},{"line_number":6029,"context_line":"        Returns True if this namespace includes the whole of the other"},{"line_number":6030,"context_line":"        namespace, False otherwise."}],"source_content_type":"text/x-python","patch_set":9,"id":"d45a2217_bb8e726d","line":6027,"updated":"2023-01-27 18:10:16.000000000","message":"this can move to Namespace","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7d94dba1cfbb9b80681376e2127d06327cb54b0","unresolved":false,"context_lines":[{"line_number":6024,"context_line":"            return False"},{"line_number":6025,"context_line":"        return max(self.lower, other.lower) \u003c min(self.upper, other.upper)"},{"line_number":6026,"context_line":""},{"line_number":6027,"context_line":"    def includes(self, other):"},{"line_number":6028,"context_line":"        \"\"\""},{"line_number":6029,"context_line":"        Returns True if this namespace includes the whole of the other"},{"line_number":6030,"context_line":"        namespace, False otherwise."}],"source_content_type":"text/x-python","patch_set":9,"id":"9be434e2_e0b201c0","line":6027,"in_reply_to":"d45a2217_bb8e726d","updated":"2023-01-28 06:10:58.000000000","message":"Done","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6ea3eec023699c58cd30f1dd97383950c75f4f0b","unresolved":true,"context_lines":[{"line_number":6081,"context_line":"            params[\u0027state_timestamp\u0027], params[\u0027epoch\u0027],"},{"line_number":6082,"context_line":"            params.get(\u0027reported\u0027, 0), params.get(\u0027tombstones\u0027, -1))"},{"line_number":6083,"context_line":""},{"line_number":6084,"context_line":"    def expand(self, donors):"},{"line_number":6085,"context_line":"        \"\"\""},{"line_number":6086,"context_line":"        Expands the bounds as necessary to match the minimum and maximum bounds"},{"line_number":6087,"context_line":"        of the given donors."}],"source_content_type":"text/x-python","patch_set":9,"id":"6a4cbc44_3cfe2f70","line":6084,"range":{"start_line":6084,"start_character":4,"end_line":6084,"end_character":29},"updated":"2023-01-27 18:10:16.000000000","message":"this can move to Namespace","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7d94dba1cfbb9b80681376e2127d06327cb54b0","unresolved":false,"context_lines":[{"line_number":6081,"context_line":"            params[\u0027state_timestamp\u0027], params[\u0027epoch\u0027],"},{"line_number":6082,"context_line":"            params.get(\u0027reported\u0027, 0), params.get(\u0027tombstones\u0027, -1))"},{"line_number":6083,"context_line":""},{"line_number":6084,"context_line":"    def expand(self, donors):"},{"line_number":6085,"context_line":"        \"\"\""},{"line_number":6086,"context_line":"        Expands the bounds as necessary to match the minimum and maximum bounds"},{"line_number":6087,"context_line":"        of the given donors."}],"source_content_type":"text/x-python","patch_set":9,"id":"6df9b87a_88e73bae","line":6084,"range":{"start_line":6084,"start_character":4,"end_line":6084,"end_character":29},"in_reply_to":"6a4cbc44_3cfe2f70","updated":"2023-01-28 06:10:58.000000000","message":"Done","commit_id":"dcfbd290788173dfa7adf068df9afde8ea881860"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5172,"context_line":"        return hashlib.md5(string)  # nosec"},{"line_number":5173,"context_line":""},{"line_number":5174,"context_line":""},{"line_number":5175,"context_line":"class ShardRangeOuterBound(object):"},{"line_number":5176,"context_line":"    \"\"\""},{"line_number":5177,"context_line":"    A custom singleton type to be subclassed for the outer bounds of"},{"line_number":5178,"context_line":"    ShardRanges."}],"source_content_type":"text/x-python","patch_set":13,"id":"03dc4f11_245b3785","line":5175,"updated":"2023-02-01 15:10:04.000000000","message":"rename NamespaceOuterBound","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5172,"context_line":"        return hashlib.md5(string)  # nosec"},{"line_number":5173,"context_line":""},{"line_number":5174,"context_line":""},{"line_number":5175,"context_line":"class ShardRangeOuterBound(object):"},{"line_number":5176,"context_line":"    \"\"\""},{"line_number":5177,"context_line":"    A custom singleton type to be subclassed for the outer bounds of"},{"line_number":5178,"context_line":"    ShardRanges."}],"source_content_type":"text/x-python","patch_set":13,"id":"7d56dfbf_325f8ea1","line":5175,"in_reply_to":"03dc4f11_245b3785","updated":"2023-02-01 22:46:47.000000000","message":"Already addressed in the follow up. And those refactor changes will go to the follow up MR per offline discussion.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5199,"context_line":"    __nonzero__ \u003d __bool__"},{"line_number":5200,"context_line":""},{"line_number":5201,"context_line":""},{"line_number":5202,"context_line":"class ShardName(object):"},{"line_number":5203,"context_line":"    \"\"\""},{"line_number":5204,"context_line":"    Encapsulates the components of a shard name."},{"line_number":5205,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"c24c4af4_af6578e4","line":5202,"updated":"2023-02-01 15:10:04.000000000","message":"move after NamespaceBoundList","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5199,"context_line":"    __nonzero__ \u003d __bool__"},{"line_number":5200,"context_line":""},{"line_number":5201,"context_line":""},{"line_number":5202,"context_line":"class ShardName(object):"},{"line_number":5203,"context_line":"    \"\"\""},{"line_number":5204,"context_line":"    Encapsulates the components of a shard name."},{"line_number":5205,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"438f2a71_b540790a","line":5202,"in_reply_to":"c24c4af4_af6578e4","updated":"2023-02-01 22:46:47.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5428,"context_line":"                (value, self.upper))"},{"line_number":5429,"context_line":"        self._lower \u003d value"},{"line_number":5430,"context_line":""},{"line_number":5431,"context_line":"    def lower_bound_in_list(self):"},{"line_number":5432,"context_line":"        \"\"\""},{"line_number":5433,"context_line":"        Returns this Namespace\u0027s lower bound and name in a list."},{"line_number":5434,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"3c1a6d52_18907bef","line":5431,"updated":"2023-02-01 15:10:04.000000000","message":"do we need this and is it tested?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5428,"context_line":"                (value, self.upper))"},{"line_number":5429,"context_line":"        self._lower \u003d value"},{"line_number":5430,"context_line":""},{"line_number":5431,"context_line":"    def lower_bound_in_list(self):"},{"line_number":5432,"context_line":"        \"\"\""},{"line_number":5433,"context_line":"        Returns this Namespace\u0027s lower bound and name in a list."},{"line_number":5434,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":13,"id":"0ba6d49e_8ee197a2","line":5431,"in_reply_to":"3c1a6d52_18907bef","updated":"2023-02-01 22:46:47.000000000","message":"yes, it\u0027s used in NamespaceBoundList.from_namespaces() and tested in TestNamespaceBoundList when it does comparison.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5430,"context_line":""},{"line_number":5431,"context_line":"    def lower_bound_in_list(self):"},{"line_number":5432,"context_line":"        \"\"\""},{"line_number":5433,"context_line":"        Returns this Namespace\u0027s lower bound and name in a list."},{"line_number":5434,"context_line":"        \"\"\""},{"line_number":5435,"context_line":"        return [self.lower_str, str(self.name)]"},{"line_number":5436,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"f2fa43dc_a6e66339","line":5433,"range":{"start_line":5433,"start_character":59,"end_line":5433,"end_character":63},"updated":"2023-02-01 15:10:04.000000000","message":"does it need to be a list vs a tuple?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5430,"context_line":""},{"line_number":5431,"context_line":"    def lower_bound_in_list(self):"},{"line_number":5432,"context_line":"        \"\"\""},{"line_number":5433,"context_line":"        Returns this Namespace\u0027s lower bound and name in a list."},{"line_number":5434,"context_line":"        \"\"\""},{"line_number":5435,"context_line":"        return [self.lower_str, str(self.name)]"},{"line_number":5436,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"3ea6ac3b_b6460b79","line":5433,"range":{"start_line":5433,"start_character":59,"end_line":5433,"end_character":63},"in_reply_to":"f2fa43dc_a6e66339","updated":"2023-02-01 22:46:47.000000000","message":"I thought about this too. If we use a tuple, then JSON encodes it into array, and decodes it back to list. Versus: list--\u003earray--\u003elist. So list is more convenient and make all related changes easier to maintain.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":true,"context_lines":[{"line_number":5506,"context_line":""},{"line_number":5507,"context_line":""},{"line_number":5508,"context_line":"class NamespaceBoundList(object):"},{"line_number":5509,"context_line":"    def __init__(self, bounds):"},{"line_number":5510,"context_line":"        self.bounds \u003d [] if bounds is None else bounds"},{"line_number":5511,"context_line":""},{"line_number":5512,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":13,"id":"9a054f7d_ed2ef9d6","line":5509,"updated":"2023-02-03 12:25:33.000000000","message":"needs docstring","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":false,"context_lines":[{"line_number":5506,"context_line":""},{"line_number":5507,"context_line":""},{"line_number":5508,"context_line":"class NamespaceBoundList(object):"},{"line_number":5509,"context_line":"    def __init__(self, bounds):"},{"line_number":5510,"context_line":"        self.bounds \u003d [] if bounds is None else bounds"},{"line_number":5511,"context_line":""},{"line_number":5512,"context_line":"    @classmethod"}],"source_content_type":"text/x-python","patch_set":13,"id":"cb09ebf2_b3dfad97","line":5509,"in_reply_to":"9a054f7d_ed2ef9d6","updated":"2023-03-01 03:28:02.000000000","message":"Done","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":true,"context_lines":[{"line_number":5510,"context_line":"        self.bounds \u003d [] if bounds is None else bounds"},{"line_number":5511,"context_line":""},{"line_number":5512,"context_line":"    @classmethod"},{"line_number":5513,"context_line":"    def from_namespaces(cls, namespaces):"},{"line_number":5514,"context_line":"        if not namespaces:"},{"line_number":5515,"context_line":"            return None"},{"line_number":5516,"context_line":"        bounds \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"bb095cc7_a8f177fc","line":5513,"updated":"2023-02-03 12:25:33.000000000","message":"needs doctsinrg","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":false,"context_lines":[{"line_number":5510,"context_line":"        self.bounds \u003d [] if bounds is None else bounds"},{"line_number":5511,"context_line":""},{"line_number":5512,"context_line":"    @classmethod"},{"line_number":5513,"context_line":"    def from_namespaces(cls, namespaces):"},{"line_number":5514,"context_line":"        if not namespaces:"},{"line_number":5515,"context_line":"            return None"},{"line_number":5516,"context_line":"        bounds \u003d []"}],"source_content_type":"text/x-python","patch_set":13,"id":"c6dfd165_db2400f0","line":5513,"in_reply_to":"bb095cc7_a8f177fc","updated":"2023-03-01 03:28:02.000000000","message":"Done","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5515,"context_line":"            return None"},{"line_number":5516,"context_line":"        bounds \u003d []"},{"line_number":5517,"context_line":"        upper \u003d namespaces[0].lower"},{"line_number":5518,"context_line":"        for sr in namespaces:"},{"line_number":5519,"context_line":"            if sr.lower \u003c upper:"},{"line_number":5520,"context_line":"                # TODO: When we cached full shard ranges, find_shard_ranges"},{"line_number":5521,"context_line":"                #   bisected using a sort order of (upper, state, lower) so"}],"source_content_type":"text/x-python","patch_set":13,"id":"26aae358_8b51b887","line":5518,"updated":"2023-02-01 15:10:04.000000000","message":"nit: can \u0027sr\u0027 be re-named \u0027namespace\u0027","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5515,"context_line":"            return None"},{"line_number":5516,"context_line":"        bounds \u003d []"},{"line_number":5517,"context_line":"        upper \u003d namespaces[0].lower"},{"line_number":5518,"context_line":"        for sr in namespaces:"},{"line_number":5519,"context_line":"            if sr.lower \u003c upper:"},{"line_number":5520,"context_line":"                # TODO: When we cached full shard ranges, find_shard_ranges"},{"line_number":5521,"context_line":"                #   bisected using a sort order of (upper, state, lower) so"}],"source_content_type":"text/x-python","patch_set":13,"id":"3aedbf3f_3ecc096d","line":5518,"in_reply_to":"26aae358_8b51b887","updated":"2023-02-01 22:46:47.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":5535,"context_line":"                # children. However, will be sorted such that the children"},{"line_number":5536,"context_line":"                # precede the parent and it is the children that we prefer."},{"line_number":5537,"context_line":"                continue"},{"line_number":5538,"context_line":"            bounds.append(sr.lower_bound_in_list())"},{"line_number":5539,"context_line":"            upper \u003d sr.upper"},{"line_number":5540,"context_line":"        return cls(bounds)"},{"line_number":5541,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"ec8d93e4_aef9f49a","line":5538,"range":{"start_line":5538,"start_character":29,"end_line":5538,"end_character":48},"updated":"2023-02-01 15:10:04.000000000","message":"nit: for me the method is unnecessary - it just assembles a tuple, but causes me to navigate to remind myself of what it does","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":5535,"context_line":"                # children. However, will be sorted such that the children"},{"line_number":5536,"context_line":"                # precede the parent and it is the children that we prefer."},{"line_number":5537,"context_line":"                continue"},{"line_number":5538,"context_line":"            bounds.append(sr.lower_bound_in_list())"},{"line_number":5539,"context_line":"            upper \u003d sr.upper"},{"line_number":5540,"context_line":"        return cls(bounds)"},{"line_number":5541,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"200a8f2a_ce64bf69","line":5538,"range":{"start_line":5538,"start_character":29,"end_line":5538,"end_character":48},"in_reply_to":"ec8d93e4_aef9f49a","updated":"2023-02-01 22:46:47.000000000","message":"Will fix this nit change in the follow up MR.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":true,"context_lines":[{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"},{"line_number":5314,"context_line":""},{"line_number":5315,"context_line":"    @functools.total_ordering"},{"line_number":5316,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5317,"context_line":"        # singleton for maximum bound"},{"line_number":5318,"context_line":"        def __ge__(self, other):"},{"line_number":5319,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":14,"id":"a7c48121_7b980d18","line":5316,"range":{"start_line":5316,"start_character":19,"end_line":5316,"end_character":39},"updated":"2023-03-01 03:28:02.000000000","message":"If the ShardRange is basically a super class of a Namespace, then why is a abstract base class of the Min/MaxBound objects named ShardRangeOuterBound. Maybe these should be called NamespaceOuterBounds or AbstactOuterBounds?","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":5313,"context_line":"    __slots__ \u003d (\u0027_lower\u0027, \u0027_upper\u0027, \u0027name\u0027)"},{"line_number":5314,"context_line":""},{"line_number":5315,"context_line":"    @functools.total_ordering"},{"line_number":5316,"context_line":"    class MaxBound(ShardRangeOuterBound):"},{"line_number":5317,"context_line":"        # singleton for maximum bound"},{"line_number":5318,"context_line":"        def __ge__(self, other):"},{"line_number":5319,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":14,"id":"3a2c728e_8eef6ec9","line":5316,"range":{"start_line":5316,"start_character":19,"end_line":5316,"end_character":39},"in_reply_to":"a7c48121_7b980d18","updated":"2023-03-07 06:15:01.000000000","message":"You are right, it should be called \"NamespaceOuterBounds\". It\u0027s fixed in Alistair\u0027s following patch at: https://review.opendev.org/c/openstack/swift/+/872417/3/swift/common/utils.py#5212","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":true,"context_lines":[{"line_number":5505,"context_line":"        return modified"},{"line_number":5506,"context_line":""},{"line_number":5507,"context_line":""},{"line_number":5508,"context_line":"class NamespaceBoundList(object):"},{"line_number":5509,"context_line":"    def __init__(self, bounds):"},{"line_number":5510,"context_line":"        \"\"\""},{"line_number":5511,"context_line":"        Encapsulate a compact representation of namespaces. Each item in the"}],"source_content_type":"text/x-python","patch_set":14,"id":"cde1f709_5045a910","line":5508,"range":{"start_line":5508,"start_character":6,"end_line":5508,"end_character":24},"updated":"2023-03-01 03:28:02.000000000","message":"OK so this is where alot of the compact format magic lies, it basially stores them as a compact list of lists where each item is [lower, name]. And because the ShardRange class is a subset it can also take in ShardRanges.\n\nIf I was force to nitpick I\u0027d say because it has the compact nature, maybe we could\u0027ve chosen a name that includes that? Like CompactBoundList or CompactNamespaceBoundsList.. but that\u0027s just a NIT, I guess NamespaceBoundList is fine 😊","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":5505,"context_line":"        return modified"},{"line_number":5506,"context_line":""},{"line_number":5507,"context_line":""},{"line_number":5508,"context_line":"class NamespaceBoundList(object):"},{"line_number":5509,"context_line":"    def __init__(self, bounds):"},{"line_number":5510,"context_line":"        \"\"\""},{"line_number":5511,"context_line":"        Encapsulate a compact representation of namespaces. Each item in the"}],"source_content_type":"text/x-python","patch_set":14,"id":"45dc4d82_2402ad16","line":5508,"range":{"start_line":5508,"start_character":6,"end_line":5508,"end_character":24},"in_reply_to":"cde1f709_5045a910","updated":"2023-03-07 06:15:01.000000000","message":"Thanks for pondering the name of this class, I often spend a lot of time in naming variables and classes too. A prefix of \"Compact\" does carry more context of why we are having this class, but the name itself then becomes a little too long. Yeah, maybe use NamespaceBoundList for now.","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":true,"context_lines":[{"line_number":5537,"context_line":"            return None"},{"line_number":5538,"context_line":"        bounds \u003d []"},{"line_number":5539,"context_line":"        upper \u003d namespaces[0].lower"},{"line_number":5540,"context_line":"        for sr in namespaces:"},{"line_number":5541,"context_line":"            if sr.lower \u003c upper:"},{"line_number":5542,"context_line":"                # Discard overlapping namespace."},{"line_number":5543,"context_line":"                # Overlapping namespaces are expected in lists of shard ranges"}],"source_content_type":"text/x-python","patch_set":14,"id":"4ad8a266_5a2d33b2","line":5540,"range":{"start_line":5540,"start_character":12,"end_line":5540,"end_character":14},"updated":"2023-03-01 03:28:02.000000000","message":"NIT: sr doesn\u0027t really make sense anymore as it isn\u0027t a shardrange. Ites a namespace. So ns or n would proably suffice.","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":5537,"context_line":"            return None"},{"line_number":5538,"context_line":"        bounds \u003d []"},{"line_number":5539,"context_line":"        upper \u003d namespaces[0].lower"},{"line_number":5540,"context_line":"        for sr in namespaces:"},{"line_number":5541,"context_line":"            if sr.lower \u003c upper:"},{"line_number":5542,"context_line":"                # Discard overlapping namespace."},{"line_number":5543,"context_line":"                # Overlapping namespaces are expected in lists of shard ranges"}],"source_content_type":"text/x-python","patch_set":14,"id":"01ac43e7_3281b66a","line":5540,"range":{"start_line":5540,"start_character":12,"end_line":5540,"end_character":14},"in_reply_to":"4ad8a266_5a2d33b2","updated":"2023-03-07 06:15:01.000000000","message":"Done","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6dad3cf6dd32ef8c125898ae61cd2b456419dbdd","unresolved":true,"context_lines":[{"line_number":5545,"context_line":"                # container is in the process of sharding, the parent shard"},{"line_number":5546,"context_line":"                # range and its children shard ranges may be returned in the"},{"line_number":5547,"context_line":"                # list of shard ranges. However, the backend sorts the list by"},{"line_number":5548,"context_line":"                # (lower, state, upper) such that the children precede the"},{"line_number":5549,"context_line":"                # parent, and it is the children that we prefer to retain in"},{"line_number":5550,"context_line":"                # the NamespaceBoundList. For example, these namespaces:"},{"line_number":5551,"context_line":"                #   (a-b, \"child1\"), (b-c, \"child2\"), (a-c, \"parent\")"}],"source_content_type":"text/x-python","patch_set":14,"id":"420d5cd9_27112c97","line":5548,"range":{"start_line":5548,"start_character":18,"end_line":5548,"end_character":39},"updated":"2023-02-07 10:20:24.000000000","message":"my bad: the sort is by (upper, state, lower, name) https://github.com/openstack/swift/blob/477423f60a1579ee275c37b749cc23aa3fdc4ea7/swift/common/utils.py#L5409-L5414\n\nhttps://github.com/openstack/swift/blob/ece4b04e8215f80b55c367abc523290b503efc76/swift/container/backend.py#L1871\n\nThe state part of the sort key is what sorts children ahead of the parent: the parent state (SHARDING) \u003e child state (CREATED|CLEAVED|ACTIVE).","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":5545,"context_line":"                # container is in the process of sharding, the parent shard"},{"line_number":5546,"context_line":"                # range and its children shard ranges may be returned in the"},{"line_number":5547,"context_line":"                # list of shard ranges. However, the backend sorts the list by"},{"line_number":5548,"context_line":"                # (lower, state, upper) such that the children precede the"},{"line_number":5549,"context_line":"                # parent, and it is the children that we prefer to retain in"},{"line_number":5550,"context_line":"                # the NamespaceBoundList. For example, these namespaces:"},{"line_number":5551,"context_line":"                #   (a-b, \"child1\"), (b-c, \"child2\"), (a-c, \"parent\")"}],"source_content_type":"text/x-python","patch_set":14,"id":"c9592641_75a125d9","line":5548,"range":{"start_line":5548,"start_character":18,"end_line":5548,"end_character":39},"in_reply_to":"420d5cd9_27112c97","updated":"2023-03-07 06:15:01.000000000","message":"Done","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":true,"context_lines":[{"line_number":5562,"context_line":"                # object name to the preceding namespace. In the example, an"},{"line_number":5563,"context_line":"                # object named \"c\" would be mapped to \"ns1\". (In previous"},{"line_number":5564,"context_line":"                # versions, an object update lying in a gap would have been"},{"line_number":5565,"context_line":"                # mapped to the root container.)"},{"line_number":5566,"context_line":"                continue"},{"line_number":5567,"context_line":"            bounds.append(sr.lower_bound_in_list())"},{"line_number":5568,"context_line":"            upper \u003d sr.upper"}],"source_content_type":"text/x-python","patch_set":14,"id":"24757e08_12c39455","line":5565,"updated":"2023-03-01 03:28:02.000000000","message":"OK, so then an update (PUT) would then go to the preceding shard for example, which will suck it up and it\u0027ll be a misplaced object. Interesting to note, because when we have gaps in the future we\u0027ll need to go find them rather the now, where we just need to go look in the root.\nUPDATE: Actually this isn\u0027t true, the misplaced objects code in the sharder, will go pull the shards from root and uses states\u003dupdaing which in turn enables fill_gaps, which will fill the missing gap with the root container.\nThis means that the preceeding namespace will happy take the obj for the gap, and then push it back to root if there there is still a gap during misplaced_objects.\n\nSimilarly for the cleaving.. so ok. We\u0027re only really accepting the into the preceeding one for a sharder cycle max.","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":5562,"context_line":"                # object name to the preceding namespace. In the example, an"},{"line_number":5563,"context_line":"                # object named \"c\" would be mapped to \"ns1\". (In previous"},{"line_number":5564,"context_line":"                # versions, an object update lying in a gap would have been"},{"line_number":5565,"context_line":"                # mapped to the root container.)"},{"line_number":5566,"context_line":"                continue"},{"line_number":5567,"context_line":"            bounds.append(sr.lower_bound_in_list())"},{"line_number":5568,"context_line":"            upper \u003d sr.upper"}],"source_content_type":"text/x-python","patch_set":14,"id":"aeb5ad4b_605da7a9","line":5565,"in_reply_to":"24757e08_12c39455","updated":"2023-03-07 06:15:01.000000000","message":"Thanks for clarifying this!","commit_id":"81bcd49b79db159cf362260b1f73341d81676ab8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b78b011d1e3714fcc957f6e36615aaa603606bd2","unresolved":true,"context_lines":[{"line_number":5548,"context_line":"        self.bounds \u003d [] if bounds is None else bounds"},{"line_number":5549,"context_line":""},{"line_number":5550,"context_line":"    @classmethod"},{"line_number":5551,"context_line":"    def parse(cls, namespaces):"},{"line_number":5552,"context_line":"        \"\"\""},{"line_number":5553,"context_line":"        Create a NamespaceBoundList object by parsing a list of Namespaces or"},{"line_number":5554,"context_line":"        shard ranges and only storing the compact bounds list."}],"source_content_type":"text/x-python","patch_set":17,"id":"7174986b_d609e081","line":5551,"updated":"2023-03-15 15:39:46.000000000","message":"+1 parse is good","commit_id":"6ff90ea73ebf4771efba3928ea7667b7ae731c71"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"466a6a50af50fee9d0c36e5a798b315ad8dcfdb2","unresolved":true,"context_lines":[{"line_number":2492,"context_line":"            shard_ranges, response \u003d self._get_shard_ranges("},{"line_number":2493,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":2494,"context_line":"            if shard_ranges:"},{"line_number":2495,"context_line":"                namespaces \u003d [sr.dict_namespace() for sr in shard_ranges]"},{"line_number":2496,"context_line":"                infocache[cache_key] \u003d tuple(namespaces)"},{"line_number":2497,"context_line":"                if memcache:"},{"line_number":2498,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":1,"id":"4a4060b6_8e41648f","line":2495,"range":{"start_line":2495,"start_character":16,"end_line":2495,"end_character":73},"updated":"2023-01-18 10:44:35.000000000","message":"IIRC Tim pointed out that caching the lowers AND uppers of each namespace might almost double the size of the cached blob, and the uppers are redundant in the context of a contiguous sequence of namespaces. \n\nYou could drop the uppers when serialising to memcache here (have an sr.dict_namespace_lower method or similar) but then you\u0027d need to figure out the upper when deserialising, in order to construct a ShardRange. That\u0027s one of the things the NamespaceMap class in my patch is doing i.e. providing an interface to get Namespaces with (name, lower, and upper) from a list of just (name, lower).","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"8aaf00c0748aafbd9acb37b8cb9509a2c99f41b7","unresolved":false,"context_lines":[{"line_number":2492,"context_line":"            shard_ranges, response \u003d self._get_shard_ranges("},{"line_number":2493,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":2494,"context_line":"            if shard_ranges:"},{"line_number":2495,"context_line":"                namespaces \u003d [sr.dict_namespace() for sr in shard_ranges]"},{"line_number":2496,"context_line":"                infocache[cache_key] \u003d tuple(namespaces)"},{"line_number":2497,"context_line":"                if memcache:"},{"line_number":2498,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":1,"id":"94121ac4_94d88267","line":2495,"range":{"start_line":2495,"start_character":16,"end_line":2495,"end_character":73},"in_reply_to":"4a4060b6_8e41648f","updated":"2023-01-19 03:24:35.000000000","message":"Done","commit_id":"e26ca03e258fda4eccfcc1f956c41a86fe39c69a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":607,"context_line":"        if obj:"},{"line_number":608,"context_line":"            raise ValueError(\u0027Shard cache key cannot have obj\u0027)"},{"line_number":609,"context_line":"        if shard \u003d\u003d \u0027updating\u0027:"},{"line_number":610,"context_line":"            cache_key \u003d \u0027shard-%s-v2/%s/%s\u0027 % (shard, account, container)"},{"line_number":611,"context_line":"        else:"},{"line_number":612,"context_line":"            cache_key \u003d \u0027shard-%s/%s/%s\u0027 % (shard, account, container)"},{"line_number":613,"context_line":"    elif obj:"}],"source_content_type":"text/x-python","patch_set":13,"id":"a033d3d9_3baa722b","line":610,"updated":"2023-02-02 15:48:55.000000000","message":"if we\u0027re really worried about upgrade (I\u0027m not sure I am) - maybe we could have left the key the same, and made our code robust to read either format (but always writeback the optimized form)","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":607,"context_line":"        if obj:"},{"line_number":608,"context_line":"            raise ValueError(\u0027Shard cache key cannot have obj\u0027)"},{"line_number":609,"context_line":"        if shard \u003d\u003d \u0027updating\u0027:"},{"line_number":610,"context_line":"            cache_key \u003d \u0027shard-%s-v2/%s/%s\u0027 % (shard, account, container)"},{"line_number":611,"context_line":"        else:"},{"line_number":612,"context_line":"            cache_key \u003d \u0027shard-%s/%s/%s\u0027 % (shard, account, container)"},{"line_number":613,"context_line":"    elif obj:"}],"source_content_type":"text/x-python","patch_set":13,"id":"d9770fe8_48c76836","line":610,"in_reply_to":"8f980f5e_70c119ed","updated":"2023-03-07 06:15:01.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":true,"context_lines":[{"line_number":607,"context_line":"        if obj:"},{"line_number":608,"context_line":"            raise ValueError(\u0027Shard cache key cannot have obj\u0027)"},{"line_number":609,"context_line":"        if shard \u003d\u003d \u0027updating\u0027:"},{"line_number":610,"context_line":"            cache_key \u003d \u0027shard-%s-v2/%s/%s\u0027 % (shard, account, container)"},{"line_number":611,"context_line":"        else:"},{"line_number":612,"context_line":"            cache_key \u003d \u0027shard-%s/%s/%s\u0027 % (shard, account, container)"},{"line_number":613,"context_line":"    elif obj:"}],"source_content_type":"text/x-python","patch_set":13,"id":"8f980f5e_70c119ed","line":610,"in_reply_to":"a033d3d9_3baa722b","updated":"2023-02-03 12:25:33.000000000","message":"during upgrade older proxies cannot parse the new format if it is stored under the same key","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":288,"context_line":"                         :class:`swift.common.memcached.MemcacheRing`."},{"line_number":289,"context_line":"        :param cache_key: the cache key for both infocache and memcache."},{"line_number":290,"context_line":"        :return: a tuple of (list of lowerbounds, cache state),"},{"line_number":291,"context_line":"            each lowerbound is in the format [lower_str, name_str]"},{"line_number":292,"context_line":"        \"\"\""},{"line_number":293,"context_line":"        # try get namespaces from infocache first"},{"line_number":294,"context_line":"        namespaces \u003d infocache.get(cache_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"40339901_7e646a9a","line":291,"range":{"start_line":291,"start_character":12,"end_line":291,"end_character":66},"updated":"2023-01-26 17:09:20.000000000","message":"this description makes me lean towards encapsulating the compact representation of (bound, name) in a class","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":288,"context_line":"                         :class:`swift.common.memcached.MemcacheRing`."},{"line_number":289,"context_line":"        :param cache_key: the cache key for both infocache and memcache."},{"line_number":290,"context_line":"        :return: a tuple of (list of lowerbounds, cache state),"},{"line_number":291,"context_line":"            each lowerbound is in the format [lower_str, name_str]"},{"line_number":292,"context_line":"        \"\"\""},{"line_number":293,"context_line":"        # try get namespaces from infocache first"},{"line_number":294,"context_line":"        namespaces \u003d infocache.get(cache_key)"}],"source_content_type":"text/x-python","patch_set":5,"id":"c5a09e3a_32abad11","line":291,"range":{"start_line":291,"start_character":12,"end_line":291,"end_character":66},"in_reply_to":"40339901_7e646a9a","updated":"2023-01-27 01:18:58.000000000","message":"I was thinking it too. thanks!","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":305,"context_line":"            cache_state \u003d \u0027hit\u0027 if namespaces else \u0027miss\u0027"},{"line_number":306,"context_line":"        except MemcacheConnectionError:"},{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":"        return namespaces or [], cache_state"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    def _get_update_shard_caching_disabled(self, req, account, container, obj):"},{"line_number":311,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"c442f766_e5ce157a","line":308,"range":{"start_line":308,"start_character":25,"end_line":308,"end_character":31},"updated":"2023-01-26 17:09:20.000000000","message":"I don\u0027t think \u0027or []\u0027 is necessary - the condition at line 356 will be False for return value of None.\n\nSame for line 299 and line 302: they could be\n\n  return None, \u0027skip\u0027","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":305,"context_line":"            cache_state \u003d \u0027hit\u0027 if namespaces else \u0027miss\u0027"},{"line_number":306,"context_line":"        except MemcacheConnectionError:"},{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":"        return namespaces or [], cache_state"},{"line_number":309,"context_line":""},{"line_number":310,"context_line":"    def _get_update_shard_caching_disabled(self, req, account, container, obj):"},{"line_number":311,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"47f5c9ea_22e89bf6","line":308,"range":{"start_line":308,"start_character":25,"end_line":308,"end_character":31},"in_reply_to":"c442f766_e5ce157a","updated":"2023-01-27 01:18:58.000000000","message":"Done","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"858b8541710ce441ceb26fac02279f7144ff31a3","unresolved":false,"context_lines":[{"line_number":324,"context_line":"            req, account, container, states\u003d\u0027updating\u0027, includes\u003dobj)"},{"line_number":325,"context_line":"        record_cache_op_metrics("},{"line_number":326,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":327,"context_line":"        return find_shard_range(obj, shard_ranges or [])"},{"line_number":328,"context_line":""},{"line_number":329,"context_line":"    def _get_update_shard(self, req, account, container, obj):"},{"line_number":330,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":5,"id":"e20cfbe0_01a5188f","line":327,"updated":"2023-01-26 02:20:15.000000000","message":"this was changed by me from original \"return shard_ranges[0]\", just revert it back.","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":355,"context_line":"            infocache, memcache, cache_key)"},{"line_number":356,"context_line":"        if cached_namespaces:"},{"line_number":357,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":358,"context_line":"            infocache[cache_key] \u003d tuple(cached_namespaces)"},{"line_number":359,"context_line":"            namespace \u003d find_namespace(obj, cached_namespaces)"},{"line_number":360,"context_line":"            update_shard \u003d ShardRange("},{"line_number":361,"context_line":"                namespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"}],"source_content_type":"text/x-python","patch_set":5,"id":"f15d4438_52f2e247","line":358,"range":{"start_line":358,"start_character":35,"end_line":358,"end_character":40},"updated":"2023-01-26 17:09:20.000000000","message":"I\u0027m not sure why we cast to a tuple here - unless it is to deliberately make the object in infocache immutable?","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":355,"context_line":"            infocache, memcache, cache_key)"},{"line_number":356,"context_line":"        if cached_namespaces:"},{"line_number":357,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":358,"context_line":"            infocache[cache_key] \u003d tuple(cached_namespaces)"},{"line_number":359,"context_line":"            namespace \u003d find_namespace(obj, cached_namespaces)"},{"line_number":360,"context_line":"            update_shard \u003d ShardRange("},{"line_number":361,"context_line":"                namespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"}],"source_content_type":"text/x-python","patch_set":5,"id":"d14756bb_c5b868e1","line":358,"range":{"start_line":358,"start_character":35,"end_line":358,"end_character":40},"in_reply_to":"f15d4438_52f2e247","updated":"2023-01-27 01:18:58.000000000","message":"Got confirmed from Tim, yes, seems it\u0027s only for that purpose.","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e9ec694912731b34bdab369a4c1b07964e20b59b","unresolved":true,"context_lines":[{"line_number":356,"context_line":"        if cached_namespaces:"},{"line_number":357,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":358,"context_line":"            infocache[cache_key] \u003d tuple(cached_namespaces)"},{"line_number":359,"context_line":"            namespace \u003d find_namespace(obj, cached_namespaces)"},{"line_number":360,"context_line":"            update_shard \u003d ShardRange("},{"line_number":361,"context_line":"                namespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":362,"context_line":"                upper\u003dnamespace.upper) if namespace else None"}],"source_content_type":"text/x-python","patch_set":5,"id":"5e05ef28_660267ca","line":359,"range":{"start_line":359,"start_character":24,"end_line":359,"end_character":62},"updated":"2023-01-26 17:09:20.000000000","message":"Maybe it\u0027s just a style thing, but I\u0027m still inclined to encapsulate all the namespace bound compaction stuff into a class, rather than bouncing a list of tuples to a function - if only because it means I only have to go to one place in the code to understand what is going on with the bounds representation.","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7363fba5b72802f205436e735dfc845aaec52dd7","unresolved":false,"context_lines":[{"line_number":356,"context_line":"        if cached_namespaces:"},{"line_number":357,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":358,"context_line":"            infocache[cache_key] \u003d tuple(cached_namespaces)"},{"line_number":359,"context_line":"            namespace \u003d find_namespace(obj, cached_namespaces)"},{"line_number":360,"context_line":"            update_shard \u003d ShardRange("},{"line_number":361,"context_line":"                namespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":362,"context_line":"                upper\u003dnamespace.upper) if namespace else None"}],"source_content_type":"text/x-python","patch_set":5,"id":"0d824aad_ba350e6e","line":359,"range":{"start_line":359,"start_character":24,"end_line":359,"end_character":62},"in_reply_to":"5e05ef28_660267ca","updated":"2023-01-27 01:18:58.000000000","message":"Ack","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"858b8541710ce441ceb26fac02279f7144ff31a3","unresolved":false,"context_lines":[{"line_number":359,"context_line":"            namespace \u003d find_namespace(obj, cached_namespaces)"},{"line_number":360,"context_line":"            update_shard \u003d ShardRange("},{"line_number":361,"context_line":"                namespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":362,"context_line":"                upper\u003dnamespace.upper) if namespace else None"},{"line_number":363,"context_line":"        else:"},{"line_number":364,"context_line":"            # pull full set of updating shards from backend"},{"line_number":365,"context_line":"            shard_ranges, response \u003d self._get_shard_ranges("}],"source_content_type":"text/x-python","patch_set":5,"id":"50882336_c9f90c8b","line":362,"updated":"2023-01-26 02:20:15.000000000","message":"here namespace won\u0027t be None","commit_id":"1a3061498d3c0bcbea572543e153779f9218f2da"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"858b8541710ce441ceb26fac02279f7144ff31a3","unresolved":true,"context_lines":[{"line_number":326,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":327,"context_line":"        if not shard_ranges:"},{"line_number":328,"context_line":"            return None"},{"line_number":329,"context_line":"        return shard_ranges[0]"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _get_update_shard(self, req, account, container, obj):"},{"line_number":332,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"6e1a922b_ea59a992","line":329,"updated":"2023-01-26 02:20:15.000000000","message":"but why in the original code, we return shard_ranges[0]?","commit_id":"5d05f3f48ee44ebb080c0738134c8f35fb6fa675"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":326,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":327,"context_line":"        if not shard_ranges:"},{"line_number":328,"context_line":"            return None"},{"line_number":329,"context_line":"        return shard_ranges[0]"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _get_update_shard(self, req, account, container, obj):"},{"line_number":332,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"634870ba_04b92e6b","line":329,"in_reply_to":"494e974e_1e5cd149","updated":"2023-02-01 22:46:47.000000000","message":"Oh, just saw this. Yes, we should go back to just use shard_ranges[0].","commit_id":"5d05f3f48ee44ebb080c0738134c8f35fb6fa675"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":326,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":327,"context_line":"        if not shard_ranges:"},{"line_number":328,"context_line":"            return None"},{"line_number":329,"context_line":"        return shard_ranges[0]"},{"line_number":330,"context_line":""},{"line_number":331,"context_line":"    def _get_update_shard(self, req, account, container, obj):"},{"line_number":332,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"494e974e_1e5cd149","line":329,"in_reply_to":"6e1a922b_ea59a992","updated":"2023-02-01 15:10:04.000000000","message":"when the includes param is sent with a request to GET shard ranges the backend only returns one shard range:\n\nhttps://github.com/openstack/swift/blob/001d931e6a77e7ee9167562a51f8c87ed76e559a/swift/container/backend.py#L1866-L1867\n\nbefore we\u0027d pass this one item list to\n\n  find_shard_range(obj, shard_ranges or [])\n  \nand just get back the one item. So the result is the same as shard_ranges[0].","commit_id":"5d05f3f48ee44ebb080c0738134c8f35fb6fa675"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"44fb026dec24dab14e70df093933f9a3e8ca12e5","unresolved":false,"context_lines":[{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["},{"line_number":314,"context_line":"                    [lower.encode(\u0027utf-8\u0027), name.encode(\u0027utf-8\u0027)]"}],"source_content_type":"text/x-python","patch_set":11,"id":"7d57e32e_e5325628","line":311,"updated":"2023-01-31 05:43:04.000000000","message":"Previously, we encapsulated the utf-8 encoding for PY2 into ShardRange internal function _encode(). Now if we want to hide this, we need another small class \"NamespaceBound\" which only has lower bound and name, but I am not sure if too many new class objects will backfire here in terms of performance.","commit_id":"54a62060e7c592f9d9a468af048ec936d9f47535"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":342,"context_line":"                # found cached shard ranges in either infocache or memcache"},{"line_number":343,"context_line":"                infocache[cache_key] \u003d tuple(cached_ranges)"},{"line_number":344,"context_line":"                shard_ranges \u003d [ShardRange.from_dict(shard_range)"},{"line_number":345,"context_line":"                                for shard_range in cached_ranges]"},{"line_number":346,"context_line":"            else:"},{"line_number":347,"context_line":"                # pull full set of updating shards from backend"},{"line_number":348,"context_line":"                shard_ranges, response \u003d self._get_shard_ranges("}],"source_content_type":"text/x-python","patch_set":13,"id":"47d75d9e_fbd3f18c","side":"PARENT","line":345,"updated":"2023-02-02 15:48:55.000000000","message":"SRL \u003d [sr.from_dict() for sr in cache]\n\n\nIIRC *this* list comprehension that kept showing up in profiling","commit_id":"2d1b68b12eb4bb4e21610a6bcc28f91cb6831c8b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":342,"context_line":"                # found cached shard ranges in either infocache or memcache"},{"line_number":343,"context_line":"                infocache[cache_key] \u003d tuple(cached_ranges)"},{"line_number":344,"context_line":"                shard_ranges \u003d [ShardRange.from_dict(shard_range)"},{"line_number":345,"context_line":"                                for shard_range in cached_ranges]"},{"line_number":346,"context_line":"            else:"},{"line_number":347,"context_line":"                # pull full set of updating shards from backend"},{"line_number":348,"context_line":"                shard_ranges, response \u003d self._get_shard_ranges("}],"source_content_type":"text/x-python","patch_set":13,"id":"10e5b3a5_3ce356a5","side":"PARENT","line":345,"in_reply_to":"47d75d9e_fbd3f18c","updated":"2023-03-07 06:15:01.000000000","message":"Ack","commit_id":"2d1b68b12eb4bb4e21610a6bcc28f91cb6831c8b"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":348,"context_line":"                shard_ranges, response \u003d self._get_shard_ranges("},{"line_number":349,"context_line":"                    req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":350,"context_line":"                if shard_ranges:"},{"line_number":351,"context_line":"                    cached_ranges \u003d [dict(sr) for sr in shard_ranges]"},{"line_number":352,"context_line":"                    infocache[cache_key] \u003d tuple(cached_ranges)"},{"line_number":353,"context_line":"                    if memcache:"},{"line_number":354,"context_line":"                        memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"dd40eb4c_ffe4b2b8","side":"PARENT","line":351,"updated":"2023-02-02 15:48:55.000000000","message":"SRL \u003d [sr.to_dict() for sr in resp]\n\nthere\u0027s some nice easy to grok symmetry in the existing implementation","commit_id":"2d1b68b12eb4bb4e21610a6bcc28f91cb6831c8b"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":348,"context_line":"                shard_ranges, response \u003d self._get_shard_ranges("},{"line_number":349,"context_line":"                    req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":350,"context_line":"                if shard_ranges:"},{"line_number":351,"context_line":"                    cached_ranges \u003d [dict(sr) for sr in shard_ranges]"},{"line_number":352,"context_line":"                    infocache[cache_key] \u003d tuple(cached_ranges)"},{"line_number":353,"context_line":"                    if memcache:"},{"line_number":354,"context_line":"                        memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"52bf2d9c_065ba025","side":"PARENT","line":351,"in_reply_to":"dd40eb4c_ffe4b2b8","updated":"2023-03-07 06:15:01.000000000","message":"Ack","commit_id":"2d1b68b12eb4bb4e21610a6bcc28f91cb6831c8b"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["}],"source_content_type":"text/x-python","patch_set":13,"id":"100e2d9e_27196b08","line":310,"updated":"2023-02-01 15:10:04.000000000","message":"is this what caused the probe test failure?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["}],"source_content_type":"text/x-python","patch_set":13,"id":"2266a6ab_79250a84","line":310,"in_reply_to":"100e2d9e_27196b08","updated":"2023-02-01 22:46:47.000000000","message":"yes, test failures with PY2.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["},{"line_number":314,"context_line":"                    [lower.encode(\u0027utf-8\u0027), name.encode(\u0027utf-8\u0027)]"},{"line_number":315,"context_line":"                    for lower, name in namespaces]"},{"line_number":316,"context_line":"            namespace_list \u003d NamespaceBoundList(namespaces)"},{"line_number":317,"context_line":"        else:"},{"line_number":318,"context_line":"            namespace_list \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"0c857cb4_b093cf8b","line":315,"range":{"start_line":310,"start_character":0,"end_line":315,"end_character":50},"updated":"2023-02-01 15:10:04.000000000","message":"can this be encapsulated in NamespaceBoundsList?\n\nIn fact, I think we get all this taken care of \u0027for free\u0027 if we run the bounds through a Namespace constructor and have NamespaceBoundsList actually be a NamespaceList which has a method to_bounds() for serialising to memcache. The trade off is instantiating Namespace objects vs instantiating list objects.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":true,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["},{"line_number":314,"context_line":"                    [lower.encode(\u0027utf-8\u0027), name.encode(\u0027utf-8\u0027)]"},{"line_number":315,"context_line":"                    for lower, name in namespaces]"},{"line_number":316,"context_line":"            namespace_list \u003d NamespaceBoundList(namespaces)"},{"line_number":317,"context_line":"        else:"},{"line_number":318,"context_line":"            namespace_list \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"e64eeab0_ebf764ba","line":315,"range":{"start_line":310,"start_character":0,"end_line":315,"end_character":50},"in_reply_to":"0c857cb4_b093cf8b","updated":"2023-02-01 22:46:47.000000000","message":"yeah, I also left a comment on this yesterday. I am reluctant to instantiate Namespace objects and then convert them back to list of bounds, since we saw doing this with ShardRange here takes a lot of CPU during previous profilings.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["},{"line_number":314,"context_line":"                    [lower.encode(\u0027utf-8\u0027), name.encode(\u0027utf-8\u0027)]"},{"line_number":315,"context_line":"                    for lower, name in namespaces]"},{"line_number":316,"context_line":"            namespace_list \u003d NamespaceBoundList(namespaces)"},{"line_number":317,"context_line":"        else:"},{"line_number":318,"context_line":"            namespace_list \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"4b5dc9e3_be1bcf98","line":315,"range":{"start_line":310,"start_character":0,"end_line":315,"end_character":50},"in_reply_to":"370ba618_09534783","updated":"2023-03-07 06:15:01.000000000","message":"This piece of code is only for PY2, we should remove it after PY3 migration is done.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":307,"context_line":"            cache_state \u003d \u0027error\u0027"},{"line_number":308,"context_line":""},{"line_number":309,"context_line":"        if namespaces:"},{"line_number":310,"context_line":"            if six.PY2:"},{"line_number":311,"context_line":"                # json.loads() in memcache.get will convert json \u0027string\u0027 to"},{"line_number":312,"context_line":"                # \u0027unicode\u0027 with python2, here we cast \u0027unicode\u0027 back to \u0027str\u0027"},{"line_number":313,"context_line":"                namespaces \u003d ["},{"line_number":314,"context_line":"                    [lower.encode(\u0027utf-8\u0027), name.encode(\u0027utf-8\u0027)]"},{"line_number":315,"context_line":"                    for lower, name in namespaces]"},{"line_number":316,"context_line":"            namespace_list \u003d NamespaceBoundList(namespaces)"},{"line_number":317,"context_line":"        else:"},{"line_number":318,"context_line":"            namespace_list \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"370ba618_09534783","line":315,"range":{"start_line":310,"start_character":0,"end_line":315,"end_character":50},"in_reply_to":"e64eeab0_ebf764ba","updated":"2023-02-02 15:48:55.000000000","message":"we definately want to optimize/measure the construction of the list (which will be huge) into which we bisect - but it would be WAY better if all that optimization/measurement was encasulated in single container/class.\n\nhttps://levelup.gitconnected.com/how-to-deserialize-json-to-custom-class-objects-in-python-d8b92949cd3b\n\nI don\u0027t think I understand how bytes/str effects sort order.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":318,"context_line":"            namespace_list \u003d None"},{"line_number":319,"context_line":"        return namespace_list, cache_state"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _get_update_shard_caching_disabled(self, req, account, container, obj):"},{"line_number":322,"context_line":"        \"\"\""},{"line_number":323,"context_line":"        Fetch all updating shard ranges for the given root container when"},{"line_number":324,"context_line":"        all caching is disabled."}],"source_content_type":"text/x-python","patch_set":13,"id":"f2e792cb_f1a358bf","line":321,"updated":"2023-02-01 15:10:04.000000000","message":"I\u0027m ambivalent about this being extracted to a method. Yes, it saves one level of indent, but it requires this line to be duplicated\n\n  record_cache_op_metrics(\n            self.logger, \u0027shard_updating\u0027, cache_state, response)\n            \nand causes the potential confusion over why find_shard_ranges isn\u0027t needed in this case.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":318,"context_line":"            namespace_list \u003d None"},{"line_number":319,"context_line":"        return namespace_list, cache_state"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _get_update_shard_caching_disabled(self, req, account, container, obj):"},{"line_number":322,"context_line":"        \"\"\""},{"line_number":323,"context_line":"        Fetch all updating shard ranges for the given root container when"},{"line_number":324,"context_line":"        all caching is disabled."}],"source_content_type":"text/x-python","patch_set":13,"id":"1f573adc_3deac626","line":321,"in_reply_to":"f2e792cb_f1a358bf","updated":"2023-02-01 22:46:47.000000000","message":"Blame me, I came from a kernel coding style which requires no more than three levels of indentation for every function and I really like that. :-)\nSince we are going to use shard_range[0] which is the only one, I am going to keep this function.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":336,"context_line":"        record_cache_op_metrics("},{"line_number":337,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":338,"context_line":"        if not shard_ranges:"},{"line_number":339,"context_line":"            return None"},{"line_number":340,"context_line":"        return shard_ranges[0]"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def _get_update_shard(self, req, account, container, obj):"}],"source_content_type":"text/x-python","patch_set":13,"id":"30ab1401_377ce3bb","line":339,"updated":"2023-02-01 15:10:04.000000000","message":"could write:\n\n  return shard_ranges[0] if shard_ranges else None","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":336,"context_line":"        record_cache_op_metrics("},{"line_number":337,"context_line":"            self.logger, \u0027shard_updating\u0027, \u0027disabled\u0027, response)"},{"line_number":338,"context_line":"        if not shard_ranges:"},{"line_number":339,"context_line":"            return None"},{"line_number":340,"context_line":"        return shard_ranges[0]"},{"line_number":341,"context_line":""},{"line_number":342,"context_line":"    def _get_update_shard(self, req, account, container, obj):"}],"source_content_type":"text/x-python","patch_set":13,"id":"1da35714_83998f2a","line":339,"in_reply_to":"30ab1401_377ce3bb","updated":"2023-02-01 22:46:47.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":357,"context_line":"        if not self.app.recheck_updating_shard_ranges:"},{"line_number":358,"context_line":"            # caching is disabled"},{"line_number":359,"context_line":"            return self._get_update_shard_caching_disabled("},{"line_number":360,"context_line":"                req, account, container, obj)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"        # caching is enabled, try to get from caches"},{"line_number":363,"context_line":"        response \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"43aec432_440abef3","line":360,"updated":"2023-02-01 15:10:04.000000000","message":"hmmm, so if memcache is disabled we don\u0027t put the shard ranges into infocache - probably doesn\u0027t matter, but if a middleware ever wanted to access them then it could be useful.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":357,"context_line":"        if not self.app.recheck_updating_shard_ranges:"},{"line_number":358,"context_line":"            # caching is disabled"},{"line_number":359,"context_line":"            return self._get_update_shard_caching_disabled("},{"line_number":360,"context_line":"                req, account, container, obj)"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"        # caching is enabled, try to get from caches"},{"line_number":363,"context_line":"        response \u003d None"}],"source_content_type":"text/x-python","patch_set":13,"id":"db5ca7a3_4a247af3","line":360,"in_reply_to":"43aec432_440abef3","updated":"2023-02-01 22:46:47.000000000","message":"I am implementing the proxy local cache as well. I replaced infocache for updating shard ranges with local cache. Will cover this behavior with new local cache too.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":370,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":371,"context_line":"            infocache[cache_key] \u003d cached_namespaces"},{"line_number":372,"context_line":"            namespace \u003d cached_namespaces.get_namespace(obj)"},{"line_number":373,"context_line":"            update_shard \u003d ShardRange("},{"line_number":374,"context_line":"                name\u003dnamespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":375,"context_line":"                upper\u003dnamespace.upper)"},{"line_number":376,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"bfb7a4db_3477e51a","line":373,"updated":"2023-02-01 15:10:04.000000000","message":"this is unfortunate - we have to cast to a ShardRange just so that _get_update_target can use the account and container attributes of ShardRange 😞\n\nI had hoped that the name parsing to account/container could be kept out of Namespace, but I wonder if we should move it there - it just means that whenever a Namespace is  instantiated its name must be of the form \u0027a/c\u0027.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":370,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":371,"context_line":"            infocache[cache_key] \u003d cached_namespaces"},{"line_number":372,"context_line":"            namespace \u003d cached_namespaces.get_namespace(obj)"},{"line_number":373,"context_line":"            update_shard \u003d ShardRange("},{"line_number":374,"context_line":"                name\u003dnamespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":375,"context_line":"                upper\u003dnamespace.upper)"},{"line_number":376,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"ed0c6416_4028f2a6","line":373,"in_reply_to":"730c50d7_0eaf0157","updated":"2023-02-02 15:48:55.000000000","message":"yup, this bugs me too - in seems like the old implementation was more:\n\n    if cached_ranges:\n        shard_ranges \u003d ...\n    else:\n        shard_ranges \u003d fetch_from_backed()\n    return find_shard_range(shard_ranges)\n\nthis is more \n\n    if cached_ranges:\n        shard_ranges \u003d ...\n        shard \u003d do_one_thing(shard_ranges)\n    else:\n        shard_ranges \u003d fetch_from_backed()\n        shard \u003d do_different_thing(shard_ranges)\n    return shard\n    \n... and that makes less sense to me - because I want the code that picks the shard ranges to be the same in either case, I want us to normalize either a cache lookup or a backend response to a NBL (or SRL?) and then have a single method that will find the right shard regardless of where the list came from.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":true,"context_lines":[{"line_number":370,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":371,"context_line":"            infocache[cache_key] \u003d cached_namespaces"},{"line_number":372,"context_line":"            namespace \u003d cached_namespaces.get_namespace(obj)"},{"line_number":373,"context_line":"            update_shard \u003d ShardRange("},{"line_number":374,"context_line":"                name\u003dnamespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":375,"context_line":"                upper\u003dnamespace.upper)"},{"line_number":376,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"730c50d7_0eaf0157","line":373,"in_reply_to":"bfb7a4db_3477e51a","updated":"2023-02-01 22:46:47.000000000","message":"That\u0027s right. But here we only instantiate one ShardRange object for one object update path, should not be a problem? I am fine with either way.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":370,"context_line":"            # found cached namespaces in either infocache or memcache"},{"line_number":371,"context_line":"            infocache[cache_key] \u003d cached_namespaces"},{"line_number":372,"context_line":"            namespace \u003d cached_namespaces.get_namespace(obj)"},{"line_number":373,"context_line":"            update_shard \u003d ShardRange("},{"line_number":374,"context_line":"                name\u003dnamespace.name, timestamp\u003d0, lower\u003dnamespace.lower,"},{"line_number":375,"context_line":"                upper\u003dnamespace.upper)"},{"line_number":376,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":13,"id":"5e75d124_12a147f0","line":373,"in_reply_to":"ed0c6416_4028f2a6","updated":"2023-03-07 06:15:01.000000000","message":"added more comments to make new implementation clearer.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"eb3019b3e12de30c59969020926250dd6d00dcb1","unresolved":true,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"807e87b0_0da536b8","line":382,"updated":"2023-02-02 15:48:55.000000000","message":"NBL.from_namespaces(shard_ranges) reads a little funny, like I know a ShardRange is a Namespace - but do we ever build a NBL from a list of actual Namespace objects?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a2e9b841c2b82372c7ebccb99caeaca9cdcbc141","unresolved":true,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"837ab6c1_015b206f","line":382,"in_reply_to":"053a8aa4_e4f14fb4","updated":"2023-03-01 03:28:02.000000000","message":"how about something about what it does instead, like CompactBoundsList or something. Then it can take in Namespaces or ShardRanges (which is does) but also says something about what it does that\u0027s special?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"109f67f430f1ed8aebc164245a010984bd9ef2fd","unresolved":true,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"053a8aa4_e4f14fb4","line":382,"in_reply_to":"807e87b0_0da536b8","updated":"2023-02-03 12:25:33.000000000","message":"IMHO the method name should communicate what the method accepts, not what the caller chooses to pass in.\n\nI\u0027d have less objection to renaming to something bland like parse(), but I\u0027d dislike renaming to e.g. \u0027from_shard_ranges()\u0027 for the following reasons:\n\n* Future me will always get a good idea of what the method accepts from its name. We may not currently pass in Namespaces, but we *can*, and if the method is called from_shard_ranges then at first glance it suggests that we *cannot* pass in just Namespaces.\n\n* The method docstring is consistent with its name (oops, we don\u0027t have a docstring on this method yet!). Do we change the arg name to \u0027shard_ranges\u0027, but then document it as being a list of Namespaces? that doesn\u0027t stack up.\n\n* If in future a caller ever chooses to pass in a list of Namespaces then we don\u0027t have to consider changing the method name (from_shard_ranges -\u003e from_namespaces) to adapt to the caller\u0027s whims.\n\nWhat I\u0027d like is to have polymorphic constructors 😄 I did consider having the constructor accept either bounds or Namespaces, then type-testing and doing the right-thing.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"fea77099_fa33a499","line":382,"in_reply_to":"837ab6c1_015b206f","updated":"2023-03-07 06:15:01.000000000","message":"Changed to \"parse()\", I feel it is more concise. Also added more details into docstring.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"2d9895aba09b838acda09fb266756230d0f4d946","unresolved":true,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"ff6f23c6_aceae8e9","line":382,"in_reply_to":"8d0f24bf_07e56c0b","updated":"2023-03-10 06:17:45.000000000","message":"Yeah parse is much better!","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7822b90ac5ed535642814ba5ac447cc7ea1445ff","unresolved":true,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"8d0f24bf_07e56c0b","line":382,"in_reply_to":"fea77099_fa33a499","updated":"2023-03-07 06:24:11.000000000","message":"After test codes are changed to parse(), they do read less funny now. 😊 Mat, what do you think?","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b78b011d1e3714fcc957f6e36615aaa603606bd2","unresolved":false,"context_lines":[{"line_number":379,"context_line":"                req, account, container, states\u003d\u0027updating\u0027)"},{"line_number":380,"context_line":"            if shard_ranges:"},{"line_number":381,"context_line":"                cached_namespaces \u003d NamespaceBoundList.from_namespaces("},{"line_number":382,"context_line":"                    shard_ranges)"},{"line_number":383,"context_line":"                infocache[cache_key] \u003d cached_namespaces"},{"line_number":384,"context_line":"                if memcache:"},{"line_number":385,"context_line":"                    memcache.set("}],"source_content_type":"text/x-python","patch_set":13,"id":"40d503fc_136ead03","line":382,"in_reply_to":"ff6f23c6_aceae8e9","updated":"2023-03-15 15:39:46.000000000","message":"Done","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":398,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":399,"context_line":"            if shard_range:"},{"line_number":400,"context_line":"                partition, nodes \u003d self.app.container_ring.get_nodes("},{"line_number":401,"context_line":"                    shard_range.account, shard_range.container)"},{"line_number":402,"context_line":"                return partition, nodes, shard_range.name"},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"        return container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027], None"}],"source_content_type":"text/x-python","patch_set":13,"id":"12d54b81_8b2609c0","line":401,"updated":"2023-02-01 15:10:04.000000000","message":"we don\u0027t need this to be a ShardRange except for the \u0027name\u0027 parsing to account/container","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"9ab6fb68c6465f4c9efb97c36312e55c8be8bdb5","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":399,"context_line":"            if shard_range:"},{"line_number":400,"context_line":"                partition, nodes \u003d self.app.container_ring.get_nodes("},{"line_number":401,"context_line":"                    shard_range.account, shard_range.container)"},{"line_number":402,"context_line":"                return partition, nodes, shard_range.name"},{"line_number":403,"context_line":""},{"line_number":404,"context_line":"        return container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027], None"}],"source_content_type":"text/x-python","patch_set":13,"id":"e06222d9_161fbbca","line":401,"in_reply_to":"12d54b81_8b2609c0","updated":"2023-03-07 06:15:01.000000000","message":"Yes, that\u0027s right. Luckily it\u0027s only one ShardRange object instantiation per call.","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"}],"test/unit/common/test_utils.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":8144,"context_line":"        self.assertLess(a_ftol_ns, a_ltor_ns)"},{"line_number":8145,"context_line":"        self.assertLess(a_ltor_ns, a_rtoz_ns)"},{"line_number":8146,"context_line":"        self.assertLess(a_rtoz_ns, a_end_ns)"},{"line_number":8147,"context_line":"        self.assertLessEqual(a_start_ns, a_atof_ns)"},{"line_number":8148,"context_line":"        self.assertLessEqual(a_atof_ns, a_rtoz_ns)"},{"line_number":8149,"context_line":"        self.assertGreater(a_end_ns, a_atof_ns)"},{"line_number":8150,"context_line":"        self.assertGreater(a_rtoz_ns, a_ftol_ns)"}],"source_content_type":"text/x-python","patch_set":13,"id":"523d15ce_6a4efe08","line":8147,"updated":"2023-02-01 15:10:04.000000000","message":"also \n\n  self.assertLessEqual(a_atof_ns, a_atof_ns)","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":8144,"context_line":"        self.assertLess(a_ftol_ns, a_ltor_ns)"},{"line_number":8145,"context_line":"        self.assertLess(a_ltor_ns, a_rtoz_ns)"},{"line_number":8146,"context_line":"        self.assertLess(a_rtoz_ns, a_end_ns)"},{"line_number":8147,"context_line":"        self.assertLessEqual(a_start_ns, a_atof_ns)"},{"line_number":8148,"context_line":"        self.assertLessEqual(a_atof_ns, a_rtoz_ns)"},{"line_number":8149,"context_line":"        self.assertGreater(a_end_ns, a_atof_ns)"},{"line_number":8150,"context_line":"        self.assertGreater(a_rtoz_ns, a_ftol_ns)"}],"source_content_type":"text/x-python","patch_set":13,"id":"9664f478_5b3c1e79","line":8147,"in_reply_to":"523d15ce_6a4efe08","updated":"2023-02-01 22:46:47.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":8149,"context_line":"        self.assertGreater(a_end_ns, a_atof_ns)"},{"line_number":8150,"context_line":"        self.assertGreater(a_rtoz_ns, a_ftol_ns)"},{"line_number":8151,"context_line":"        self.assertGreater(a_end_ns, a_start_ns)"},{"line_number":8152,"context_line":"        self.assertGreaterEqual(a_end_ns, a_atof_ns)"},{"line_number":8153,"context_line":"        self.assertGreaterEqual(a_rtoz_ns, a_start_ns)"},{"line_number":8154,"context_line":""},{"line_number":8155,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"a283377f_b00ac0c7","line":8152,"updated":"2023-02-01 15:10:04.000000000","message":"also\n\n  self.assertGreaterEqual(a_atof_ns, a_atof_ns)","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":8149,"context_line":"        self.assertGreater(a_end_ns, a_atof_ns)"},{"line_number":8150,"context_line":"        self.assertGreater(a_rtoz_ns, a_ftol_ns)"},{"line_number":8151,"context_line":"        self.assertGreater(a_end_ns, a_start_ns)"},{"line_number":8152,"context_line":"        self.assertGreaterEqual(a_end_ns, a_atof_ns)"},{"line_number":8153,"context_line":"        self.assertGreaterEqual(a_rtoz_ns, a_start_ns)"},{"line_number":8154,"context_line":""},{"line_number":8155,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"d4edf78f_db3a75d5","line":8152,"in_reply_to":"a283377f_b00ac0c7","updated":"2023-02-01 22:46:47.000000000","message":"Done","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"96bbb81126912fc5e4c51674638f62265373fc8c","unresolved":true,"context_lines":[{"line_number":8168,"context_line":"        end \u003d [\u0027z\u0027, \u0027a/z-\u0027]"},{"line_number":8169,"context_line":"        end_ns \u003d utils.Namespace(\u0027a/z-\u0027, \u0027z\u0027, \u0027\u0027)"},{"line_number":8170,"context_line":"        lowerbounds \u003d [start, atof, ftol, ltor, rtoz, end]"},{"line_number":8171,"context_line":"        namespace_list \u003d utils.NamespaceBoundList(lowerbounds)"},{"line_number":8172,"context_line":""},{"line_number":8173,"context_line":"        # test \u0027get_namespace\u0027"},{"line_number":8174,"context_line":"        self.assertEqual(namespace_list.get_namespace(\u00271\u0027), start_ns)"}],"source_content_type":"text/x-python","patch_set":13,"id":"fb7f25cb_a1ffaafd","line":8171,"updated":"2023-02-01 15:10:04.000000000","message":"we can use setUp to create the re-used vars and then have a test method for each function","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3e467fa4f019c847454cdf965e34ca89c028038","unresolved":false,"context_lines":[{"line_number":8168,"context_line":"        end \u003d [\u0027z\u0027, \u0027a/z-\u0027]"},{"line_number":8169,"context_line":"        end_ns \u003d utils.Namespace(\u0027a/z-\u0027, \u0027z\u0027, \u0027\u0027)"},{"line_number":8170,"context_line":"        lowerbounds \u003d [start, atof, ftol, ltor, rtoz, end]"},{"line_number":8171,"context_line":"        namespace_list \u003d utils.NamespaceBoundList(lowerbounds)"},{"line_number":8172,"context_line":""},{"line_number":8173,"context_line":"        # test \u0027get_namespace\u0027"},{"line_number":8174,"context_line":"        self.assertEqual(namespace_list.get_namespace(\u00271\u0027), start_ns)"}],"source_content_type":"text/x-python","patch_set":13,"id":"aa721d4c_a34c4714","line":8171,"in_reply_to":"fb7f25cb_a1ffaafd","updated":"2023-02-01 22:46:47.000000000","message":"Ack","commit_id":"a56ddb39f9357d405269d52f47bd3398487b949e"}]}
