prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Search by topic broken ?
  Browsing packages, then choosing the Internet / WWW9HTTP / Browser topics gives no result:
  
  https://pypi.org/search/?q=&o=&c=Topic+%3A%3A+Internet+%3A%3A+WWW%2FHTTP+%3A%3A+Browsers
  
  There should be at least the [mechanoid package](https://pypi.org/project/mechanoid/)
  
  Using firefox 50.1:0 on Ubuntu 16.04
  
  </issue>
  <code>
  [start of warehouse/cli/search/reindex.py]
  1 # Licensed under the Apache License, Version 2.0 (the "License");
  2 # you may not use this file except in compliance with the License.
  3 # You may obtain a copy of the License at
  4 #
  5 # http://www.apache.org/licenses/LICENSE-2.0
  6 #
  7 # Unless required by applicable law or agreed to in writing, software
  8 # distributed under the License is distributed on an "AS IS" BASIS,
  9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10 # See the License for the specific language governing permissions and
  11 # limitations under the License.
  12 
  13 import binascii
  14 import os
  15 
  16 import click
  17 
  18 from elasticsearch.helpers import parallel_bulk
  19 from sqlalchemy.orm import lazyload, joinedload, load_only
  20 
  21 from warehouse.cli.search import search
  22 from warehouse.db import Session
  23 from warehouse.packaging.models import Release, Project
  24 from warehouse.packaging.search import Project as ProjectDocType
  25 from warehouse.search import get_index
  26 from warehouse.utils.db import windowed_query
  27 
  28 
  29 def _project_docs(db):
  30     releases = (
  31         db.query(Release)
  32           .options(load_only(
  33                    "summary", "description", "author",
  34                    "author_email", "maintainer", "maintainer_email",
  35                    "home_page", "download_url", "keywords", "platform",
  36                    "created"))
  37           .options(lazyload("*"),
  38                    (joinedload(Release.project)
  39                     .load_only("normalized_name", "name")
  40                     .joinedload(Project.releases)
  41                     .load_only("version", "is_prerelease")),
  42                    joinedload(Release._classifiers).load_only("classifier"))
  43           .distinct(Release.name)
  44           .order_by(Release.name, Release._pypi_ordering.desc())
  45     )
  46     for release in windowed_query(releases, Release.name, 1000):
  47         p = ProjectDocType.from_db(release)
  48         p.full_clean()
  49         yield p.to_dict(include_meta=True)
  50 
  51 
  52 @search.command()
  53 @click.pass_obj
  54 def reindex(config, **kwargs):
  55     """
  56     Recreate the Search Index.
  57     """
  58     client = config.registry["elasticsearch.client"]
  59     db = Session(bind=config.registry["sqlalchemy.engine"])
  60     number_of_replicas = config.registry.get("elasticsearch.replicas", 0)
  61     refresh_interval = config.registry.get("elasticsearch.interval", "1s")
  62 
  63     # We use a randomly named index so that we can do a zero downtime reindex.
  64     # Essentially we'll use a randomly named index which we will use until all
  65     # of the data has been reindexed, at which point we'll point an alias at
  66     # our randomly named index, and then delete the old randomly named index.
  67 
  68     # Create the new index and associate all of our doc types with it.
  69     index_base = config.registry["elasticsearch.index"]
  70     random_token = binascii.hexlify(os.urandom(5)).decode("ascii")
  71     new_index_name = "{}-{}".format(index_base, random_token)
  72     doc_types = config.registry.get("search.doc_types", set())
  73 
  74     # Create the new index with zero replicas and index refreshes disabled
  75     # while we are bulk indexing.
  76     new_index = get_index(
  77         new_index_name,
  78         doc_types,
  79         using=client,
  80         shards=config.registry.get("elasticsearch.shards", 1),
  81         replicas=0,
  82         interval="-1",
  83     )
  84 
  85     # From this point on, if any error occurs, we want to be able to delete our
  86     # in progress index.
  87     try:
  88         db.execute("SET statement_timeout = '600s'")
  89 
  90         for _ in parallel_bulk(client, _project_docs(db)):
  91             pass
  92     except:
  93         new_index.delete()
  94         raise
  95     finally:
  96         db.rollback()
  97         db.close()
  98 
  99     # Now that we've finished indexing all of our data we can optimize it and
  100     # update the replicas and refresh intervals.
  101     client.indices.forcemerge(index=new_index_name)
  102     client.indices.put_settings(
  103         index=new_index_name,
  104         body={
  105             "index": {
  106                 "number_of_replicas": number_of_replicas,
  107                 "refresh_interval": refresh_interval,
  108             }
  109         }
  110     )
  111 
  112     # Point the alias at our new randomly named index and delete the old index.
  113     if client.indices.exists_alias(name=index_base):
  114         to_delete = set()
  115         actions = []
  116         for name in client.indices.get_alias(name=index_base):
  117             to_delete.add(name)
  118             actions.append({"remove": {"index": name, "alias": index_base}})
  119         actions.append({"add": {"index": new_index_name, "alias": index_base}})
  120         client.indices.update_aliases({"actions": actions})
  121         client.indices.delete(",".join(to_delete))
  122     else:
  123         client.indices.put_alias(name=index_base, index=new_index_name)
  124
  [end of warehouse/cli/search/reindex.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/warehouse/cli/search/reindex.py b/warehouse/cli/search/reindex.py
  --- a/warehouse/cli/search/reindex.py
  +++ b/warehouse/cli/search/reindex.py
  @@ -70,6 +70,7 @@
       random_token = binascii.hexlify(os.urandom(5)).decode("ascii")
       new_index_name = "{}-{}".format(index_base, random_token)
       doc_types = config.registry.get("search.doc_types", set())
  +    shards = config.registry.get("elasticsearch.shards", 1)
   
       # Create the new index with zero replicas and index refreshes disabled
       # while we are bulk indexing.
  @@ -77,10 +78,11 @@
           new_index_name,
           doc_types,
           using=client,
  -        shards=config.registry.get("elasticsearch.shards", 1),
  +        shards=shards,
           replicas=0,
           interval="-1",
       )
  +    new_index.create(wait_for_active_shards=shards)
   
       # From this point on, if any error occurs, we want to be able to delete our
       # in progress index.
  
verification_info: {"golden_diff": "diff --git a/warehouse/cli/search/reindex.py b/warehouse/cli/search/reindex.py\n--- a/warehouse/cli/search/reindex.py\n+++ b/warehouse/cli/search/reindex.py\n@@ -70,6 +70,7 @@\n     random_token = binascii.hexlify(os.urandom(5)).decode(\"ascii\")\n     new_index_name = \"{}-{}\".format(index_base, random_token)\n     doc_types = config.registry.get(\"search.doc_types\", set())\n+    shards = config.registry.get(\"elasticsearch.shards\", 1)\n \n     # Create the new index with zero replicas and index refreshes disabled\n     # while we are bulk indexing.\n@@ -77,10 +78,11 @@\n         new_index_name,\n         doc_types,\n         using=client,\n-        shards=config.registry.get(\"elasticsearch.shards\", 1),\n+        shards=shards,\n         replicas=0,\n         interval=\"-1\",\n     )\n+    new_index.create(wait_for_active_shards=shards)\n \n     # From this point on, if any error occurs, we want to be able to delete our\n     # in progress index.\n", "issue": "Search by topic broken ?\nBrowsing packages, then choosing the Internet / WWW9HTTP / Browser topics gives no result:\r\n\r\nhttps://pypi.org/search/?q=&o=&c=Topic+%3A%3A+Internet+%3A%3A+WWW%2FHTTP+%3A%3A+Browsers\r\n\r\nThere should be at least the [mechanoid package](https://pypi.org/project/mechanoid/)\r\n\r\nUsing firefox 50.1:0 on Ubuntu 16.04\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport binascii\nimport os\n\nimport click\n\nfrom elasticsearch.helpers import parallel_bulk\nfrom sqlalchemy.orm import lazyload, joinedload, load_only\n\nfrom warehouse.cli.search import search\nfrom warehouse.db import Session\nfrom warehouse.packaging.models import Release, Project\nfrom warehouse.packaging.search import Project as ProjectDocType\nfrom warehouse.search import get_index\nfrom warehouse.utils.db import windowed_query\n\n\ndef _project_docs(db):\n    releases = (\n        db.query(Release)\n          .options(load_only(\n                   \"summary\", \"description\", \"author\",\n                   \"author_email\", \"maintainer\", \"maintainer_email\",\n                   \"home_page\", \"download_url\", \"keywords\", \"platform\",\n                   \"created\"))\n          .options(lazyload(\"*\"),\n                   (joinedload(Release.project)\n                    .load_only(\"normalized_name\", \"name\")\n                    .joinedload(Project.releases)\n                    .load_only(\"version\", \"is_prerelease\")),\n                   joinedload(Release._classifiers).load_only(\"classifier\"))\n          .distinct(Release.name)\n          .order_by(Release.name, Release._pypi_ordering.desc())\n    )\n    for release in windowed_query(releases, Release.name, 1000):\n        p = ProjectDocType.from_db(release)\n        p.full_clean()\n        yield p.to_dict(include_meta=True)\n\n\n@search.command()\n@click.pass_obj\ndef reindex(config, **kwargs):\n    \"\"\"\n    Recreate the Search Index.\n    \"\"\"\n    client = config.registry[\"elasticsearch.client\"]\n    db = Session(bind=config.registry[\"sqlalchemy.engine\"])\n    number_of_replicas = config.registry.get(\"elasticsearch.replicas\", 0)\n    refresh_interval = config.registry.get(\"elasticsearch.interval\", \"1s\")\n\n    # We use a randomly named index so that we can do a zero downtime reindex.\n    # Essentially we'll use a randomly named index which we will use until all\n    # of the data has been reindexed, at which point we'll point an alias at\n    # our randomly named index, and then delete the old randomly named index.\n\n    # Create the new index and associate all of our doc types with it.\n    index_base = config.registry[\"elasticsearch.index\"]\n    random_token = binascii.hexlify(os.urandom(5)).decode(\"ascii\")\n    new_index_name = \"{}-{}\".format(index_base, random_token)\n    doc_types = config.registry.get(\"search.doc_types\", set())\n\n    # Create the new index with zero replicas and index refreshes disabled\n    # while we are bulk indexing.\n    new_index = get_index(\n        new_index_name,\n        doc_types,\n        using=client,\n        shards=config.registry.get(\"elasticsearch.shards\", 1),\n        replicas=0,\n        interval=\"-1\",\n    )\n\n    # From this point on, if any error occurs, we want to be able to delete our\n    # in progress index.\n    try:\n        db.execute(\"SET statement_timeout = '600s'\")\n\n        for _ in parallel_bulk(client, _project_docs(db)):\n            pass\n    except:\n        new_index.delete()\n        raise\n    finally:\n        db.rollback()\n        db.close()\n\n    # Now that we've finished indexing all of our data we can optimize it and\n    # update the replicas and refresh intervals.\n    client.indices.forcemerge(index=new_index_name)\n    client.indices.put_settings(\n        index=new_index_name,\n        body={\n            \"index\": {\n                \"number_of_replicas\": number_of_replicas,\n                \"refresh_interval\": refresh_interval,\n            }\n        }\n    )\n\n    # Point the alias at our new randomly named index and delete the old index.\n    if client.indices.exists_alias(name=index_base):\n        to_delete = set()\n        actions = []\n        for name in client.indices.get_alias(name=index_base):\n            to_delete.add(name)\n            actions.append({\"remove\": {\"index\": name, \"alias\": index_base}})\n        actions.append({\"add\": {\"index\": new_index_name, \"alias\": index_base}})\n        client.indices.update_aliases({\"actions\": actions})\n        client.indices.delete(\",\".join(to_delete))\n    else:\n        client.indices.put_alias(name=index_base, index=new_index_name)\n", "path": "warehouse/cli/search/reindex.py"}]}