10000 Fix a low-probability crash in our qsort implementation. · postgres/postgres@9d6077a · GitHub
[go: up one dir, main page]

Skip to content
{"payload":{"commit":{"oid":"9d6077abf9d6efd992a59f05ef5aba981ea32096","url":"/postgres/postgres/commit/9d6077abf9d6efd992a59f05ef5aba981ea32096","authoredDate":"2015-07-16T22:57:46.000-04:00","committedDate":"2015-07-16T22:57:46.000-04:00","shortMessage":null,"shortMessageMarkdown":"\u003cdiv\u003eFix a low-probability crash in our qsort implementation.\u003c/div\u003e","shortMessageMarkdownLink":null,"bodyMessageHtml":"It's standard for quicksort implementations, after having partitioned the\ninput into two subgroups, to recurse to process the smaller partition and\nthen handle the larger partition by iterating. This method guarantees\nthat no more than log2(N) levels of recursion can be needed. However,\nBentley and McIlroy argued that checking to see which partition is smaller\nisn't worth the cycles, and so their code doesn't do that but just always\nrecurses on the left partition. In most cases that's fine; but with\nworst-case input we might need O(N) levels of recursion, and that means\nthat qsort could be driven to stack overflow. Such an overflow seems to\nbe the only explanation for today's report from Yiqing Jin of a SIGSEGV\nin med3_tuple while creating an index of a couple billion entries with a\nvery large maintenance_work_mem setting. Therefore, let's spend the few\nadditional cycles and lines of code needed to choose the smaller partition\nfor recursion.\n\nAlso, fix up the qsort code so that it properly uses size_t not int for\nsome intermediate values representing numbers of items. This would only\nbe a live risk when sorting more than INT_MAX bytes (in qsort/qsort_arg)\nor tuples (in qsort_tuple), which I believe would never happen with any\ncaller in the current core code --- but perhaps it could happen with\ncall sites in third-party modules? In any case, this is trouble waiting\nto happen, and the corrected code is probably if anything shorter and\nfaster than before, since it removes sign-extension steps that had to\nhappen when converting between int and size_t.\n\nIn passing, move a couple of CHECK_FOR_INTERRUPTS() calls so that it's\nnot necessary to preserve the value of \"r\" across them, and prettify\nthe output of gen_qsort_tuple.pl a little.\n\nBack-patch to all supported branches. The odds of hitting this issue\nare probably higher in 9.4 and up than before, due to the new ability\nto allocate sort workspaces exceeding 1GB, but there's no good reason\nto believe that it's impossible to crash older branches this way.","authors":[{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false}],"committerAttribution":false,"committer":{"login":"tglsfdc","displayName":"Tom Lane","avatarUrl":"https://avatars.githubusercontent.com/u/8755309?v=4","path":"/tglsfdc","isGitHub":false},"parents":["828df727a673d718265766611e59aa5189d102ba"],"globalRelayId":"MDY6Q29tbWl0OTI3NDQyOjlkNjA3N2FiZjlkNmVmZDk5MmE1OWYwNWVmNWFiYTk4MWVhMzIwOTY=","sha1":"828df727a673d718265766611e59aa5189d102ba","sha2":"9d6077abf9d6efd992a59f05ef5aba981ea32096"},"currentUser":null,"repo":{"id":927442,"defaultBranch":"master","name":"postgres","ownerLogin":"postgres","currentUserCanPush":false,"isFork":false,"isEmpty":false,"createdAt":"2010-09-21T11:35:45.000Z","ownerAvatar":"https://avatars.githubusercontent.com/u/177543?v=4","public":true,"private":false,"isOrgOwned":true},"diffEntryData":[{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":13,"text":"@@ -14,11 +14,13 @@","html":"@@ -14,11 +14,13 @@","displayNoNewLineWarning":false,"position":0,"left":13,"right":13},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":14,"text":" #","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":14,"right":14},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":15,"text":" #\tModifications from vanilla NetBSD source:","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\tModifications from vanilla NetBSD source:\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":15,"right":15},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":16,"text":" #\t Add do ... while() macro fix","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\t Add do ... while() macro fix\u003c/span\u003e","displayNoNewLineWarning":false,"position":3,"left":16,"right":16},{"stylingDirective":null,"type":"DELETION","blobLineNumber":17,"text":"-# \t Remove __inline, _DIAGASSERTs, __P","html":"-\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \t Remove __inline, _DIAGASSERTs, __P\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":17,"right":16},{"stylingDirective":null,"type":"DELETION","blobLineNumber":18,"text":"-# \t Remove ill-considered \"swap_cnt\" switch to insertion sort,","html":"-\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \t Remove ill-considered \u0026quot;swap_cnt\u0026quot; switch to insertion sort,\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":18,"right":16},{"stylingDirective":null,"type":"DELETION","blobLineNumber":19,"text":"-# \t in favor of a simple check for presorted input.","html":"-\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e \t in favor of a simple check for presorted input.\u003c/span\u003e","displayNoNewLineWarning":false,"position":6,"left":19,"right":16},{"stylingDirective":null,"type":"DELETION","blobLineNumber":20,"text":"-# Instead of sorting arbitrary objects, we're always sorting SortTuples","html":"-\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Instead of sorting arbitrary objects, we\u0026#39;re always sorting SortTuples\u003c/span\u003e","displayNoNewLineWarning":false,"position":7,"left":20,"right":16},{"stylingDirective":null,"type":"DELETION","blobLineNumber":21,"text":"-# Add CHECK_FOR_INTERRUPTS()","html":"-\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Add CHECK_FOR_INTERRUPTS()\u003c/span\u003e","displayNoNewLineWarning":false,"position":8,"left":21,"right":16},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":17,"text":"+#\t Remove __inline, _DIAGASSERTs, __P","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\t Remove __inline, _DIAGASSERTs, __P\u003c/span\u003e","displayNoNewLineWarning":false,"position":9,"left":21,"right":17},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":18,"text":"+#\t Remove ill-considered \"swap_cnt\" switch to insertion sort,","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\t Remove ill-considered \u0026quot;swap_cnt\u0026quot; switch to insertion sort,\u003c/span\u003e","displayNoNewLineWarning":false,"position":10,"left":21,"right":18},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":19,"text":"+#\t in favor of a simple check for presorted input.","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\t in favor of a simple check for presorted input.\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":21,"right":19},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":20,"text":"+#\t Take care to recurse on the smaller partition, to bound stack usage.","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\t Take care to recurse on the smaller partition, to bound stack usage.\u003c/span\u003e","displayNoNewLineWarning":false,"position":12,"left":21,"right":20},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":21,"text":"+#","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":21,"right":21},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":22,"text":"+# Instead of sorting arbitrary objects, we're always sorting SortTuples.","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Instead of sorting arbitrary objects, we\u0026#39;re always sorting SortTuples.\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":21,"right":22},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":23,"text":"+# Add CHECK_FOR_INTERRUPTS().","html":"+\u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e Add CHECK_FOR_INTERRUPTS().\u003c/span\u003e","displayNoNewLineWarning":false,"position":15,"left":21,"right":23},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":24,"text":" #","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":22,"right":24},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":25,"text":" # CAUTION: if you change this file, see also qsort.c and qsort_arg.c","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e CAUTION: if you change this file, see also qsort.c and qsort_arg.c\u003c/span\u003e","displayNoNewLineWarning":false,"position":17,"left":23,"right":25},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":26,"text":" #","html":" \u003cspan class=\"pl-c\"\u003e\u003cspan class=\"pl-c\"\u003e#\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":18,"left":24,"right":26},{"stylingDirective":null,"type":"HUNK","blobLineNumber":44,"text":"@@ -43,17 +45,20 @@","html":"@@ -43,17 +45,20 @@","displayNoNewLineWarning":false,"position":19,"left":42,"right":44},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":45,"text":" $EXTRAPARAMS = ', ssup';","html":" \u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e = \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e, ssup\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":20,"left":43,"right":45},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":46,"text":" $CMPPARAMS = ', ssup';","html":" \u003cspan class=\"pl-smi\"\u003e$CMPPARAMS\u003c/span\u003e = \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e, ssup\u003cspan class=\"pl-pds\"\u003e\u0026#39;\u003c/span\u003e\u003c/span\u003e;","displayNoNewLineWarning":false,"position":21,"left":44,"right":46},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":47,"text":" print \u003c\u003c'EOM';","html":" \u003cspan class=\"pl-c1\"\u003eprint\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026lt;\u0026lt;\u0026#39;EOM\u0026#39;\u003c/span\u003e\u003c/span\u003e;\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":22,"left":45,"right":47},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":48,"text":"+","html":"+\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":23,"left":45,"right":48},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":49,"text":" #define cmp_ssup(a, b, ssup) \\","html":" \u003cspan class=\"pl-s\"\u003e#define cmp_ssup(a, b, ssup) \\\u003c/span\u003e","displayNoNewLineWarning":false,"position":24,"left":46,"right":49},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":50,"text":" \tApplySortComparator((a)-\u003edatum1, (a)-\u003eisnull1, \\","html":" \u003cspan class=\"pl-s\"\u003e\tApplySortComparator((a)-\u0026gt;datum1, (a)-\u0026gt;isnull1, \\\u003c/span\u003e","displayNoNewLineWarning":false,"position":25,"left":47,"right":50},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":51,"text":" \t\t\t\t\t\t(b)-\u003edatum1, (b)-\u003eisnull1, ssup)","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\t\t\t(b)-\u0026gt;datum1, (b)-\u0026gt;isnull1, ssup)\u003c/span\u003e","displayNoNewLineWarning":false,"position":26,"left":48,"right":51},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":52,"text":"+","html":"+\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":27,"left":48,"right":52},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":53,"text":" EOM","html":" \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003eEOM\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":28,"left":49,"right":53},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":54,"text":" emit_qsort_implementation();","html":" emit_qsort_implementation();","displayNoNewLineWarning":false,"position":29,"left":50,"right":54},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":55,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":30,"left":51,"right":55},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":56,"text":" sub emit_qsort_boilerplate","html":" \u003cspan class=\"pl-k\"\u003esub\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eemit_qsort_boilerplate\u003c/span\u003e","displayNoNewLineWarning":false,"position":31,"left":52,"right":56},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":57,"text":" {","html":" {","displayNoNewLineWarning":false,"position":32,"left":53,"right":57},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":58,"text":" \tprint \u003c\u003c'EOM';","html":" \t\u003cspan class=\"pl-c1\"\u003eprint\u003c/span\u003e \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003e\u0026lt;\u0026lt;\u0026#39;EOM\u0026#39;\u003c/span\u003e\u003c/span\u003e;\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":33,"left":54,"right":58},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":59,"text":" /*","html":" \u003cspan class=\"pl-s\"\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":34,"left":55,"right":59},{"stylingDirective":null,"type":"DELETION","blobLineNumber":56,"text":"- * autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit","html":"-\u003cspan class=\"pl-s\"\u003e * autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit\u003c/span\u003e","displayNoNewLineWarning":false,"position":35,"left":56,"right":59},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":60,"text":"+ * autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit!","html":"+\u003cspan class=\"pl-s\"\u003e * autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit!\u003c/span\u003e","displayNoNewLineWarning":false,"position":36,"left":56,"right":60},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":61,"text":"+ *","html":"+\u003cspan class=\"pl-s\"\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":37,"left":56,"right":61},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":62,"text":" * This file is included by tuplesort.c, rather than compiled separately.","html":" \u003cspan class=\"pl-s\"\u003e * This file is included by tuplesort.c, rather than compiled separately.\u003c/span\u003e","displayNoNewLineWarning":false,"position":38,"left":57,"right":62},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":63,"text":" */","html":" \u003cspan class=\"pl-s\"\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":39,"left":58,"right":63},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":64,"text":" ","html":" \u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":40,"left":59,"right":64},{"stylingDirective":null,"type":"HUNK","blobLineNumber":82,"text":"@@ -78,7 +83,7 @@ sub emit_qsort_boilerplate","html":"@@ -78,7 +83,7 @@ sub emit_qsort_boilerplate","displayNoNewLineWarning":false,"position":41,"left":77,"right":82},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":83,"text":" * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND","html":" \u003cspan class=\"pl-s\"\u003e * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS\u0026#39;\u0026#39; AND\u003c/span\u003e","displayNoNewLineWarning":false,"position":42,"left":78,"right":83},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":84,"text":" * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE","html":" \u003cspan class=\"pl-s\"\u003e * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\u003c/span\u003e","displayNoNewLineWarning":false,"position":43,"left":79,"right":84},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":85,"text":" * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE","html":" \u003cspan class=\"pl-s\"\u003e * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\u003c/span\u003e","displayNoNewLineWarning":false,"position":44,"left":80,"right":85},{"stylingDirective":null,"type":"DELETION","blobLineNumber":81,"text":"- * ARE DISCLAIMED.\tIN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE","html":"-\u003cspan class=\"pl-s\"\u003e * ARE DISCLAIMED.\u003cspan class=\"x x-first x-last\"\u003e\t\u003c/span\u003eIN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\u003c/span\u003e","displayNoNewLineWarning":false,"position":45,"left":81,"right":85},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":86,"text":"+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE","html":"+\u003cspan class=\"pl-s\"\u003e * ARE DISCLAIMED.\u003cspan class=\"x x-first x-last\"\u003e \u003c/span\u003eIN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\u003c/span\u003e","displayNoNewLineWarning":false,"position":46,"left":81,"right":86},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":87,"text":" * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL","html":" \u003cspan class=\"pl-s\"\u003e * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\u003c/span\u003e","displayNoNewLineWarning":false,"position":47,"left":82,"right":87},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":88,"text":" * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS","html":" \u003cspan class=\"pl-s\"\u003e * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\u003c/span\u003e","displayNoNewLineWarning":false,"position":48,"left":83,"right":88},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":89,"text":" * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)","html":" \u003cspan class=\"pl-s\"\u003e * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\u003c/span\u003e","displayNoNewLineWarning":false,"position":49,"left":84,"right":89},{"stylingDirective":null,"type":"HUNK","blobLineNumber":96,"text":"@@ -92,8 +97,16 @@ sub emit_qsort_boilerplate","html":"@@ -92,8 +97,16 @@ sub emit_qsort_boilerplate","displayNoNewLineWarning":false,"position":50,"left":91,"right":96},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":97,"text":" * Qsort routine based on J. L. Bentley and M. D. McIlroy,","html":" \u003cspan class=\"pl-s\"\u003e * Qsort routine based on J. L. Bentley and M. D. McIlroy,\u003c/span\u003e","displayNoNewLineWarning":false,"position":51,"left":92,"right":97},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":98,"text":" * \"Engineering a sort function\",","html":" \u003cspan class=\"pl-s\"\u003e * \u0026quot;Engineering a sort function\u0026quot;,\u003c/span\u003e","displayNoNewLineWarning":false,"position":52,"left":93,"right":98},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":99,"text":" * Software--Practice and Experience 23 (1993) 1249-1265.","html":" \u003cspan class=\"pl-s\"\u003e * Software--Practice and Experience 23 (1993) 1249-1265.\u003c/span\u003e","displayNoNewLineWarning":false,"position":53,"left":94,"right":99},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":100,"text":"+ *","html":"+\u003cspan class=\"pl-s\"\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":54,"left":94,"right":100},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":101,"text":" * We have modified their original by adding a check for already-sorted input,","html":" \u003cspan class=\"pl-s\"\u003e * We have modified their original by adding a check for already-sorted input,\u003c/span\u003e","displayNoNewLineWarning":false,"position":55,"left":95,"right":101},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":102,"text":" * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.","html":" \u003cspan class=\"pl-s\"\u003e * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.\u003c/span\u003e","displayNoNewLineWarning":false,"position":56,"left":96,"right":102},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":103,"text":"+ *","html":"+\u003cspan class=\"pl-s\"\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":57,"left":96,"right":103},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":104,"text":"+ * Also, we recurse on the smaller partition and iterate on the larger one,","html":"+\u003cspan class=\"pl-s\"\u003e * Also, we recurse on the smaller partition and iterate on the larger one,\u003c/span\u003e","displayNoNewLineWarning":false,"position":58,"left":96,"right":104},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":105,"text":"+ * which ensures we cannot recurse more than log(N) levels (since the","html":"+\u003cspan class=\"pl-s\"\u003e * which ensures we cannot recurse more than log(N) levels (since the\u003c/span\u003e","displayNoNewLineWarning":false,"position":59,"left":96,"right":105},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":106,"text":"+ * partition recursed to is surely no more than half of the input). Bentley","html":"+\u003cspan class=\"pl-s\"\u003e * partition recursed to is surely no more than half of the input). Bentley\u003c/span\u003e","displayNoNewLineWarning":false,"position":60,"left":96,"right":106},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":107,"text":"+ * and McIlroy explicitly rejected doing this on the grounds that it's \"not","html":"+\u003cspan class=\"pl-s\"\u003e * and McIlroy explicitly rejected doing this on the grounds that it\u0026#39;s \u0026quot;not\u003c/span\u003e","displayNoNewLineWarning":false,"position":61,"left":96,"right":107},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":108,"text":"+ * worth the effort\", but we have seen crashes in the field due to stack","html":"+\u003cspan class=\"pl-s\"\u003e * worth the effort\u0026quot;, but we have seen crashes in the field due to stack\u003c/span\u003e","displayNoNewLineWarning":false,"position":62,"left":96,"right":108},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":109,"text":"+ * overrun, so that judgment seems wrong.","html":"+\u003cspan class=\"pl-s\"\u003e * overrun, so that judgment seems wrong.\u003c/span\u003e","displayNoNewLineWarning":false,"position":63,"left":96,"right":109},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":110,"text":" */","html":" \u003cspan class=\"pl-s\"\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":64,"left":97,"right":110},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":111,"text":" ","html":" \u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":65,"left":98,"right":111},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":112,"text":" static void","html":" \u003cspan class=\"pl-s\"\u003estatic void\u003c/span\u003e","displayNoNewLineWarning":false,"position":66,"left":99,"right":112},{"stylingDirective":null,"type":"HUNK","blobLineNumber":126,"text":"@@ -114,7 +127,8 @@ sub emit_qsort_boilerplate","html":"@@ -114,7 +127,8 @@ sub emit_qsort_boilerplate","displayNoNewLineWarning":false,"position":67,"left":113,"right":126},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":127,"text":" \t\t*(b) = t;\t\t\t\t\t\t\\","html":" \u003cspan class=\"pl-s\"\u003e\t\t*(b) = t;\t\t\t\t\t\t\\\u003c/span\u003e","displayNoNewLineWarning":false,"position":68,"left":114,"right":127},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":128,"text":" \t} while (0);","html":" \u003cspan class=\"pl-s\"\u003e\t} while (0);\u003c/span\u003e","displayNoNewLineWarning":false,"position":69,"left":115,"right":128},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":129,"text":" ","html":" \u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":70,"left":116,"right":129},{"stylingDirective":null,"type":"DELETION","blobLineNumber":117,"text":"-#define vecswap(a, b, n) if ((n) \u003e 0) swapfunc((a), (b), (size_t)(n))","html":"-\u003cspan class=\"pl-s\"\u003e#define vecswap(a, b, n) if ((n) \u0026gt; 0) swapfunc((a), (b), (size_t)(n))\u003c/span\u003e","displayNoNewLineWarning":false,"position":71,"left":117,"right":129},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":130,"text":"+#define vecswap(a, b, n) if ((n) \u003e 0) swapfunc(a, b, n)","html":"+\u003cspan class=\"pl-s\"\u003e#define vecswap(a, b, n) if ((n) \u0026gt; 0) swapfunc(a, b, n)\u003c/span\u003e","displayNoNewLineWarning":false,"position":72,"left":117,"right":130},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":131,"text":"+","html":"+\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":73,"left":117,"right":131},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":132,"text":" EOM","html":" \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003eEOM\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":74,"left":118,"right":132},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":133,"text":" }","html":" }","displayNoNewLineWarning":false,"position":75,"left":119,"right":133},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":134,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":76,"left":120,"right":134},{"stylingDirective":null,"type":"HUNK","blobLineNumber":154,"text":"@@ -141,8 +155,9 @@ sub emit_qsort_implementation","html":"@@ -141,8 +155,9 @@ sub emit_qsort_implementation","displayNoNewLineWarning":false,"position":77,"left":140,"right":154},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":155,"text":" \t\t\t *pl,","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t *pl,\u003c/span\u003e","displayNoNewLineWarning":false,"position":78,"left":141,"right":155},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":156,"text":" \t\t\t *pm,","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t *pm,\u003c/span\u003e","displayNoNewLineWarning":false,"position":79,"left":142,"right":156},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":157,"text":" \t\t\t *pn;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t *pn;\u003c/span\u003e","displayNoNewLineWarning":false,"position":80,"left":143,"right":157},{"stylingDirective":null,"type":"DELETION","blobLineNumber":144,"text":"-\tint\t\t\td,","html":"-\u003cspan class=\"pl-s\"\u003e\tint\t\t\td,\u003c/span\u003e","displayNoNewLineWarning":false,"position":81,"left":144,"right":157},{"stylingDirective":null,"type":"DELETION","blobLineNumber":145,"text":"-\t\t\t\tr,","html":"-\u003cspan class=\"pl-s\"\u003e\t\t\t\tr,\u003c/span\u003e","displayNoNewLineWarning":false,"position":82,"left":145,"right":157},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":158,"text":"+\tsize_t\t\td1,","html":"+\u003cspan class=\"pl-s\"\u003e\tsize_t\t\td1,\u003c/span\u003e","displayNoNewLineWarning":false,"position":83,"left":145,"right":158},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":159,"text":"+\t\t\t\td2;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\t\td2;\u003c/span\u003e","displayNoNewLineWarning":false,"position":84,"left":145,"right":159},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":160,"text":"+\tint\t\t\tr,","html":"+\u003cspan class=\"pl-s\"\u003e\tint\t\t\tr,\u003c/span\u003e","displayNoNewLineWarning":false,"position":85,"left":145,"right":160},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":161,"text":" \t\t\t\tpresorted;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\tpresorted;\u003c/span\u003e","displayNoNewLineWarning":false,"position":86,"left":146,"right":161},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":162,"text":" ","html":" \u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":87,"left":147,"right":162},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":163,"text":" loop:","html":" \u003cspan class=\"pl-s\"\u003eloop:\u003c/span\u003e","displayNoNewLineWarning":false,"position":88,"left":148,"right":163},{"stylingDirective":null,"type":"HUNK","blobLineNumber":187,"text":"@@ -173,7 +188,8 @@ sub emit_qsort_implementation","html":"@@ -173,7 +188,8 @@ sub emit_qsort_implementation","displayNoNewLineWarning":false,"position":89,"left":172,"right":187},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":188,"text":" \t\tpn = a + (n - 1);","html":" \u003cspan class=\"pl-s\"\u003e\t\tpn = a + (n - 1);\u003c/span\u003e","displayNoNewLineWarning":false,"position":90,"left":173,"right":188},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":189,"text":" \t\tif (n \u003e 40)","html":" \u003cspan class=\"pl-s\"\u003e\t\tif (n \u0026gt; 40)\u003c/span\u003e","displayNoNewLineWarning":false,"position":91,"left":174,"right":189},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":190,"text":" \t\t{","html":" \u003cspan class=\"pl-s\"\u003e\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":92,"left":175,"right":190},{"stylingDirective":null,"type":"DELETION","blobLineNumber":176,"text":"-\t\t\td = (n / 8);","html":"-\u003cspan class=\"pl-s\"\u003e\t\t\td = (n / 8);\u003c/span\u003e","displayNoNewLineWarning":false,"position":93,"left":176,"right":190},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":191,"text":"+\t\t\tsize_t\t\td = (n / 8);","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tsize_t\t\td = (n / 8);\u003c/span\u003e","displayNoNewLineWarning":false,"position":94,"left":176,"right":191},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":192,"text":"+","html":"+\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":95,"left":176,"right":192},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":193,"text":" \t\t\tpl = med3_$SUFFIX(pl, pl + d, pl + 2 * d$EXTRAPARAMS);","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tpl = med3_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pl, pl + d, pl + 2 * d\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":96,"left":177,"right":193},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":194,"text":" \t\t\tpm = med3_$SUFFIX(pm - d, pm, pm + d$EXTRAPARAMS);","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tpm = med3_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pm - d, pm, pm + d\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":97,"left":178,"right":194},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":195,"text":" \t\t\tpn = med3_$SUFFIX(pn - 2 * d, pn - d, pn$EXTRAPARAMS);","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tpn = med3_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pn - 2 * d, pn - d, pn\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":98,"left":179,"right":195},{"stylingDirective":null,"type":"HUNK","blobLineNumber":202,"text":"@@ -187,23 +203,23 @@ sub emit_qsort_implementation","html":"@@ -187,23 +203,23 @@ sub emit_qsort_implementation","displayNoNewLineWarning":false,"position":99,"left":186,"right":202},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":203,"text":" \t{","html":" \u003cspan class=\"pl-s\"\u003e\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":100,"left":187,"right":203},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":204,"text":" \t\twhile (pb \u003c= pc \u0026\u0026 (r = cmp_$SUFFIX(pb, a$CMPPARAMS)) \u003c= 0)","html":" \u003cspan class=\"pl-s\"\u003e\t\twhile (pb \u0026lt;= pc \u0026amp;\u0026amp; (r = cmp_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pb, a\u003cspan class=\"pl-smi\"\u003e$CMPPARAMS\u003c/span\u003e)) \u0026lt;= 0)\u003c/span\u003e","displayNoNewLineWarning":false,"position":101,"left":188,"right":204},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":205,"text":" \t\t{","html":" \u003cspan class=\"pl-s\"\u003e\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":102,"left":189,"right":205},{"stylingDirective":null,"type":"DELETION","blobLineNumber":190,"text":"-\t\t\tCHECK_FOR_INTERRUPTS();","html":"-\u003cspan class=\"pl-s\"\u003e\t\t\tCHECK_FOR_INTERRUPTS();\u003c/span\u003e","displayNoNewLineWarning":false,"position":103,"left":190,"right":205},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":206,"text":" \t\t\tif (r == 0)","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tif (r == 0)\u003c/span\u003e","displayNoNewLineWarning":false,"position":104,"left":191,"right":206},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":207,"text":" \t\t\t{","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":105,"left":192,"right":207},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":208,"text":" \t\t\t\tswap(pa, pb);","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\tswap(pa, pb);\u003c/span\u003e","displayNoNewLineWarning":false,"position":106,"left":193,"right":208},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":209,"text":" \t\t\t\tpa++;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\tpa++;\u003c/span\u003e","displayNoNewLineWarning":false,"position":107,"left":194,"right":209},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":210,"text":" \t\t\t}","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":108,"left":195,"right":210},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":211,"text":" \t\t\tpb++;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tpb++;\u003c/span\u003e","displayNoNewLineWarning":false,"position":109,"left":196,"right":211},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":212,"text":"+\t\t\tCHECK_FOR_INTERRUPTS();","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tCHECK_FOR_INTERRUPTS();\u003c/span\u003e","displayNoNewLineWarning":false,"position":110,"left":196,"right":212},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":213,"text":" \t\t}","html":" \u003cspan class=\"pl-s\"\u003e\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":111,"left":197,"right":213},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":214,"text":" \t\twhile (pb \u003c= pc \u0026\u0026 (r = cmp_$SUFFIX(pc, a$CMPPARAMS)) \u003e= 0)","html":" \u003cspan class=\"pl-s\"\u003e\t\twhile (pb \u0026lt;= pc \u0026amp;\u0026amp; (r = cmp_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pc, a\u003cspan class=\"pl-smi\"\u003e$CMPPARAMS\u003c/span\u003e)) \u0026gt;= 0)\u003c/span\u003e","displayNoNewLineWarning":false,"position":112,"left":198,"right":214},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":215,"text":" \t\t{","html":" \u003cspan class=\"pl-s\"\u003e\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":113,"left":199,"right":215},{"stylingDirective":null,"type":"DELETION","blobLineNumber":200,"text":"-\t\t\tCHECK_FOR_INTERRUPTS();","html":"-\u003cspan class=\"pl-s\"\u003e\t\t\tCHECK_FOR_INTERRUPTS();\u003c/span\u003e","displayNoNewLineWarning":false,"position":114,"left":200,"right":215},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":216,"text":" \t\t\tif (r == 0)","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tif (r == 0)\u003c/span\u003e","displayNoNewLineWarning":false,"position":115,"left":201,"right":216},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":217,"text":" \t\t\t{","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":116,"left":202,"right":217},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":218,"text":" \t\t\t\tswap(pc, pd);","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\tswap(pc, pd);\u003c/span\u003e","displayNoNewLineWarning":false,"position":117,"left":203,"right":218},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":219,"text":" \t\t\t\tpd--;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t\tpd--;\u003c/span\u003e","displayNoNewLineWarning":false,"position":118,"left":204,"right":219},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":220,"text":" \t\t\t}","html":" \u003cspan class=\"pl-s\"\u003e\t\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":119,"left":205,"right":220},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":221,"text":" \t\t\tpc--;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tpc--;\u003c/span\u003e","displayNoNewLineWarning":false,"position":120,"left":206,"right":221},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":222,"text":"+\t\t\tCHECK_FOR_INTERRUPTS();","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tCHECK_FOR_INTERRUPTS();\u003c/span\u003e","displayNoNewLineWarning":false,"position":121,"left":206,"right":222},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":223,"text":" \t\t}","html":" \u003cspan class=\"pl-s\"\u003e\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":122,"left":207,"right":223},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":224,"text":" \t\tif (pb \u003e pc)","html":" \u003cspan class=\"pl-s\"\u003e\t\tif (pb \u0026gt; pc)\u003c/span\u003e","displayNoNewLineWarning":false,"position":123,"left":208,"right":224},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":225,"text":" \t\t\tbreak;","html":" \u003cspan class=\"pl-s\"\u003e\t\t\tbreak;\u003c/span\u003e","displayNoNewLineWarning":false,"position":124,"left":209,"right":225},{"stylingDirective":null,"type":"HUNK","blobLineNumber":227,"text":"@@ -212,21 +228,39 @@ sub emit_qsort_implementation","html":"@@ -212,21 +228,39 @@ sub emit_qsort_implementation","displayNoNewLineWarning":false,"position":125,"left":211,"right":227},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":228,"text":" \t\tpc--;","html":" \u003cspan class=\"pl-s\"\u003e\t\tpc--;\u003c/span\u003e","displayNoNewLineWarning":false,"position":126,"left":212,"right":228},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":229,"text":" \t}","html":" \u003cspan class=\"pl-s\"\u003e\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":127,"left":213,"right":229},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":230,"text":" \tpn = a + n;","html":" \u003cspan class=\"pl-s\"\u003e\tpn = a + n;\u003c/span\u003e","displayNoNewLineWarning":false,"position":128,"left":214,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":215,"text":"-\tr = Min(pa - a, pb - pa);","html":"-\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003er\u003c/span\u003e = Min(pa - a, pb - pa);\u003c/span\u003e","displayNoNewLineWarning":false,"position":129,"left":215,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":216,"text":"-\tvecswap(a, pb - r, r);","html":"-\u003cspan class=\"pl-s\"\u003e\tvecswap(a, pb - \u003cspan class=\"x x-first x-last\"\u003er, r\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":130,"left":216,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":217,"text":"-\tr = Min(pd - pc, pn - pd - 1);","html":"-\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003er\u003c/span\u003e = Min(pd - pc, pn - pd - 1);\u003c/span\u003e","displayNoNewLineWarning":false,"position":131,"left":217,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":218,"text":"-\tvecswap(pb, pn - r, r);","html":"-\u003cspan class=\"pl-s\"\u003e\tvecswap(pb, pn - \u003cspan class=\"x x-first x-last\"\u003er, r\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":132,"left":218,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":219,"text":"-\tif ((r = pb - pa) \u003e 1)","html":"-\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003eif ((r \u003c/span\u003e= pb - pa\u003cspan class=\"x x-first x-last\"\u003e) \u0026gt; 1)\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":133,"left":219,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":220,"text":"-\t\tqsort_$SUFFIX(a, r$EXTRAPARAMS);","html":"-\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first\"\u003e\tqsort_\u003c/span\u003e\u003cspan class=\"pl-smi x\"\u003e$SUFFIX\u003c/span\u003e\u003cspan class=\"x\"\u003e(a, r\u003c/span\u003e\u003cspan class=\"pl-smi x\"\u003e$EXTRAPARAMS\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":134,"left":220,"right":230},{"stylingDirective":null,"type":"DELETION","blobLineNumber":221,"text":"-\tif ((r = pd - pc) \u003e 1)","html":"-\u003cspan class=\"pl-s\"\u003e\tif (\u003cspan class=\"x x-first x-last\"\u003e(r = pd - pc) \u0026gt; 1\u003c/span\u003e)\u003c/span\u003e","displayNoNewLineWarning":false,"position":135,"left":221,"right":230},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":231,"text":"+\td1 = Min(pa - a, pb - pa);","html":"+\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003ed1\u003c/span\u003e = Min(pa - a, pb - pa);\u003c/span\u003e","displayNoNewLineWarning":false,"position":136,"left":221,"right":231},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":232,"text":"+\tvecswap(a, pb - d1, d1);","html":"+\u003cspan class=\"pl-s\"\u003e\tvecswap(a, pb - \u003cspan class=\"x x-first x-last\"\u003ed1, d1\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":137,"left":221,"right":232},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":233,"text":"+\td1 = Min(pd - pc, pn - pd - 1);","html":"+\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003ed1\u003c/span\u003e = Min(pd - pc, pn - pd - 1);\u003c/span\u003e","displayNoNewLineWarning":false,"position":138,"left":221,"right":233},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":234,"text":"+\tvecswap(pb, pn - d1, d1);","html":"+\u003cspan class=\"pl-s\"\u003e\tvecswap(pb, pn - \u003cspan class=\"x x-first x-last\"\u003ed1, d1\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":139,"left":221,"right":234},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":235,"text":"+\td1 = pb - pa;","html":"+\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003ed1 \u003c/span\u003e= pb - pa\u003cspan class=\"x x-first x-last\"\u003e;\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":140,"left":221,"right":235},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":236,"text":"+\td2 = pd - pc;","html":"+\u003cspan class=\"pl-s\"\u003e\t\u003cspan class=\"x x-first x-last\"\u003ed2 = pd - pc\u003c/span\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":141,"left":221,"right":236},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":237,"text":"+\tif (d1 \u003c= d2)","html":"+\u003cspan class=\"pl-s\"\u003e\tif (\u003cspan class=\"x x-first x-last\"\u003ed1 \u0026lt;= d2\u003c/span\u003e)\u003c/span\u003e","displayNoNewLineWarning":false,"position":142,"left":221,"right":237},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":238,"text":" \t{","html":" \u003cspan class=\"pl-s\"\u003e\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":143,"left":222,"right":238},{"stylingDirective":null,"type":"DELETION","blobLineNumber":223,"text":"-\t\t/* Iterate rather than recurse to save stack space */","html":"-\u003cspan class=\"pl-s\"\u003e\t\t/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":144,"left":223,"right":238},{"stylingDirective":null,"type":"DELETION","blobLineNumber":224,"text":"-\t\ta = pn - r;","html":"-\u003cspan class=\"pl-s\"\u003e\t\ta = pn - r;\u003c/span\u003e","displayNoNewLineWarning":false,"position":145,"left":224,"right":238},{"stylingDirective":null,"type":"DELETION","blobLineNumber":225,"text":"-\t\tn = r;","html":"-\u003cspan class=\"pl-s\"\u003e\t\tn = r;\u003c/span\u003e","displayNoNewLineWarning":false,"position":146,"left":225,"right":238},{"stylingDirective":null,"type":"DELETION","blobLineNumber":226,"text":"-\t\tgoto loop;","html":"-\u003cspan class=\"pl-s\"\u003e\t\tgoto loop;\u003c/span\u003e","displayNoNewLineWarning":false,"position":147,"left":226,"right":238},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":239,"text":"+\t\t/* Recurse on left partition, then iterate on right partition */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t/* Recurse on left partition, then iterate on right partition */\u003c/span\u003e","displayNoNewLineWarning":false,"position":148,"left":226,"right":239},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":240,"text":"+\t\tif (d1 \u003e 1)","html":"+\u003cspan class=\"pl-s\"\u003e\t\tif (d1 \u0026gt; 1)\u003c/span\u003e","displayNoNewLineWarning":false,"position":149,"left":226,"right":240},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":241,"text":"+\t\t\tqsort_$SUFFIX(a, d1$EXTRAPARAMS);","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tqsort_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(a, d1\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":150,"left":226,"right":241},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":242,"text":"+\t\tif (d2 \u003e 1)","html":"+\u003cspan class=\"pl-s\"\u003e\t\tif (d2 \u0026gt; 1)\u003c/span\u003e","displayNoNewLineWarning":false,"position":151,"left":226,"right":242},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":243,"text":"+\t\t{","html":"+\u003cspan class=\"pl-s\"\u003e\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":152,"left":226,"right":243},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":244,"text":"+\t\t\t/* Iterate rather than recurse to save stack space */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\t/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":153,"left":226,"right":244},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":245,"text":"+\t\t\t/* qsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS); */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\t/* qsort_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pn - d2, d2\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e); */\u003c/span\u003e","displayNoNewLineWarning":false,"position":154,"left":226,"right":245},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":246,"text":"+\t\t\ta = pn - d2;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\ta = pn - d2;\u003c/span\u003e","displayNoNewLineWarning":false,"position":155,"left":226,"right":246},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":247,"text":"+\t\t\tn = d2;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tn = d2;\u003c/span\u003e","displayNoNewLineWarning":false,"position":156,"left":226,"right":247},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":248,"text":"+\t\t\tgoto loop;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tgoto loop;\u003c/span\u003e","displayNoNewLineWarning":false,"position":157,"left":226,"right":248},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":249,"text":"+\t\t}","html":"+\u003cspan class=\"pl-s\"\u003e\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":158,"left":226,"right":249},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":250,"text":"+\t}","html":"+\u003cspan class=\"pl-s\"\u003e\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":159,"left":226,"right":250},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":251,"text":"+\telse","html":"+\u003cspan class=\"pl-s\"\u003e\telse\u003c/span\u003e","displayNoNewLineWarning":false,"position":160,"left":226,"right":251},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":252,"text":"+\t{","html":"+\u003cspan class=\"pl-s\"\u003e\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":161,"left":226,"right":252},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":253,"text":"+\t\t/* Recurse on right partition, then iterate on left partition */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t/* Recurse on right partition, then iterate on left partition */\u003c/span\u003e","displayNoNewLineWarning":false,"position":162,"left":226,"right":253},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":254,"text":"+\t\tif (d2 \u003e 1)","html":"+\u003cspan class=\"pl-s\"\u003e\t\tif (d2 \u0026gt; 1)\u003c/span\u003e","displayNoNewLineWarning":false,"position":163,"left":226,"right":254},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":255,"text":"+\t\t\tqsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS);","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tqsort_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pn - d2, d2\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);\u003c/span\u003e","displayNoNewLineWarning":false,"position":164,"left":226,"right":255},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":256,"text":"+\t\tif (d1 \u003e 1)","html":"+\u003cspan class=\"pl-s\"\u003e\t\tif (d1 \u0026gt; 1)\u003c/span\u003e","displayNoNewLineWarning":false,"position":165,"left":226,"right":256},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":257,"text":"+\t\t{","html":"+\u003cspan class=\"pl-s\"\u003e\t\t{\u003c/span\u003e","displayNoNewLineWarning":false,"position":166,"left":226,"right":257},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":258,"text":"+\t\t\t/* Iterate rather than recurse to save stack space */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\t/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":167,"left":226,"right":258},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":259,"text":"+\t\t\t/* qsort_$SUFFIX(a, d1$EXTRAPARAMS); */","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\t/* qsort_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(a, d1\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e); */\u003c/span\u003e","displayNoNewLineWarning":false,"position":168,"left":226,"right":259},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":260,"text":"+\t\t\tn = d1;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tn = d1;\u003c/span\u003e","displayNoNewLineWarning":false,"position":169,"left":226,"right":260},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":261,"text":"+\t\t\tgoto loop;","html":"+\u003cspan class=\"pl-s\"\u003e\t\t\tgoto loop;\u003c/span\u003e","displayNoNewLineWarning":false,"position":170,"left":226,"right":261},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":262,"text":"+\t\t}","html":"+\u003cspan class=\"pl-s\"\u003e\t\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":171,"left":226,"right":262},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":263,"text":" \t}","html":" \u003cspan class=\"pl-s\"\u003e\t}\u003c/span\u003e","displayNoNewLineWarning":false,"position":172,"left":227,"right":263},{"stylingDirective":null,"type":"DELETION","blobLineNumber":228,"text":"-/*\t\tqsort_$SUFFIX(pn - r, r$EXTRAPARAMS);*/","html":"-\u003cspan class=\"pl-s\"\u003e/*\t\tqsort_\u003cspan class=\"pl-smi\"\u003e$SUFFIX\u003c/span\u003e(pn - r, r\u003cspan class=\"pl-smi\"\u003e$EXTRAPARAMS\u003c/span\u003e);*/\u003c/span\u003e","displayNoNewLineWarning":false,"position":173,"left":228,"right":263},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":264,"text":" }","html":" \u003cspan class=\"pl-s\"\u003e}\u003c/span\u003e","displayNoNewLineWarning":false,"position":174,"left":229,"right":264},{"stylingDirective":null,"type":"DELETION","blobLineNumber":230,"text":"-","html":"-\u003cspan class=\"pl-s\"\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":175,"left":230,"right":264},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":265,"text":" EOM","html":" \u003cspan class=\"pl-s\"\u003e\u003cspan class=\"pl-pds\"\u003eEOM\u003c/span\u003e\u003c/span\u003e","displayNoNewLineWarning":false,"position":176,"left":231,"right":265},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":266,"text":" }","html":" }","displayNoNewLineWarning":false,"position":177,"left":232,"right":266}],"diffNumber":0,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":266,"linesChanged":86,"newTreeEntry":{"lineCount":266,"path":"src/backend/utils/sort/gen_qsort_tuple.pl","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"src/backend/utils/sort/gen_qsort_tuple.pl","mode":100644},"linesAdded":60,"linesDeleted":26,"path":"src/backend/utils/sort/gen_qsort_tuple.pl","pathDigest":"c2ef0c9d920f178326b950c4ed04ea9f40dbd06c93ebfd30f2ba9cc46a7e9bb2","status":"MODIFIED","truncatedReason":null,"oldOid":"828df727a673d718265766611e59aa5189d102ba","newOid":"9d6077abf9d6efd992a59f05ef5aba981ea32096","copilotChatReference":null,"deletedSha":"828df727a673d718265766611e59aa5189d102ba","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null},{"diffLines":[{"stylingDirective":null,"type":"HUNK","blobLineNumber":5,"text":"@@ -6,6 +6,7 @@","html":"@@ -6,6 +6,7 @@","displayNoNewLineWarning":false,"position":0,"left":5,"right":5},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":6,"text":" *\t Remove __inline, _DIAGASSERTs, __P","html":" \u003cspan class=pl-c\u003e *\t Remove __inline, _DIAGASSERTs, __P\u003c/span\u003e","displayNoNewLineWarning":false,"position":1,"left":6,"right":6},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":7,"text":" *\t Remove ill-considered \"swap_cnt\" switch to insertion sort,","html":" \u003cspan class=pl-c\u003e *\t Remove ill-considered \u0026quot;swap_cnt\u0026quot; switch to insertion sort,\u003c/span\u003e","displayNoNewLineWarning":false,"position":2,"left":7,"right":7},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":8,"text":" *\t in favor of a simple check for presorted input.","html":" \u003cspan class=pl-c\u003e *\t in favor of a simple check for presorted input.\u003c/span\u003e","displayNoNewLineWarning":false,"position":3,"left":8,"right":8},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":9,"text":"+ *\t Take care to recurse on the smaller partition, to bound stack usage.","html":"+\u003cspan class=pl-c\u003e *\t Take care to recurse on the smaller partition, to bound stack usage.\u003c/span\u003e","displayNoNewLineWarning":false,"position":4,"left":8,"right":9},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":10,"text":" *","html":" \u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":5,"left":9,"right":10},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":11,"text":" *\tCAUTION: if you change this file, see also qsort_arg.c, gen_qsort_tuple.pl","html":" \u003cspan class=pl-c\u003e *\tCAUTION: if you change this file, see also qsort_arg.c, gen_qsort_tuple.pl\u003c/span\u003e","displayNoNewLineWarning":false,"position":6,"left":10,"right":11},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":12,"text":" *","html":" \u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":7,"left":11,"right":12},{"stylingDirective":null,"type":"HUNK","blobLineNumber":54,"text":"@@ -54,9 +55,18 @@ static void swapfunc(char *, char *, size_t, int);","html":"@@ -54,9 +55,18 @@ static void swapfunc(char *, char *, size_t, int);","displayNoNewLineWarning":false,"position":8,"left":53,"right":54},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":55,"text":" * Qsort routine based on J. L. Bentley and M. D. McIlroy,","html":" \u003cspan class=pl-c\u003e * Qsort routine based on J. L. Bentley and M. D. McIlroy,\u003c/span\u003e","displayNoNewLineWarning":false,"position":9,"left":54,"right":55},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":56,"text":" * \"Engineering a sort function\",","html":" \u003cspan class=pl-c\u003e * \u0026quot;Engineering a sort function\u0026quot;,\u003c/span\u003e","displayNoNewLineWarning":false,"position":10,"left":55,"right":56},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":57,"text":" * Software--Practice and Experience 23 (1993) 1249-1265.","html":" \u003cspan class=pl-c\u003e * Software--Practice and Experience 23 (1993) 1249-1265.\u003c/span\u003e","displayNoNewLineWarning":false,"position":11,"left":56,"right":57},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":58,"text":"+ *","html":"+\u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":12,"left":56,"right":58},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":59,"text":" * We have modified their original by adding a check for already-sorted input,","html":" \u003cspan class=pl-c\u003e * We have modified their original by adding a check for already-sorted input,\u003c/span\u003e","displayNoNewLineWarning":false,"position":13,"left":57,"right":59},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":60,"text":" * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.","html":" \u003cspan class=pl-c\u003e * which seems to be a win per discussions on pgsql-hackers around 2006-03-21.\u003c/span\u003e","displayNoNewLineWarning":false,"position":14,"left":58,"right":60},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":61,"text":"+ *","html":"+\u003cspan class=pl-c\u003e *\u003c/span\u003e","displayNoNewLineWarning":false,"position":15,"left":58,"right":61},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":62,"text":"+ * Also, we recurse on the smaller partition and iterate on the larger one,","html":"+\u003cspan class=pl-c\u003e * Also, we recurse on the smaller partition and iterate on the larger one,\u003c/span\u003e","displayNoNewLineWarning":false,"position":16,"left":58,"right":62},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":63,"text":"+ * which ensures we cannot recurse more than log(N) levels (since the","html":"+\u003cspan class=pl-c\u003e * which ensures we cannot recurse more than log(N) levels (since the\u003c/span\u003e","displayNoNewLineWarning":false,"position":17,"left":58,"right":63},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":64,"text":"+ * partition recursed to is surely no more than half of the input). Bentley","html":"+\u003cspan class=pl-c\u003e * partition recursed to is surely no more than half of the input). Bentley\u003c/span\u003e","displayNoNewLineWarning":false,"position":18,"left":58,"right":64},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":65,"text":"+ * and McIlroy explicitly rejected doing this on the grounds that it's \"not","html":"+\u003cspan class=pl-c\u003e * and McIlroy explicitly rejected doing this on the grounds that it\u0026#39;s \u0026quot;not\u003c/span\u003e","displayNoNewLineWarning":false,"position":19,"left":58,"right":65},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":66,"text":"+ * worth the effort\", but we have seen crashes in the field due to stack","html":"+\u003cspan class=pl-c\u003e * worth the effort\u0026quot;, but we have seen crashes in the field due to stack\u003c/span\u003e","displayNoNewLineWarning":false,"position":20,"left":58,"right":66},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":67,"text":"+ * overrun, so that judgment seems wrong.","html":"+\u003cspan class=pl-c\u003e * overrun, so that judgment seems wrong.\u003c/span\u003e","displayNoNewLineWarning":false,"position":21,"left":58,"right":67},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":68,"text":" */","html":" \u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":22,"left":59,"right":68},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":69,"text":"+","html":"+","displayNoNewLineWarning":false,"position":23,"left":59,"right":69},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":70,"text":" #define swapcode(TYPE, parmi, parmj, n) \\","html":" \u003cspan class=pl-k\u003e#define\u003c/span\u003e \u003cspan class=pl-en\u003eswapcode\u003c/span\u003e(\u003cspan class=pl-c1\u003eTYPE\u003c/span\u003e, \u003cspan class=pl-s1\u003eparmi\u003c/span\u003e, \u003cspan class=pl-s1\u003eparmj\u003c/span\u003e, \u003cspan class=pl-s1\u003en\u003c/span\u003e) \\","displayNoNewLineWarning":false,"position":24,"left":60,"right":70},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":71,"text":" do {\t\t\\","html":" do {\t\t\\","displayNoNewLineWarning":false,"position":25,"left":61,"right":71},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":72,"text":" \tsize_t i = (n) / sizeof (TYPE);\t\t\t\\","html":" \tsize_t i = (n) / sizeof (TYPE);\t\t\t\\","displayNoNewLineWarning":false,"position":26,"left":62,"right":72},{"stylingDirective":null,"type":"HUNK","blobLineNumber":98,"text":"@@ -89,7 +99,7 @@ swapfunc(char *a, char *b, size_t n, int swaptype)","html":"@@ -89,7 +99,7 @@ swapfunc(char *a, char *b, size_t n, int swaptype)","displayNoNewLineWarning":false,"position":27,"left":88,"right":98},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":99,"text":" \t} else\t\t\t\t\t\t\t\\","html":" \t} else\t\t\t\t\t\t\t\\","displayNoNewLineWarning":false,"position":28,"left":89,"right":99},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":100,"text":" \t\tswapfunc(a, b, es, swaptype)","html":" \t\tswapfunc(a, b, es, swaptype)","displayNoNewLineWarning":false,"position":29,"left":90,"right":100},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":101,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":30,"left":91,"right":101},{"stylingDirective":null,"type":"DELETION","blobLineNumber":92,"text":"-#define vecswap(a, b, n) if ((n) \u003e 0) swapfunc((a), (b), (size_t)(n), swaptype)","html":"-\u003cspan class=\"pl-k\"\u003e#define\u003c/span\u003e \u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e) if ((n) \u0026gt; 0) swapfunc(\u003cspan class=\"x x-first x-last\"\u003e(a), (b), (size_t)(n)\u003c/span\u003e, swaptype)","displayNoNewLineWarning":false,"position":31,"left":92,"right":101},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":102,"text":"+#define vecswap(a, b, n) if ((n) \u003e 0) swapfunc(a, b, n, swaptype)","html":"+\u003cspan class=\"pl-k\"\u003e#define\u003c/span\u003e \u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003eb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003en\u003c/span\u003e) if ((n) \u0026gt; 0) swapfunc(\u003cspan class=\"x x-first x-last\"\u003ea, b, n\u003c/span\u003e, swaptype)","displayNoNewLineWarning":false,"position":32,"left":92,"right":102},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":103,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":33,"left":93,"right":103},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":104,"text":" static char *","html":" \u003cspan class=pl-k\u003estatic\u003c/span\u003e \u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e","displayNoNewLineWarning":false,"position":34,"left":94,"right":104},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":105,"text":" med3(char *a, char *b, char *c, int (*cmp) (const void *, const void *))","html":" \u003cspan class=pl-en\u003emed3\u003c/span\u003e(\u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003ea\u003c/span\u003e, \u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003eb\u003c/span\u003e, \u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003ec\u003c/span\u003e, \u003cspan class=pl-smi\u003eint\u003c/span\u003e (\u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003ecmp\u 10000 003c/span\u003e) (\u003cspan class=pl-k\u003econst\u003c/span\u003e \u003cspan class=pl-smi\u003evoid\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e, \u003cspan class=pl-k\u003econst\u003c/span\u003e \u003cspan class=pl-smi\u003evoid\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e))","displayNoNewLineWarning":false,"position":35,"left":95,"right":105},{"stylingDirective":null,"type":"HUNK","blobLineNumber":118,"text":"@@ -109,8 +119,9 @@ pg_qsort(void *a, size_t n, size_t es, int (*cmp) (const void *, const void *))","html":"@@ -109,8 +119,9 @@ pg_qsort(void *a, size_t n, size_t es, int (*cmp) (const void *, const void *))","displayNoNewLineWarning":false,"position":36,"left":108,"right":118},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":119,"text":" \t\t\t *pl,","html":" \t\t\t \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003epl\u003c/span\u003e,","displayNoNewLineWarning":false,"position":37,"left":109,"right":119},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":120,"text":" \t\t\t *pm,","html":" \t\t\t \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003epm\u003c/span\u003e,","displayNoNewLineWarning":false,"position":38,"left":110,"right":120},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":121,"text":" \t\t\t *pn;","html":" \t\t\t \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003epn\u003c/span\u003e;","displayNoNewLineWarning":false,"position":39,"left":111,"right":121},{"stylingDirective":null,"type":"DELETION","blobLineNumber":112,"text":"-\tint\t\t\td,","html":"-\t\u003cspan class=pl-smi\u003eint\u003c/span\u003e\t\t\t\u003cspan class=pl-s1\u003ed\u003c/span\u003e,","displayNoNewLineWarning":false,"position":40,"left":112,"right":121},{"stylingDirective":null,"type":"DELETION","blobLineNumber":113,"text":"-\t\t\t\tr,","html":"-\t\t\t\t\u003cspan class=pl-s1\u003er\u003c/span\u003e,","displayNoNewLineWarning":false,"position":41,"left":113,"right":121},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":122,"text":"+\tsize_t\t\td1,","html":"+\t\u003cspan class=pl-smi\u003esize_t\u003c/span\u003e\t\t\u003cspan class=pl-s1\u003ed1\u003c/span\u003e,","displayNoNewLineWarning":false,"position":42,"left":113,"right":122},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":123,"text":"+\t\t\t\td2;","html":"+\t\t\t\t\u003cspan class=pl-s1\u003ed2\u003c/span\u003e;","displayNoNewLineWarning":false,"position":43,"left":113,"right":123},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":124,"text":"+\tint\t\t\tr,","html":"+\t\u003cspan class=pl-smi\u003eint\u003c/span\u003e\t\t\t\u003cspan class=pl-s1\u003er\u003c/span\u003e,","displayNoNewLineWarning":false,"position":44,"left":113,"right":124},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":125,"text":" \t\t\t\tswaptype,","html":" \t\t\t\t\u003cspan class=pl-s1\u003eswaptype\u003c/span\u003e,","displayNoNewLineWarning":false,"position":45,"left":114,"right":125},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":126,"text":" \t\t\t\tpresorted;","html":" \t\t\t\t\u003cspan class=pl-s1\u003epresorted\u003c/span\u003e;","displayNoNewLineWarning":false,"position":46,"left":115,"right":126},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":127,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":47,"left":116,"right":127},{"stylingDirective":null,"type":"HUNK","blobLineNumber":151,"text":"@@ -141,7 +152,8 @@ loop:SWAPINIT(a, es);","html":"@@ -141,7 +152,8 @@ loop:SWAPINIT(a, es);","displayNoNewLineWarning":false,"position":48,"left":140,"right":151},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":152,"text":" \t\tpn = (char *) a + (n - 1) * es;","html":" \t\t\u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e (\u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e) \u003cspan class=pl-s1\u003ea\u003c/span\u003e \u003cspan class=pl-c1\u003e+\u003c/span\u003e (\u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-c1\u003e1\u003c/span\u003e) \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":49,"left":141,"right":152},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":153,"text":" \t\tif (n \u003e 40)","html":" \t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026gt;\u003c/span\u003e \u003cspan class=pl-c1\u003e40\u003c/span\u003e)","displayNoNewLineWarning":false,"position":50,"left":142,"right":153},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":154,"text":" \t\t{","html":" \t\t{","displayNoNewLineWarning":false,"position":51,"left":143,"right":154},{"stylingDirective":null,"type":"DELETION","blobLineNumber":144,"text":"-\t\t\td = (n / 8) * es;","html":"-\t\t\t\u003cspan class=pl-s1\u003ed\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e (\u003cspan class=pl-s1\u003en\u003c/span\u003e / \u003cspan class=pl-c1\u003e8\u003c/span\u003e) \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":52,"left":144,"right":154},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":155,"text":"+\t\t\tsize_t\t\td = (n / 8) * es;","html":"+\t\t\t\u003cspan class=pl-smi\u003esize_t\u003c/span\u003e\t\t\u003cspan class=pl-s1\u003ed\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e (\u003cspan class=pl-s1\u003en\u003c/span\u003e / \u003cspan class=pl-c1\u003e8\u003c/span\u003e) \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":53,"left":144,"right":155},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":156,"text":"+","html":"+","displayNoNewLineWarning":false,"position":54,"left":144,"right":156},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":157,"text":" \t\t\tpl = med3(pl, pl + d, pl + 2 * d, cmp);","html":" \t\t\t\u003cspan class=pl-s1\u003epl\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003emed3\u003c/span\u003e(\u003cspan class=pl-s1\u003epl\u003c/span\u003e, \u003cspan class=pl-s1\u003epl\u003c/span\u003e \u003cspan class=pl-c1\u003e+\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003epl\u003c/span\u003e \u003cspan class=pl-c1\u003e+\u003c/span\u003e \u003cspan class=pl-c1\u003e2\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003ecmp\u003c/span\u003e);","displayNoNewLineWarning":false,"position":55,"left":145,"right":157},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":158,"text":" \t\t\tpm = med3(pm - d, pm, pm + d, cmp);","html":" \t\t\t\u003cspan class=pl-s1\u003epm\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003emed3\u003c/span\u003e(\u003cspan class=pl-s1\u003epm\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003epm\u003c/span\u003e, \u003cspan class=pl-s1\u003epm\u003c/span\u003e \u003cspan class=pl-c1\u003e+\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003ecmp\u003c/span\u003e);","displayNoNewLineWarning":false,"position":56,"left":146,"right":158},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":159,"text":" \t\t\tpn = med3(pn - 2 * d, pn - d, pn, cmp);","html":" \t\t\t\u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-en\u003emed3\u003c/span\u003e(\u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-c1\u003e2\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-s1\u003ed\u003c/span\u003e, \u003cspan class=pl-s1\u003epn\u003c/span\u003e, \u003cspan class=pl-s1\u003ecmp\u003c/span\u003e);","displayNoNewLineWarning":false,"position":57,"left":147,"right":159},{"stylingDirective":null,"type":"HUNK","blobLineNumber":189,"text":"@@ -178,27 +190,46 @@ loop:SWAPINIT(a, es);","html":"@@ -178,27 +190,46 @@ loop:SWAPINIT(a, es);","displayNoNewLineWarning":false,"position":58,"left":177,"right":189},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":190,"text":" \t\tpc -= es;","html":" \t\t\u003cspan class=pl-s1\u003epc\u003c/span\u003e \u003cspan class=pl-c1\u003e-=\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":59,"left":178,"right":190},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":191,"text":" \t}","html":" \t}","displayNoNewLineWarning":false,"position":60,"left":179,"right":191},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":192,"text":" \tpn = (char *) a + n * es;","html":" \t\u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e (\u003cspan class=pl-smi\u003echar\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e) \u003cspan class=pl-s1\u003ea\u003c/span\u003e \u003cspan class=pl-c1\u003e+\u003c/span\u003e \u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":61,"left":180,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":181,"text":"-\tr = Min(pa - (char *) a, pb - pa);","html":"-\t\u003cspan class=\"pl-s1 x x-first x-last\"\u003er\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eMin\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e);","displayNoNewLineWarning":false,"position":62,"left":181,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":182,"text":"-\tvecswap(a, pb - r, r);","html":"-\t\u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1 x x-first\"\u003er\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003er\u003c/span\u003e);","displayNoNewLineWarning":false,"position":63,"left":182,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":183,"text":"-\tr = Min(pd - pc, pn - pd - es);","html":"-\t\u003cspan class=\"pl-s1 x x-first x-last\"\u003er\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eMin\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epd\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epc\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epd\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ees\u003c/span\u003e);","displayNoNewLineWarning":false,"position":64,"left":183,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":184,"text":"-\tvecswap(pb, pn - r, r);","html":"-\t\u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1 x x-first\"\u003er\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003er\u003c/span\u003e);","displayNoNewLineWarning":false,"position":65,"left":184,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":185,"text":"-\tif ((r = pb - pa) \u003e es)","html":"-\t\u003cspan class=\"pl-k x x-first\"\u003eif\u003c/span\u003e\u003cspan class=\"x\"\u003e ((\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003er\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e\u003cspan class=\"x x-first\"\u003e) \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ees\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e","displayNoNewLineWarning":false,"position":66,"left":185,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":186,"text":"-\t\tqsort(a, r / es, es, cmp);","html":"-\t\u003cspan class=\"x x-first\"\u003e\t\u003c/span\u003e\u003cspan class=\"pl-en x\"\u003eqsort\u003c/span\u003e\u003cspan class=\"x\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ea\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003er\u003c/span\u003e\u003cspan class=\"x\"\u003e / \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ees\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ees\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003ecmp\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e)\u003c/span\u003e;","displayNoNewLineWarning":false,"position":67,"left":186,"right":192},{"stylingDirective":null,"type":"DELETION","blobLineNumber":187,"text":"-\tif ((r = pd - pc) \u003e es)","html":"-\t\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"x x-first\"\u003e(\u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003er\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003epd\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e-\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003epc\u003c/span\u003e\u003cspan class=\"x\"\u003e) \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003ees\u003c/span\u003e)","displayNoNewLineWarning":false,"position":68,"left":187,"right":192},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":193,"text":"+\td1 = Min(pa - (char *) a, pb - pa);","html":"+\t\u003cspan class=\"pl-s1 x x-first x-last\"\u003ed1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eMin\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e (\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e);","displayNoNewLineWarning":false,"position":69,"left":187,"right":193},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":194,"text":"+\tvecswap(a, pb - d1, d1);","html":"+\t\u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1 x x-first\"\u003ed1\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003ed1\u003c/span\u003e);","displayNoNewLineWarning":false,"position":70,"left":187,"right":194},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":195,"text":"+\td1 = Min(pd - pc, pn - pd - es);","html":"+\t\u003cspan class=\"pl-s1 x x-first x-last\"\u003ed1\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-en\"\u003eMin\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epd\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epc\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epd\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003ees\u003c/span\u003e);","displayNoNewLineWarning":false,"position":71,"left":187,"right":195},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":196,"text":"+\tvecswap(pb, pn - d1, d1);","html":"+\t\u003cspan class=\"pl-en\"\u003evecswap\u003c/span\u003e(\u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e, \u003cspan class=\"pl-s1\"\u003epn\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1 x x-first\"\u003ed1\u003c/span\u003e\u003cspan class=\"x\"\u003e, \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003ed1\u003c/span\u003e);","displayNoNewLineWarning":false,"position":72,"left":187,"right":196},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":197,"text":"+\td1 = pb - pa;","html":"+\t\u003cspan class=\"pl-s1 x x-first\"\u003ed1\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1\"\u003e=\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epb\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e-\u003c/span\u003e \u003cspan class=\"pl-s1\"\u003epa\u003c/span\u003e\u003cspan class=\"x x-first x-last\"\u003e;\u003c/span\u003e","displayNoNewLineWarning":false,"position":73,"left":187,"right":197},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":198,"text":"+\td2 = pd - pc;","html":"+\t\u003cspan class=\"pl-s1 x x-first\"\u003ed2\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e=\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x\"\u003epd\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-c1 x\"\u003e-\u003c/span\u003e\u003cspan class=\"x\"\u003e \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003epc\u003c/span\u003e;","displayNoNewLineWarning":false,"position":74,"left":187,"right":198},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":199,"text":"+\tif (d1 \u003c= d2)","html":"+\t\u003cspan class=\"pl-k\"\u003eif\u003c/span\u003e (\u003cspan class=\"pl-s1 x x-first\"\u003ed1\u003c/span\u003e\u003cspan class=\"x\"\u003e \u0026lt;= \u003c/span\u003e\u003cspan class=\"pl-s1 x x-last\"\u003ed2\u003c/span\u003e)","displayNoNewLineWarning":false,"position":75,"left":187,"right":199},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":200,"text":" \t{","html":" \t{","displayNoNewLineWarning":false,"position":76,"left":188,"right":200},{"stylingDirective":null,"type":"DELETION","blobLineNumber":189,"text":"-\t\t/* Iterate rather than recurse to save stack space */","html":"-\t\t\u003cspan class=pl-c\u003e/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":77,"left":189,"right":200},{"stylingDirective":null,"type":"DELETION","blobLineNumber":190,"text":"-\t\ta = pn - r;","html":"-\t\t\u003cspan class=pl-s1\u003ea\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-s1\u003er\u003c/span\u003e;","displayNoNewLineWarning":false,"position":78,"left":190,"right":200},{"stylingDirective":null,"type":"DELETION","blobLineNumber":191,"text":"-\t\tn = r / es;","html":"-\t\t\u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003er\u003c/span\u003e / \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":79,"left":191,"right":200},{"stylingDirective":null,"type":"DELETION","blobLineNumber":192,"text":"-\t\tgoto loop;","html":"-\t\tgoto \u003cspan class=pl-ent\u003eloop\u003c/span\u003e;","displayNoNewLineWarning":false,"position":80,"left":192,"right":200},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":201,"text":"+\t\t/* Recurse on left partition, then iterate on right partition */","html":"+\t\t\u003cspan class=pl-c\u003e/* Recurse on left partition, then iterate on right partition */\u003c/span\u003e","displayNoNewLineWarning":false,"position":81,"left":192,"right":201},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":202,"text":"+\t\tif (d1 \u003e es)","html":"+\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ed1\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026gt;\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e)","displayNoNewLineWarning":false,"position":82,"left":192,"right":202},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":203,"text":"+\t\t\tpg_qsort(a, d1 / es, es, cmp);","html":"+\t\t\t\u003cspan class=pl-en\u003epg_qsort\u003c/span\u003e(\u003cspan class=pl-s1\u003ea\u003c/span\u003e, \u003cspan class=pl-s1\u003ed1\u003c/span\u003e / \u003cspan class=pl-s1\u003ees\u003c/span\u003e, \u003cspan class=pl-s1\u003ees\u003c/span\u003e, \u003cspan class=pl-s1\u003ecmp\u003c/span\u003e);","displayNoNewLineWarning":false,"position":83,"left":192,"right":203},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":204,"text":"+\t\tif (d2 \u003e es)","html":"+\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ed2\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026gt;\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e)","displayNoNewLineWarning":false,"position":84,"left":192,"right":204},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":205,"text":"+\t\t{","html":"+\t\t{","displayNoNewLineWarning":false,"position":85,"left":192,"right":205},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":206,"text":"+\t\t\t/* Iterate rather than recurse to save stack space */","html":"+\t\t\t\u003cspan class=pl-c\u003e/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":86,"left":192,"right":206},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":207,"text":"+\t\t\t/* pg_qsort(pn - d2, d2 / es, es, cmp); */","html":"+\t\t\t\u003cspan class=pl-c\u003e/* pg_qsort(pn - d2, d2 / es, es, cmp); */\u003c/span\u003e","displayNoNewLineWarning":false,"position":87,"left":192,"right":207},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":208,"text":"+\t\t\ta = pn - d2;","html":"+\t\t\t\u003cspan class=pl-s1\u003ea\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-s1\u003ed2\u003c/span\u003e;","displayNoNewLineWarning":false,"position":88,"left":192,"right":208},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":209,"text":"+\t\t\tn = d2 / es;","html":"+\t\t\t\u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ed2\u003c/span\u003e / \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":89,"left":192,"right":209},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":210,"text":"+\t\t\tgoto loop;","html":"+\t\t\tgoto \u003cspan class=pl-ent\u003eloop\u003c/span\u003e;","displayNoNewLineWarning":false,"position":90,"left":192,"right":210},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":211,"text":"+\t\t}","html":"+\t\t}","displayNoNewLineWarning":false,"position":91,"left":192,"right":211},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":212,"text":"+\t}","html":"+\t}","displayNoNewLineWarning":false,"position":92,"left":192,"right":212},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":213,"text":"+\telse","html":"+\t\u003cspan class=pl-k\u003eelse\u003c/span\u003e","displayNoNewLineWarning":false,"position":93,"left":192,"right":213},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":214,"text":"+\t{","html":"+\t{","displayNoNewLineWarning":false,"position":94,"left":192,"right":214},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":215,"text":"+\t\t/* Recurse on right partition, then iterate on left partition */","html":"+\t\t\u003cspan class=pl-c\u003e/* Recurse on right partition, then iterate on left partition */\u003c/span\u003e","displayNoNewLineWarning":false,"position":95,"left":192,"right":215},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":216,"text":"+\t\tif (d2 \u003e es)","html":"+\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ed2\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026gt;\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e)","displayNoNewLineWarning":false,"position":96,"left":192,"right":216},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":217,"text":"+\t\t\tpg_qsort(pn - d2, d2 / es, es, cmp);","html":"+\t\t\t\u003cspan class=pl-en\u003epg_qsort\u003c/span\u003e(\u003cspan class=pl-s1\u003epn\u003c/span\u003e \u003cspan class=pl-c1\u003e-\u003c/span\u003e \u003cspan class=pl-s1\u003ed2\u003c/span\u003e, \u003cspan class=pl-s1\u003ed2\u003c/span\u003e / \u003cspan class=pl-s1\u003ees\u003c/span\u003e, \u003cspan class=pl-s1\u003ees\u003c/span\u003e, \u003cspan class=pl-s1\u003ecmp\u003c/span\u003e);","displayNoNewLineWarning":false,"position":97,"left":192,"right":217},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":218,"text":"+\t\tif (d1 \u003e es)","html":"+\t\t\u003cspan class=pl-k\u003eif\u003c/span\u003e (\u003cspan class=pl-s1\u003ed1\u003c/span\u003e \u003cspan class=pl-c1\u003e\u0026gt;\u003c/span\u003e \u003cspan class=pl-s1\u003ees\u003c/span\u003e)","displayNoNewLineWarning":false,"position":98,"left":192,"right":218},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":219,"text":"+\t\t{","html":"+\t\t{","displayNoNewLineWarning":false,"position":99,"left":192,"right":219},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":220,"text":"+\t\t\t/* Iterate rather than recurse to save stack space */","html":"+\t\t\t\u003cspan class=pl-c\u003e/* Iterate rather than recurse to save stack space */\u003c/span\u003e","displayNoNewLineWarning":false,"position":100,"left":192,"right":220},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":221,"text":"+\t\t\t/* pg_qsort(a, d1 / es, es, cmp); */","html":"+\t\t\t\u003cspan class=pl-c\u003e/* pg_qsort(a, d1 / es, es, cmp); */\u003c/span\u003e","displayNoNewLineWarning":false,"position":101,"left":192,"right":221},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":222,"text":"+\t\t\tn = d1 / es;","html":"+\t\t\t\u003cspan class=pl-s1\u003en\u003c/span\u003e \u003cspan class=pl-c1\u003e=\u003c/span\u003e \u003cspan class=pl-s1\u003ed1\u003c/span\u003e / \u003cspan class=pl-s1\u003ees\u003c/span\u003e;","displayNoNewLineWarning":false,"position":102,"left":192,"right":222},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":223,"text":"+\t\t\tgoto loop;","html":"+\t\t\tgoto \u003cspan class=pl-ent\u003eloop\u003c/span\u003e;","displayNoNewLineWarning":false,"position":103,"left":192,"right":223},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":224,"text":"+\t\t}","html":"+\t\t}","displayNoNewLineWarning":false,"position":104,"left":192,"right":224},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":225,"text":" \t}","html":" \t}","displayNoNewLineWarning":false,"position":105,"left":193,"right":225},{"stylingDirective":null,"type":"DELETION","blobLineNumber":194,"text":"-/*\t\tqsort(pn - r, r / es, es, cmp);*/","html":"-\u003cspan class=pl-c\u003e/*\t\tqsort(pn - r, r / es, es, cmp);*/\u003c/span\u003e","displayNoNewLineWarning":false,"position":106,"left":194,"right":225},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":226,"text":" }","html":" }","displayNoNewLineWarning":false,"position":107,"left":195,"right":226},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":227,"text":" ","html":"\u003cbr\u003e","displayNoNewLineWarning":false,"position":108,"left":196,"right":227},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":228,"text":" /*","html":" \u003cspan class=pl-c\u003e/*\u003c/span\u003e","displayNoNewLineWarning":false,"position":109,"left":197,"right":228},{"stylingDirective":null,"type":"DELETION","blobLineNumber":198,"text":"- * qsort wrapper for strcmp.","html":"-\u003cspan class=\"pl-c\"\u003e * qsort wrapper for strcmp.\u003c/span\u003e","displayNoNewLineWarning":false,"position":110,"left":198,"right":228},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":229,"text":"+ * qsort comparator wrapper for strcmp.","html":"+\u003cspan class=\"pl-c\"\u003e * qsort \u003cspan class=\"x x-first x-last\"\u003ecomparator \u003c/span\u003ewrapper for strcmp.\u003c/span\u003e","displayNoNewLineWarning":false,"position":111,"left":198,"right":229},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":230,"text":" */","html":" \u003cspan class=pl-c\u003e */\u003c/span\u003e","displayNoNewLineWarning":false,"position":112,"left":199,"right":230},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":231,"text":" int","html":" \u003cspan class=pl-smi\u003eint\u003c/span\u003e","displayNoNewLineWarning":false,"position":113,"left":200,"right":231},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":232,"text":" pg_qsort_strcmp(const void *a, const void *b)","html":" \u003cspan class=pl-en\u003epg_qsort_strcmp\u003c/span\u003e(\u003cspan class=pl-k\u003econst\u003c/span\u003e \u003cspan class=pl-smi\u003evoid\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003ea\u003c/span\u003e, \u003cspan class=pl-k\u003econst\u003c/span\u003e \u003cspan class=pl-smi\u003evoid\u003c/span\u003e \u003cspan class=pl-c1\u003e*\u003c/span\u003e\u003cspan class=pl-s1\u003eb\u003c/span\u003e)","displayNoNewLineWarning":false,"position":114,"left":201,"right":232},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":233,"text":" {","html":" {","displayNoNewLineWarning":false,"position":115,"left":202,"right":233},{"stylingDirective":null,"type":"DELETION","blobLineNumber":203,"text":"-\treturn strcmp(*(char *const *) a, *(char *const *) b);","html":"-\t\u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estrcmp\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-k\"\u003econst\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e(\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-k\"\u003econst\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003eb\u003c/span\u003e);","displayNoNewLineWarning":false,"position":116,"left":203,"right":233},{"stylingDirective":null,"type":"ADDITION","blobLineNumber":234,"text":"+\treturn strcmp(*(const char *const *) a, *(const char *const *) b);","html":"+\t\u003cspan class=\"pl-k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"pl-en\"\u003estrcmp\u003c/span\u003e(\u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e(\u003cspan class=\"pl-k x x-first\"\u003econst\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e \u003c/span\u003e\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-k\"\u003econst\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003ea\u003c/span\u003e, \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e(\u003cspan class=\"pl-k x x-first\"\u003econst\u003c/span\u003e\u003cspan class=\"x x-last\"\u003e \u003c/span\u003e\u003cspan class=\"pl-smi\"\u003echar\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e\u003cspan class=\"pl-k\"\u003econst\u003c/span\u003e \u003cspan class=\"pl-c1\"\u003e*\u003c/span\u003e) \u003cspan class=\"pl-s1\"\u003eb\u003c/span\u003e);","displayNoNewLineWarning":false,"position":117,"left":203,"right":234},{"stylingDirective":null,"type":"CONTEXT","blobLineNumber":235,"text":" }","html":" }","displayNoNewLineWarning":false,"position":118,"left":204,"right":235}],"diffNumber":1,"diffSize":"0 Bytes","isBinary":false,"isTooBig":false,"collapsed":false,"isSubmodule":false,"lineCount":235,"linesChanged":67,"newTreeEntry":{"lineCount":235,"path":"src/port/qsort.c","mode":100644,"isGenerated":false},"oldTreeEntry":{"lineCount":0,"path":"src/port/qsort.c","mode":100644},"linesAdded":49,"linesDeleted":18,"path":"src/port/qsort.c","pathDigest":"d814c8d624316705ce09d3b1b7fba727a49abaaa4c0278c58c0a3fa9b0804ede","status":"MODIFIED","truncatedReason":null,"oldOid":"828df727a673d718265766611e59aa5189d102ba","newOid":"9d6077abf9d6efd992a59f05ef5aba981ea32096","copilotChatReference":null,"deletedSha":"828df727a673d718265766611e59aa5189d102ba","canToggleRichDiff":false,"defaultToRichDiff":false,"proseDifffHtml":null,"renderInfo":null,"dependencyDiffPath":null,"submodule":null},{"path":"src/port/qsort_arg.c","pathDigest":"df36e8b921cce98e2243856e28c69ce69e1dce3f8ff73fc694b43366863eb93e","status":"MODIFIED"}],"splitViewPreference":"unified","ignoreWhitespace":false,"repoOwnerGlobalRelayId":"MDEyOk9yZ2FuaXphdGlvbjE3NzU0Mw==","commentsPreference":"visible","diffLineSpacingPreference":"relaxed","useMonospaceFont":false,"pasteUrlLinkAsPlainText":false,"userNotices":[],"path":"/postgres/postgres/commit/9d6077abf9d6efd992a59f05ef5aba981ea32096","fileTreeExpanded":true,"headerInfo":{"additions":156,"deletions":60,"filesChanged":3,"filesChangedString":"3"},"moreDiffsToLoad":true,"asyncDiffLoadInfo":{"startIndex":2,"truncated":false,"byteCount":8762,"lineShownCount":297},"commentInfo":{"canComment":false,"locked":false,"canLock":false,"repoArchived":false},"csrf_tokens":{"/users/diffview?diff=split":{"post":"s27kXXEV34uJkVa-ibCCoI8EdXgwTiHX17lTIKCT4tg5MG9OIjW0sWBmWMtBKvYUDXwf3wrt45n4pcBpO6zcmQ"},"/users/diffview?diff=unified":{"post":"XOqMF-lxrenJu_cbz8-tnOMPqbwsgQmn8M4eyo-nl3HWtAcEulHG0yBM-W4HVdkoYXfDGxYiy-nf0o2DFJipMA"},"/notifications/thread":{"post":"nmTSfGC5G0ua5jqpKRmVFvM2Tn7CkZNmXGd5n8dlVDILhMFMJw63yHWL2TPWm88P39FuDOzi2Wa85qBuv-V0zQ"}}},"title":"Fix a low-probability crash in our qsort implementation. · postgres/postgres@9d6077a","appPayload":{"helpUrl":"https://docs.github.com","findInDiffWorkerPath":"/assets-cdn/worker/find-in-diff-worker-2bfe39677d14.js","enabled_features":{"diff_ux_refresh_beta":false,"diff_inline_comments":true,"diff_ux_refresh_ssr_five":false,"diff_ux_refresh_ssr_ten":false,"react_diff_line_type_character_correction":true}}}

Commit 9d6077a

Browse files
committed
Fix a low-probability crash in our qsort implementation.
It's standard for quicksort implementations, after having partitioned the input into two subgroups, to recurse to process the smaller partition and then handle the larger partition by iterating. This method guarantees that no more than log2(N) levels of recursion can be needed. However, Bentley and McIlroy argued that checking to see which partition is smaller isn't worth the cycles, and so their code doesn't do that but just always recurses on the left partition. In most cases that's fine; but with worst-case input we might need O(N) levels of recursion, and that means that qsort could be driven to stack overflow. Such an overflow seems to be the only explanation for today's report from Yiqing Jin of a SIGSEGV in med3_tuple while creating an index of a couple billion entries with a very large maintenance_work_mem setting. Therefore, let's spend the few additional cycles and lines of code needed to choose the smaller partition for recursion. Also, fix up the qsort code so that it properly uses size_t not int for some intermediate values representing numbers of items. This would only be a live risk when sorting more than INT_MAX bytes (in qsort/qsort_arg) or tuples (in qsort_tuple), which I believe would never happen with any caller in the current core code --- but perhaps it could happen with call sites in third-party modules? In any case, this is trouble waiting to happen, and the corrected code is probably if anything shorter and faster than before, since it removes sign-extension steps that had to happen when converting between int and size_t. In passing, move a couple of CHECK_FOR_INTERRUPTS() calls so that it's not necessary to preserve the value of "r" across them, and prettify the output of gen_qsort_tuple.pl a little. Back-patch to all supported branches. The odds of hitting this issue are probably higher in 9.4 and up than before, due to the new ability to allocate sort workspaces exceeding 1GB, but there's no good reason to believe that it's impossible to crash older branches this way.
1 parent 828df72 commit 9d6077a

File tree

3 files changed

+156
-60
lines changed

3 files changed

+156
-60
lines changed

src/backend/utils/sort/gen_qsort_tuple.pl

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,13 @@
1414
#
1515
# Modifications from vanilla NetBSD source:
1616
# Add do ... while() macro fix
17-
# Remove __inline, _DIAGASSERTs, __P
18-
# Remove ill-considered "swap_cnt" switch to insertion sort,
19-
# in favor of a simple check for presorted input.
20-
# Instead of sorting arbitrary objects, we're always sorting SortTuples
21-
# Add CHECK_FOR_INTERRUPTS()
17+
# Remove __inline, _DIAGASSERTs, __P
18+
# Remove ill-considered "swap_cnt" switch to insertion sort,
19+
# in favor of a simple check for presorted input.
20+
# Take care to recurse on the smaller partition, to bound stack usage.
21+
#
22+
# Instead of sorting arbitrary objects, we're always sorting SortTuples.
23+
# Add CHECK_FOR_INTERRUPTS().
2224
#
2325
# CAUTION: if you change this file, see also qsort.c and qsort_arg.c
2426
#
@@ -43,17 +45,20 @@
4345
$EXTRAPARAMS = ', ssup';
4446
$CMPPARAMS = ', ssup';
4547
print <<'EOM';
48+
4649
#define cmp_ssup(a, b, ssup) \
4750
ApplySortComparator((a)->datum1, (a)->isnull1, \
4851
(b)->datum1, (b)->isnull1, ssup)
52+
4953
EOM
5054
emit_qsort_implementation();
5155

5256
sub emit_qsort_boilerplate
5357
{
5458
print <<'EOM';
5559
/*
56-
* autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit
60+
* autogenerated by src/backend/utils/sort/gen_qsort_tuple.pl, do not edit!
61+
*
5762
* This file is included by tuplesort.c, rather than compiled separately.
5863
*/
5964
@@ -78,7 +83,7 @@ sub emit_qsort_boilerplate
7883
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
7984
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8085
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
81-
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
86+
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
8287
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
8388
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
8489
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
@@ -92,8 +97,16 @@ sub emit_qsort_boilerplate
9297
* Qsort routine based on J. L. Bentley and M. D. McIlroy,
9398
* "Engineering a sort function",
9499
* Software--Practice and Experience 23 (1993) 1249-1265.
100+
*
95101
* We have modified their original by adding a check for already-sorted input,
96102
* which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
103+
*
104+
* Also, we recurse on the smaller partition and iterate on the larger one,
105+
* which ensures we cannot recurse more than log(N) levels (since the
106+
* partition recursed to is surely no more than half of the input). Bentley
107+
* and McIlroy explicitly rejected doing this on the grounds that it's "not
108+
* worth the effort", but we have seen crashes in the field due to stack
109+
* overrun, so that judgment seems wrong.
97110
*/
98111
99112
static void
@@ -114,7 +127,8 @@ sub emit_qsort_boilerplate
114127
*(b) = t; \
115128
} while (0);
116129
117-
#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n))
130+
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n)
131+
118132
EOM
119133
}
120134

@@ -141,8 +155,9 @@ sub emit_qsort_implementation
141155
*pl,
142156
*pm,
143157
*pn;
144-
int d,
145-
r,
158+
size_t d1,
159+
d2;
160+
int r,
146161
presorted;
147162
148163
loop:
@@ -173,7 +188,8 @@ sub emit_qsort_implementation
173188
pn = a + (n - 1);
174189
if (n > 40)
175190
{
176-
d = (n / 8);
191+
size_t d = (n / 8);
192+
177193
pl = med3_$SUFFIX(pl, pl + d, pl + 2 * d$EXTRAPARAMS);
178194
pm = med3_$SUFFIX(pm - d, pm, pm + d$EXTRAPARAMS);
179195
pn = med3_$SUFFIX(pn - 2 * d, pn - d, pn$EXTRAPARAMS);
@@ -187,23 +203,23 @@ sub emit_qsort_implementation
187203
{
188204
while (pb <= pc && (r = cmp_$SUFFIX(pb, a$CMPPARAMS)) <= 0)
189205
{
190-
CHECK_FOR_INTERRUPTS();
191206
if (r == 0)
192207
{
193208
swap(pa, pb);
194209
pa++;
195210
}
196211
pb++;
212+
CHECK_FOR_INTERRUPTS();
197213
}
198214
while (pb <= pc && (r = cmp_$SUFFIX(pc, a$CMPPARAMS)) >= 0)
199215
{
200-
CHECK_FOR_INTERRUPTS();
201216
if (r == 0)
202217
{
203218
swap(pc, pd);
204219
pd--;
205220
}
206221
pc--;
222+
CHECK_FOR_INTERRUPTS();
207223
}
208224
if (pb > pc)
209225
break;
@@ -212,21 +228,39 @@ sub emit_qsort_implementation
212228
pc--;
213229
}
214230
pn = a + n;
215-
r = Min(pa - a, pb - pa);
216-
vecswap(a, pb - r, r);
217-
r = Min(pd - pc, pn - pd - 1);
218-
vecswap(pb, pn - r, r);
219-
if ((r = pb - pa) > 1)
220-
qsort_$SUFFIX(a, r$EXTRAPARAMS);
221-
if ((r = pd - pc) > 1)
231+
d1 = Min(pa - a, pb - pa);
232+
vecswap(a, pb - d1, d1);
233+
d1 = Min(pd - pc, pn - pd - 1);
234+
vecswap(pb, pn - d1, d1);
235+
d1 = pb - pa;
236+
d2 = pd - pc;
237+
if (d1 <= d2)
222238
{
223-
/* Iterate rather than recurse to save stack space */
224-
a = pn - r;
225-
n = r;
226-
goto loop;
239+
/* Recurse on left partition, then iterate on right partition */
240+
if (d1 > 1)
241+
qsort_$SUFFIX(a, d1$EXTRAPARAMS);
242+
if (d2 > 1)
243+
{
244+
/* Iterate rather than recurse to save stack space */
245+
/* qsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS); */
246+
a = pn - d2;
247+
n = d2;
248+
goto loop;
249+
}
250+
}
251+
else
252+
{
253+
/* Recurse on right partition, then iterate on left partition */
254+
if (d2 > 1)
255+
qsort_$SUFFIX(pn - d2, d2$EXTRAPARAMS);
256+
if (d1 > 1)
257+
{
258+
/* Iterate rather than recurse to save stack space */
259+
/* qsort_$SUFFIX(a, d1$EXTRAPARAMS); */
260+
n = d1;
261+
goto loop;
262+
}
227263
}
228-
/* qsort_$SUFFIX(pn - r, r$EXTRAPARAMS);*/
229264
}
230-
231265
EOM
232266
}

