)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b0fe23062b5d7cb86b2316279d5b707fa3e460ac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"85e83e02_b06317b1","updated":"2023-07-17 16:45:32.000000000","message":"i think this is a really good idea","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7bc82911f2c8e230a1fd8c7f595a44f1eba2bd5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"7e6c70af_8ee14c98","updated":"2023-07-20 21:03:50.000000000","message":"LGTM, thanks!","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"93333fd25c27c61f73fd56e8e15b0f63d16db0ae","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"abad1ca8_9d4da6b9","updated":"2023-07-24 04:34:56.000000000","message":"Looks pretty great to me. We might carry this in prod for the ultimate test.. so might hold off landing it for now (even though that sounds backwards) :P","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"}],"swift/container/backend.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f1ebe2f636ea97bcc5cf213a6d1f9c7199deddba","unresolved":true,"context_lines":[{"line_number":1875,"context_line":"        if includes:"},{"line_number":1876,"context_line":"            return shard_ranges[:1] if shard_ranges else []"},{"line_number":1877,"context_line":""},{"line_number":1878,"context_line":"        shard_ranges \u003d filter_namespaces("},{"line_number":1879,"context_line":"            shard_ranges, includes, marker, end_marker)"},{"line_number":1880,"context_line":""},{"line_number":1881,"context_line":"        if fill_gaps:"}],"source_content_type":"text/x-python","patch_set":1,"id":"64ecde54_403edd40","line":1878,"updated":"2023-07-12 17:35:53.000000000","message":"this can probably go","commit_id":"91cde88d9e10feaef34e8a28a24339cfb9e5a0f8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4d891cda23e1c1a5549c9ef56a09c1386468ccf4","unresolved":false,"context_lines":[{"line_number":1875,"context_line":"        if includes:"},{"line_number":1876,"context_line":"            return shard_ranges[:1] if shard_ranges else []"},{"line_number":1877,"context_line":""},{"line_number":1878,"context_line":"        shard_ranges \u003d filter_namespaces("},{"line_number":1879,"context_line":"            shard_ranges, includes, marker, end_marker)"},{"line_number":1880,"context_line":""},{"line_number":1881,"context_line":"        if fill_gaps:"}],"source_content_type":"text/x-python","patch_set":1,"id":"529d9aed_f552d07b","line":1878,"in_reply_to":"64ecde54_403edd40","updated":"2023-07-19 14:01:13.000000000","message":"Done","commit_id":"91cde88d9e10feaef34e8a28a24339cfb9e5a0f8"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b0fe23062b5d7cb86b2316279d5b707fa3e460ac","unresolved":true,"context_lines":[{"line_number":1748,"context_line":"                    params.append(end_marker)"},{"line_number":1749,"context_line":"                if marker:"},{"line_number":1750,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1751,"context_line":"                    params.append(marker)"},{"line_number":1752,"context_line":"            else:"},{"line_number":1753,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"},{"line_number":1754,"context_line":"                params.extend((includes, includes))"}],"source_content_type":"text/x-python","patch_set":2,"id":"555a38b9_07eedaaa","line":1751,"updated":"2023-07-17 16:45:32.000000000","message":"this boolean seems to match up with the query for includes","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4d891cda23e1c1a5549c9ef56a09c1386468ccf4","unresolved":false,"context_lines":[{"line_number":1748,"context_line":"                    params.append(end_marker)"},{"line_number":1749,"context_line":"                if marker:"},{"line_number":1750,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1751,"context_line":"                    params.append(marker)"},{"line_number":1752,"context_line":"            else:"},{"line_number":1753,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"},{"line_number":1754,"context_line":"                params.extend((includes, includes))"}],"source_content_type":"text/x-python","patch_set":2,"id":"094d30eb_37de8650","line":1751,"in_reply_to":"555a38b9_07eedaaa","updated":"2023-07-19 14:01:13.000000000","message":"Ack","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"7913ae981bb3fa63d3f2774ef63b470f7f783688","unresolved":true,"context_lines":[{"line_number":1702,"context_line":"        :param end_marker: restricts the returned list to rows whose namespace"},{"line_number":1703,"context_line":"            includes or is less than the end_marker value."},{"line_number":1704,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1705,"context_line":"            includes the given value"},{"line_number":1706,"context_line":"        :param include_deleted: include rows marked as deleted"},{"line_number":1707,"context_line":"        :param states: include only rows matching the given state(s); can be an"},{"line_number":1708,"context_line":"            int or a list of ints."}],"source_content_type":"text/x-python","patch_set":3,"id":"2af448a1_f867e2dd","line":1705,"updated":"2023-07-19 23:48:24.000000000","message":"add the same sentence in the doc string as the public interface: \"if ``includes`` is specified then ``marker`` and ``end_marker`` are ignored.\".","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de52ee0a798bf2d8bdd05d5dd5f5c4f203578b","unresolved":false,"context_lines":[{"line_number":1702,"context_line":"        :param end_marker: restricts the returned list to rows whose namespace"},{"line_number":1703,"context_line":"            includes or is less than the end_marker value."},{"line_number":1704,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1705,"context_line":"            includes the given value"},{"line_number":1706,"context_line":"        :param include_deleted: include rows marked as deleted"},{"line_number":1707,"context_line":"        :param states: include only rows matching the given state(s); can be an"},{"line_number":1708,"context_line":"            int or a list of ints."}],"source_content_type":"text/x-python","patch_set":3,"id":"19349310_d55630e9","line":1705,"in_reply_to":"2af448a1_f867e2dd","updated":"2023-07-20 13:05:14.000000000","message":"Done","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"5bd8aac6b2ee190d9b0a08cd52bf98b39fc473ef","unresolved":false,"context_lines":[{"line_number":1751,"context_line":"                    conditions.append(\u0027lower \u003c ?\u0027)"},{"line_number":1752,"context_line":"                    params.append(end_marker)"},{"line_number":1753,"context_line":"                if marker:"},{"line_number":1754,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1755,"context_line":"                    params.append(marker)"},{"line_number":1756,"context_line":"            else:"},{"line_number":1757,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"}],"source_content_type":"text/x-python","patch_set":3,"id":"2126339b_994c15ab","line":1754,"updated":"2023-07-20 05:36:45.000000000","message":"it\u0027s true that \u0027\u0027 \u003c \u0027any_string\u0027, so we only need upper \u003d \u0027\u0027 for upper, lower doesn\u0027t need this.","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"5bd8aac6b2ee190d9b0a08cd52bf98b39fc473ef","unresolved":true,"context_lines":[{"line_number":1843,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1844,"context_line":"            includes the given value; if ``includes`` is specified then"},{"line_number":1845,"context_line":"            ``marker`` and ``end_marker`` are ignored."},{"line_number":1846,"context_line":"        :param reverse: reverse the result order."},{"line_number":1847,"context_line":"        :param include_deleted: include items that have the delete marker set"},{"line_number":1848,"context_line":"        :param states: if specified, restricts the returned list to shard"},{"line_number":1849,"context_line":"            ranges that have the given state(s); can be a list of ints or a"}],"source_content_type":"text/x-python","patch_set":3,"id":"e24237e4_e914bb2f","line":1846,"updated":"2023-07-20 05:36:45.000000000","message":"\"reverse\" not only will reverse the result order, it also does below at line 1869:\n        if reverse:\n            marker, end_marker \u003d end_marker, marker\n\nI feel we need update the doc string.","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d39939a4a1c640b8fb6a5e8910521a1699a6f0b","unresolved":true,"context_lines":[{"line_number":1843,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1844,"context_line":"            includes the given value; if ``includes`` is specified then"},{"line_number":1845,"context_line":"            ``marker`` and ``end_marker`` are ignored."},{"line_number":1846,"context_line":"        :param reverse: reverse the result order."},{"line_number":1847,"context_line":"        :param include_deleted: include items that have the delete marker set"},{"line_number":1848,"context_line":"        :param states: if specified, restricts the returned list to shard"},{"line_number":1849,"context_line":"            ranges that have the given state(s); can be a list of ints or a"}],"source_content_type":"text/x-python","patch_set":3,"id":"f501e7ff_593236b8","line":1846,"in_reply_to":"16ee238b_49e6a787","updated":"2023-07-20 13:23:21.000000000","message":"https://review.opendev.org/c/openstack/swift/+/889095","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de52ee0a798bf2d8bdd05d5dd5f5c4f203578b","unresolved":true,"context_lines":[{"line_number":1843,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1844,"context_line":"            includes the given value; if ``includes`` is specified then"},{"line_number":1845,"context_line":"            ``marker`` and ``end_marker`` are ignored."},{"line_number":1846,"context_line":"        :param reverse: reverse the result order."},{"line_number":1847,"context_line":"        :param include_deleted: include items that have the delete marker set"},{"line_number":1848,"context_line":"        :param states: if specified, restricts the returned list to shard"},{"line_number":1849,"context_line":"            ranges that have the given state(s); can be a list of ints or a"}],"source_content_type":"text/x-python","patch_set":3,"id":"16ee238b_49e6a787","line":1846,"in_reply_to":"e24237e4_e914bb2f","updated":"2023-07-20 13:05:14.000000000","message":"ok but that\u0027s off-topic so can be a different patch","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7bc82911f2c8e230a1fd8c7f595a44f1eba2bd5","unresolved":false,"context_lines":[{"line_number":1843,"context_line":"        :param includes: restricts the returned list to the shard range that"},{"line_number":1844,"context_line":"            includes the given value; if ``includes`` is specified then"},{"line_number":1845,"context_line":"            ``marker`` and ``end_marker`` are ignored."},{"line_number":1846,"context_line":"        :param reverse: reverse the result order."},{"line_number":1847,"context_line":"        :param include_deleted: include items that have the delete marker set"},{"line_number":1848,"context_line":"        :param states: if specified, restricts the returned list to shard"},{"line_number":1849,"context_line":"            ranges that have the given state(s); can be a list of ints or a"}],"source_content_type":"text/x-python","patch_set":3,"id":"fa080c15_d13995c3","line":1846,"in_reply_to":"f501e7ff_593236b8","updated":"2023-07-20 21:03:50.000000000","message":"Done","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"93333fd25c27c61f73fd56e8e15b0f63d16db0ae","unresolved":true,"context_lines":[{"line_number":1685,"context_line":"            if (\u0027no such table: %s\u0027 % SHARD_RANGE_TABLE) not in str(err):"},{"line_number":1686,"context_line":"                raise"},{"line_number":1687,"context_line":""},{"line_number":1688,"context_line":"    def _get_shard_range_rows(self, connection\u003dNone, marker\u003dNone,"},{"line_number":1689,"context_line":"                              end_marker\u003dNone, includes\u003dNone,"},{"line_number":1690,"context_line":"                              include_deleted\u003dFalse, states\u003dNone,"},{"line_number":1691,"context_line":"                              include_own\u003dFalse, exclude_others\u003dFalse):"},{"line_number":1692,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"68f3664e_c2f19602","line":1689,"range":{"start_line":1688,"start_character":53,"end_line":1689,"end_character":45},"updated":"2023-07-24 04:34:56.000000000","message":"We\u0027d normally not add new variables to the front/middle of a function, but this matches other function sigs for getting objects etc. So in this case its ok.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f47b3208ecc6e31a6ec78513b7f36287d5ddbf36","unresolved":true,"context_lines":[{"line_number":1685,"context_line":"            if (\u0027no such table: %s\u0027 % SHARD_RANGE_TABLE) not in str(err):"},{"line_number":1686,"context_line":"                raise"},{"line_number":1687,"context_line":""},{"line_number":1688,"context_line":"    def _get_shard_range_rows(self, connection\u003dNone, marker\u003dNone,"},{"line_number":1689,"context_line":"                              end_marker\u003dNone, includes\u003dNone,"},{"line_number":1690,"context_line":"                              include_deleted\u003dFalse, states\u003dNone,"},{"line_number":1691,"context_line":"                              include_own\u003dFalse, exclude_others\u003dFalse):"},{"line_number":1692,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"02247112_da3f262b","line":1689,"range":{"start_line":1688,"start_character":53,"end_line":1689,"end_character":45},"in_reply_to":"68f3664e_c2f19602","updated":"2023-07-24 10:11:01.000000000","message":"it\u0027s an \u0027_\u0027 method that\u0027s only called from one place so I figured consistent arg order was worth the kwarg shunting","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7bc82911f2c8e230a1fd8c7f595a44f1eba2bd5","unresolved":true,"context_lines":[{"line_number":1754,"context_line":"                    conditions.append(\u0027lower \u003c ?\u0027)"},{"line_number":1755,"context_line":"                    params.append(end_marker)"},{"line_number":1756,"context_line":"                if marker:"},{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"}],"source_content_type":"text/x-python","patch_set":4,"id":"b96e4fd3_176e794f","line":1757,"updated":"2023-07-20 21:03:50.000000000","message":"It makes sense to me we need to have upper \u003d \u0027\u0027, since \u0027\u0027 \u003c \u0027any_string\u0027. \nBut the original code which does the checking doesn\u0027t have upper \u003d \u0027\u0027, at here\nhttps://github.com/NVIDIA/swift/blob/master/swift/common/utils/__init__.py#L5538\ndoes it mean the original namespace_filter function is flawed when checking upper?","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"93333fd25c27c61f73fd56e8e15b0f63d16db0ae","unresolved":true,"context_lines":[{"line_number":1754,"context_line":"                    conditions.append(\u0027lower \u003c ?\u0027)"},{"line_number":1755,"context_line":"                    params.append(end_marker)"},{"line_number":1756,"context_line":"                if marker:"},{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"}],"source_content_type":"text/x-python","patch_set":4,"id":"fac11515_91e7ae7a","line":1757,"range":{"start_line":1757,"start_character":60,"end_line":1757,"end_character":61},"updated":"2023-07-24 04:34:56.000000000","message":"Markers in ranges is interesting. this is \u003e because we need to include the shard range if the maker falls into the range, but if upper IS the marker we don\u0027t want to include it, because normally marker is excluded in pagnation.\n\nKK got it!","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e3e45cf28e0e4068721319ba6ced1c9d0ffb0fd4","unresolved":false,"context_lines":[{"line_number":1754,"context_line":"                    conditions.append(\u0027lower \u003c ?\u0027)"},{"line_number":1755,"context_line":"                    params.append(end_marker)"},{"line_number":1756,"context_line":"                if marker:"},{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"}],"source_content_type":"text/x-python","patch_set":4,"id":"8c3b7756_8f9f993c","line":1757,"in_reply_to":"b96e4fd3_176e794f","updated":"2023-07-21 08:22:18.000000000","message":"That\u0027s a great observation and question!\n\nHere we\u0027re dealing with strings. But the filter_namespaces method compares marker/end_marker against *ShardRange.lower/upper* bounds. A ShardRange uses Namespace.MIN/MAX singletons to represent the empty string outer bounds, and Namespace.MAX is defined to always be greater than any other string. https://github.com/openstack/swift/blob/103adef444a29576a2ba7d52cee43cdc9ed2957b/swift/common/utils/__init__.py#L4534-L4537 \n\nSo we can conveniently write:\n\n```\nimport swift.common.utils as utils\nsr \u003d utils.ShardRange(\u0027a/c\u0027, 123.4)\nsr.upper \u003d \u0027\u0027\n\u0027z\u0027 \u003c sr.upper\nTrue\n\u0027\u0027 \u003c sr.upper\nTrue\nsr.upper_str\n\u0027\u0027\n\u0027\u0027 \u003c sr.upper_str\nFalse\n```\n\nThis is enabled by:\nhttps://github.com/openstack/swift/blob/103adef444a29576a2ba7d52cee43cdc9ed2957b/swift/common/utils/__init__.py#L4409-L4422","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f47b3208ecc6e31a6ec78513b7f36287d5ddbf36","unresolved":false,"context_lines":[{"line_number":1754,"context_line":"                    conditions.append(\u0027lower \u003c ?\u0027)"},{"line_number":1755,"context_line":"                    params.append(end_marker)"},{"line_number":1756,"context_line":"                if marker:"},{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"}],"source_content_type":"text/x-python","patch_set":4,"id":"7969a253_2d6b6b1e","line":1757,"range":{"start_line":1757,"start_character":60,"end_line":1757,"end_character":61},"in_reply_to":"fac11515_91e7ae7a","updated":"2023-07-24 10:11:01.000000000","message":"Ack","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7bc82911f2c8e230a1fd8c7f595a44f1eba2bd5","unresolved":true,"context_lines":[{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"},{"line_number":1761,"context_line":"                params.extend((includes, includes))"},{"line_number":1762,"context_line":"            if conditions:"},{"line_number":1763,"context_line":"                condition \u003d \u0027 WHERE \u0027 + \u0027 AND \u0027.join(conditions)"}],"source_content_type":"text/x-python","patch_set":4,"id":"2a4de6e9_73e1a7b2","line":1760,"updated":"2023-07-20 21:03:50.000000000","message":"an off topic question, I understand \"includes\" is used to include a given value. So here it uses \"upper \u003e\u003d ?\" to include upper bound, but why it doesn\u0027t include lower bound? should it be \"lower \u003c\u003d ?\"","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e3e45cf28e0e4068721319ba6ced1c9d0ffb0fd4","unresolved":false,"context_lines":[{"line_number":1757,"context_line":"                    conditions.append(\"(upper \u003d \u0027\u0027 OR upper \u003e ?)\")"},{"line_number":1758,"context_line":"                    params.append(marker)"},{"line_number":1759,"context_line":"            else:"},{"line_number":1760,"context_line":"                conditions.extend((\u0027lower \u003c ?\u0027, \"(upper \u003d \u0027\u0027 OR upper \u003e\u003d ?)\"))"},{"line_number":1761,"context_line":"                params.extend((includes, includes))"},{"line_number":1762,"context_line":"            if conditions:"},{"line_number":1763,"context_line":"                condition \u003d \u0027 WHERE \u0027 + \u0027 AND \u0027.join(conditions)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3b09f0d9_7b415086","line":1760,"in_reply_to":"2a4de6e9_73e1a7b2","updated":"2023-07-21 08:22:18.000000000","message":"ShardRanges do NOT include their lower bound but DO include their upper bound. A name can only be in one ShardRange, so a ShardRange is a half-open set (lower, upper].\n\n```\nsr \u003d utils.ShardRange(\u0027a/c\u0027, 123.4, \u0027l\u0027, \u0027u\u0027)\n\u0027l\u0027 in sr\nFalse\n\u0027u\u0027 in sr\nTrue\n```\n\nhttps://github.com/openstack/swift/blob/103adef444a29576a2ba7d52cee43cdc9ed2957b/swift/common/utils/__init__.py#L4832-L4836\n\nNote: the docstring is missing for Namespace, I just fixed that: https://review.opendev.org/c/openstack/swift/+/889152","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"93333fd25c27c61f73fd56e8e15b0f63d16db0ae","unresolved":true,"context_lines":[{"line_number":1880,"context_line":"        shard_ranges \u003d ["},{"line_number":1881,"context_line":"            ShardRange(*row)"},{"line_number":1882,"context_line":"            for row in self._get_shard_range_rows("},{"line_number":1883,"context_line":"                marker\u003dmarker, end_marker\u003dend_marker, includes\u003dincludes,"},{"line_number":1884,"context_line":"                include_deleted\u003dinclude_deleted, states\u003dstates,"},{"line_number":1885,"context_line":"                include_own\u003dinclude_own, exclude_others\u003dexclude_others)]"},{"line_number":1886,"context_line":"        shard_ranges.sort(key\u003dShardRange.sort_key)"},{"line_number":1887,"context_line":"        if includes:"},{"line_number":1888,"context_line":"            return shard_ranges[:1] if shard_ranges else []"}],"source_content_type":"text/x-python","patch_set":4,"id":"aa1dd658_23d99a5f","line":1885,"range":{"start_line":1883,"start_character":16,"end_line":1885,"end_character":71},"updated":"2023-07-24 04:34:56.000000000","message":"Luckily we use kwargs here, so marker/end_marker placement didn\u0027t end up being a pain.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f47b3208ecc6e31a6ec78513b7f36287d5ddbf36","unresolved":false,"context_lines":[{"line_number":1880,"context_line":"        shard_ranges \u003d ["},{"line_number":1881,"context_line":"            ShardRange(*row)"},{"line_number":1882,"context_line":"            for row in self._get_shard_range_rows("},{"line_number":1883,"context_line":"                marker\u003dmarker, end_marker\u003dend_marker, includes\u003dincludes,"},{"line_number":1884,"context_line":"                include_deleted\u003dinclude_deleted, states\u003dstates,"},{"line_number":1885,"context_line":"                include_own\u003dinclude_own, exclude_others\u003dexclude_others)]"},{"line_number":1886,"context_line":"        shard_ranges.sort(key\u003dShardRange.sort_key)"},{"line_number":1887,"context_line":"        if includes:"},{"line_number":1888,"context_line":"            return shard_ranges[:1] if shard_ranges else []"}],"source_content_type":"text/x-python","patch_set":4,"id":"c6c901eb_5291247a","line":1885,"range":{"start_line":1883,"start_character":16,"end_line":1885,"end_character":71},"in_reply_to":"aa1dd658_23d99a5f","updated":"2023-07-24 10:11:01.000000000","message":"Ack","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"}],"test/unit/container/test_backend.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b0fe23062b5d7cb86b2316279d5b707fa3e460ac","unresolved":true,"context_lines":[{"line_number":4245,"context_line":"        self.assertFalse(actual)"},{"line_number":4246,"context_line":""},{"line_number":4247,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027b\u0027, marker\u003dNamespace.MAX)"},{"line_number":4248,"context_line":"        self.assertEqual([dict(shard_ranges[0])], [dict(sr) for sr in actual])"},{"line_number":4249,"context_line":""},{"line_number":4250,"context_line":"        orig_execute \u003d GreenDBConnection.execute"},{"line_number":4251,"context_line":"        mock_call_args \u003d []"}],"source_content_type":"text/x-python","patch_set":2,"id":"75c612e5_fe969c12","line":4248,"updated":"2023-07-17 16:45:32.000000000","message":"we probably already have a lot of good coverage on all the marker/end_marker filtering; adding a few more is probably sufficient.","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4d891cda23e1c1a5549c9ef56a09c1386468ccf4","unresolved":false,"context_lines":[{"line_number":4245,"context_line":"        self.assertFalse(actual)"},{"line_number":4246,"context_line":""},{"line_number":4247,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027b\u0027, marker\u003dNamespace.MAX)"},{"line_number":4248,"context_line":"        self.assertEqual([dict(shard_ranges[0])], [dict(sr) for sr in actual])"},{"line_number":4249,"context_line":""},{"line_number":4250,"context_line":"        orig_execute \u003d GreenDBConnection.execute"},{"line_number":4251,"context_line":"        mock_call_args \u003d []"}],"source_content_type":"text/x-python","patch_set":2,"id":"7153f052_3ec5cb42","line":4248,"in_reply_to":"75c612e5_fe969c12","updated":"2023-07-19 14:01:13.000000000","message":"Ack","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b0fe23062b5d7cb86b2316279d5b707fa3e460ac","unresolved":true,"context_lines":[{"line_number":4275,"context_line":"        # verify that includes keyword plumbs through to an SQL condition"},{"line_number":4276,"context_line":"        self.assertIn(\"WHERE deleted\u003d0 AND name !\u003d ? AND lower \u003c ? AND \""},{"line_number":4277,"context_line":"                      \"(upper \u003d \u0027\u0027 OR upper \u003e ?)\", mock_call_args[0][1])"},{"line_number":4278,"context_line":"        self.assertEqual([\u0027a/c\u0027, \u0027d\u0027, \u0027c\u0027], mock_call_args[0][2])"},{"line_number":4279,"context_line":""},{"line_number":4280,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027i\u0027)"},{"line_number":4281,"context_line":"        self.assertFalse(actual)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5c63a627_bd613c28","line":4278,"updated":"2023-07-17 16:45:32.000000000","message":"the only behavior change that we might want to maintain explicitly is something like \"only create as many ShardRange/Namespace as we need\" - but do we want a CountingShardRange mock; meh.","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"4d891cda23e1c1a5549c9ef56a09c1386468ccf4","unresolved":false,"context_lines":[{"line_number":4275,"context_line":"        # verify that includes keyword plumbs through to an SQL condition"},{"line_number":4276,"context_line":"        self.assertIn(\"WHERE deleted\u003d0 AND name !\u003d ? AND lower \u003c ? AND \""},{"line_number":4277,"context_line":"                      \"(upper \u003d \u0027\u0027 OR upper \u003e ?)\", mock_call_args[0][1])"},{"line_number":4278,"context_line":"        self.assertEqual([\u0027a/c\u0027, \u0027d\u0027, \u0027c\u0027], mock_call_args[0][2])"},{"line_number":4279,"context_line":""},{"line_number":4280,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027i\u0027)"},{"line_number":4281,"context_line":"        self.assertFalse(actual)"}],"source_content_type":"text/x-python","patch_set":2,"id":"96d50972_1218244b","line":4278,"in_reply_to":"5c63a627_bd613c28","updated":"2023-07-19 14:01:13.000000000","message":"Ack","commit_id":"19bd1158555e59729fa755dc080782906b80c9a4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"5bd8aac6b2ee190d9b0a08cd52bf98b39fc473ef","unresolved":true,"context_lines":[{"line_number":4211,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027e\u0027, end_marker\u003d\u0027e\u0027)"},{"line_number":4212,"context_line":"        self.assertFalse([dict(sr) for sr in actual])"},{"line_number":4213,"context_line":""},{"line_number":4214,"context_line":"        # includes overrides marker/end_marker"},{"line_number":4215,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027b\u0027, marker\u003d\u0027e\u0027,"},{"line_number":4216,"context_line":"                                         end_marker\u003d\u0027\u0027)"},{"line_number":4217,"context_line":"        self.assertEqual([dict(shard_ranges[0])], [dict(sr) for sr in actual])"}],"source_content_type":"text/x-python","patch_set":3,"id":"4c382850_ae422e99","line":4214,"updated":"2023-07-20 05:36:45.000000000","message":"good tests! I don\u0027t see test cases (or existing) covering marker/end_marker with includes, include_own or fill_gaps? are those combined conditions will ever be used?","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c7bc82911f2c8e230a1fd8c7f595a44f1eba2bd5","unresolved":false,"context_lines":[{"line_number":4211,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027e\u0027, end_marker\u003d\u0027e\u0027)"},{"line_number":4212,"context_line":"        self.assertFalse([dict(sr) for sr in actual])"},{"line_number":4213,"context_line":""},{"line_number":4214,"context_line":"        # includes overrides marker/end_marker"},{"line_number":4215,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027b\u0027, marker\u003d\u0027e\u0027,"},{"line_number":4216,"context_line":"                                         end_marker\u003d\u0027\u0027)"},{"line_number":4217,"context_line":"        self.assertEqual([dict(shard_ranges[0])], [dict(sr) for sr in actual])"}],"source_content_type":"text/x-python","patch_set":3,"id":"ad991c80_bd50d0e0","line":4214,"in_reply_to":"116cdd4f_c06f573c","updated":"2023-07-20 21:03:50.000000000","message":"Thanks for those new added test cases. Looking at those different \"xxx overrides yyy\" scenarios, I feel we need document them all in the following doc string patch, will leave comments there.","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"87de52ee0a798bf2d8bdd05d5dd5f5c4f203578b","unresolved":false,"context_lines":[{"line_number":4211,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027e\u0027, end_marker\u003d\u0027e\u0027)"},{"line_number":4212,"context_line":"        self.assertFalse([dict(sr) for sr in actual])"},{"line_number":4213,"context_line":""},{"line_number":4214,"context_line":"        # includes overrides marker/end_marker"},{"line_number":4215,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027b\u0027, marker\u003d\u0027e\u0027,"},{"line_number":4216,"context_line":"                                         end_marker\u003d\u0027\u0027)"},{"line_number":4217,"context_line":"        self.assertEqual([dict(shard_ranges[0])], [dict(sr) for sr in actual])"}],"source_content_type":"text/x-python","patch_set":3,"id":"116cdd4f_c06f573c","line":4214,"in_reply_to":"4c382850_ae422e99","updated":"2023-07-20 13:05:14.000000000","message":"Done","commit_id":"05ee709d9611a52c760a3e3748484b30e98add7e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":true,"context_lines":[{"line_number":4177,"context_line":"        shard_ranges \u003d ["},{"line_number":4178,"context_line":"            ShardRange(\u0027.a/c0\u0027, next(self.ts), \u0027a\u0027, \u0027c\u0027),"},{"line_number":4179,"context_line":"            ShardRange(\u0027.a/c1\u0027, next(self.ts), \u0027c\u0027, \u0027d\u0027),"},{"line_number":4180,"context_line":"            ShardRange(\u0027.a/c2\u0027, next(self.ts), \u0027d\u0027, \u0027f\u0027,"},{"line_number":4181,"context_line":"                       state\u003dShardRange.ACTIVE),"},{"line_number":4182,"context_line":"            ShardRange(\u0027.a/c3\u0027, next(self.ts), \u0027e\u0027, \u0027f\u0027, deleted\u003d1,"},{"line_number":4183,"context_line":"                       state\u003dShardRange.SHARDED,),"}],"source_content_type":"text/x-python","patch_set":4,"id":"7bfc11bc_09540976","line":4180,"range":{"start_line":4180,"start_character":53,"end_line":4180,"end_character":54},"updated":"2023-08-02 23:03:39.000000000","message":"I forget whether it\u0027s intentional that this set includes an overlap.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":true,"context_lines":[{"line_number":4184,"context_line":"            ShardRange(\u0027.a/c4\u0027, next(self.ts), \u0027f\u0027, \u0027h\u0027,"},{"line_number":4185,"context_line":"                       state\u003dShardRange.CREATED),"},{"line_number":4186,"context_line":"            ShardRange(\u0027.a/c5\u0027, next(self.ts), \u0027h\u0027, \u0027j\u0027, deleted\u003d1)"},{"line_number":4187,"context_line":"        ]"},{"line_number":4188,"context_line":"        broker.merge_shard_ranges(shard_ranges)"},{"line_number":4189,"context_line":"        actual \u003d broker.get_shard_ranges()"},{"line_number":4190,"context_line":"        undeleted \u003d shard_ranges[:3] + shard_ranges[4:5]"}],"source_content_type":"text/x-python","patch_set":4,"id":"2e603f9f_f5ae78b4","line":4187,"updated":"2023-08-02 23:03:39.000000000","message":"😕 it\u0027s a little fishy that these don\u0027t cover the whole namespace...","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":false,"context_lines":[{"line_number":4200,"context_line":"                         [dict(sr) for sr in actual])"},{"line_number":4201,"context_line":""},{"line_number":4202,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027c\u0027, end_marker\u003d\u0027e\u0027)"},{"line_number":4203,"context_line":"        self.assertEqual([dict(sr) for sr in shard_ranges[1:3]],"},{"line_number":4204,"context_line":"                         [dict(sr) for sr in actual])"},{"line_number":4205,"context_line":""},{"line_number":4206,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027c\u0027, end_marker\u003d\u0027e\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"a2e1838c_604ba579","line":4203,"updated":"2023-08-02 23:03:39.000000000","message":"This\u0027d pop if we did `upper \u003e\u003d ?` like we do with `includes`.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":false,"context_lines":[{"line_number":4248,"context_line":""},{"line_number":4249,"context_line":"        # marker is Namespace.MIN"},{"line_number":4250,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027\u0027, end_marker\u003d\u0027d\u0027)"},{"line_number":4251,"context_line":"        self.assertEqual([dict(sr) for sr in shard_ranges[:2]],"},{"line_number":4252,"context_line":"                         [dict(sr) for sr in actual])"},{"line_number":4253,"context_line":""},{"line_number":4254,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003d\u0027\u0027, end_marker\u003d\u0027d\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"50bc6a90_33fb3103","line":4251,"updated":"2023-08-02 23:03:39.000000000","message":"This\u0027d pop if we accidentally did `lower \u003c\u003d ?` (which we don\u0027t do _anywhere_, but it\u0027s good to know something would pop).","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":false,"context_lines":[{"line_number":4279,"context_line":"        self.assertFalse(actual)"},{"line_number":4280,"context_line":""},{"line_number":4281,"context_line":"        actual \u003d broker.get_shard_ranges(marker\u003dNamespace.MAX)"},{"line_number":4282,"context_line":"        self.assertFalse(actual)"},{"line_number":4283,"context_line":""},{"line_number":4284,"context_line":"        orig_execute \u003d GreenDBConnection.execute"},{"line_number":4285,"context_line":"        mock_call_args \u003d []"}],"source_content_type":"text/x-python","patch_set":4,"id":"1f4a7087_0a7ea39a","line":4282,"updated":"2023-08-02 23:03:39.000000000","message":"And these two are the ones exercising the early return in `get_shard_ranges`.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"c8a18e4bab73caa89590c623942389c700da16ff","unresolved":false,"context_lines":[{"line_number":4308,"context_line":"        self.assertEqual(1, len(mock_call_args))"},{"line_number":4309,"context_line":"        # verify that marker \u0026 end_marker plumb through to an SQL condition"},{"line_number":4310,"context_line":"        self.assertIn(\"WHERE deleted\u003d0 AND name !\u003d ? AND lower \u003c ? AND \""},{"line_number":4311,"context_line":"                      \"(upper \u003d \u0027\u0027 OR upper \u003e ?)\", mock_call_args[0][1])"},{"line_number":4312,"context_line":"        self.assertEqual([\u0027a/c\u0027, \u0027d\u0027, \u0027c\u0027], mock_call_args[0][2])"},{"line_number":4313,"context_line":""},{"line_number":4314,"context_line":"        actual \u003d broker.get_shard_ranges(includes\u003d\u0027i\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"97e4167d_25fae66d","line":4311,"updated":"2023-08-02 23:03:39.000000000","message":"This is what pops if we forget the `upper \u003d \u0027\u0027 OR` -- feels a little on-the-nose, though.","commit_id":"f7d6d5806edafc79f9ee6ad1abaddfbd462787c6"}]}