src/port/qsort.c

Lines changed: 49 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Remove __inline, _DIAGASSERTs, __P
77
* Remove ill-considered "swap_cnt" switch to insertion sort,
88
* in favor of a simple check for presorted input.
9+
* Take care to recurse on the smaller partition, to bound stack usage.
910
*
1011
* CAUTION: if you change this file, see also qsort_arg.c, gen_qsort_tuple.pl
1112
*
@@ -54,9 +55,18 @@ static void swapfunc(char *, char *, size_t, int);
5455
* Qsort routine based on J. L. Bentley and M. D. McIlroy,
5556
* "Engineering a sort function",
5657
* Software--Practice and Experience 23 (1993) 1249-1265.
58+
*
5759
* We have modified their original by adding a check for already-sorted input,
5860
* which seems to be a win per discussions on pgsql-hackers around 2006-03-21.
61+
*
62+
* Also, we recurse on the smaller partition and iterate on the larger one,
63+
* which ensures we cannot recurse more than log(N) levels (since the
64+
* partition recursed to is surely no more than half of the input). Bentley
65+
* and McIlroy explicitly rejected doing this on the grounds that it's "not
66+
* worth the effort", but we have seen crashes in the field due to stack
67+
* overrun, so that judgment seems wrong.
5968
*/
69+
6070
#define swapcode(TYPE, parmi, parmj, n) \
6171
do { \
6272
size_t i = (n) / sizeof (TYPE); \
@@ -89,7 +99,7 @@ swapfunc(char *a, char *b, size_t n, int swaptype)
8999
} else \
90100
swapfunc(a, b, es, swaptype)
91101

92-
#define vecswap(a, b, n) if ((n) > 0) swapfunc((a), (b), (size_t)(n), swaptype)
102+
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
93103

94104
static char *
95105
med3(char *a, char *b, char *c, int (*cmp) (const void *, const void *))
@@ -109,8 +119,9 @@ pg_qsort(void *a, size_t n, size_t es, int (*cmp) (const void *, const void *))
109119
*pl,
110120
*pm,
111121
*pn;
112-
int d,
113-
r,
122+
size_t d1,
123+
d2;
124+
int r,
114125
swaptype,
115126
presorted;
116127

@@ -141,7 +152,8 @@ loop:SWAPINIT(a, es);
141152
pn = (char *) a + (n - 1) * es;
142153
if (n > 40)
143154
{
144-
d = (n / 8) * es;
155+
size_t d = (n / 8) * es;
156+
145157
pl = med3(pl, pl + d, pl + 2 * d, cmp);
146158
pm = med3(pm - d, pm, pm + d, cmp);
147159
pn = med3(pn - 2 * d, pn - d, pn, cmp);
@@ -178,27 +190,46 @@ loop:SWAPINIT(a, es);
178190
pc -= es;
179191
}
180192
pn = (char *) a + n * es;
181-
r = Min(pa - (char *) a, pb - pa);
182-
vecswap(a, pb - r, r);
183-
r = Min(pd - pc, pn - pd - es);
184-
vecswap(pb, pn - r, r);
185-
if ((r = pb - pa) > es)
186-
qsort(a, r / es, es, cmp);
187-
if ((r = pd - pc) > es)
193+
d1 = Min(pa - (char *) a, pb - pa);
194+
vecswap(a, pb - d1, d1);
195+
d1 = Min(pd - pc, pn - pd - es);
196+
vecswap(pb, pn - d1, d1);
197+
d1 = pb - pa;
198+
d2 = pd - pc;
199+
if (d1 <= d2)
188200
{
189-
/* Iterate rather than recurse to save stack space */
190-
a = pn - r;
191-
n = r / es;
192-
goto loop;
201+
/* Recurse on left partition, then iterate on right partition */
202+
if (d1 > es)
203+
pg_qsort(a, d1 / es, es, cmp);
204+
if (d2 > es)
205+
{
206+
/* Iterate rather than recurse to save stack space */
207+
/* pg_qsort(pn - d2, d2 / es, es, cmp); */
208+
a = pn - d2;
209+
n = d2 / es;
210+
goto loop;
211+
}
212+
}
213+
else
214+
{
215+
/* Recurse on right partition, then iterate on left partition */
216+
if (d2 > es)
217+
pg_qsort(pn - d2, d2 / es, es, cmp);
218+
if (d1 > es)
219+
{
220+
/* Iterate rather than recurse to save stack space */
221+
/* pg_qsort(a, d1 / es, es, cmp); */
222+
n = d1 / es;
223+
goto loop;
224+
}
193225
}
194-
/* qsort(pn - r, r / es, es, cmp);*/
195226
}
196227

197228
/*
198-
* qsort wrapper for strcmp.
229+
* qsort comparator wrapper for strcmp.
199230
*/
200231
int
201232
pg_qsort_strcmp(const void *a, const void *b)
202233
{
203-
return strcmp(*(char *const *) a, *(char *const *) b);
234+
return strcmp(*(const char *const *) a, *(const char *const *) b);
204235
}

0 commit comments

Comments
 (0)
0