summaryrefslogtreecommitdiff
path: root/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch
diff options
context:
space:
mode:
authorRobin H. Johnson <robbat2@gentoo.org>2015-08-08 13:49:04 -0700
committerRobin H. Johnson <robbat2@gentoo.org>2015-08-08 17:38:18 -0700
commit56bd759df1d0c750a065b8c845e93d5dfa6b549d (patch)
tree3f91093cdb475e565ae857f1c5a7fd339e2d781e /dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch
downloadgentoo-56bd759df1d0c750a065b8c845e93d5dfa6b549d.tar.gz
gentoo-56bd759df1d0c750a065b8c845e93d5dfa6b549d.tar.xz
proj/gentoo: Initial commit
This commit represents a new era for Gentoo: Storing the gentoo-x86 tree in Git, as converted from CVS. This commit is the start of the NEW history. Any historical data is intended to be grafted onto this point. Creation process: 1. Take final CVS checkout snapshot 2. Remove ALL ChangeLog* files 3. Transform all Manifests to thin 4. Remove empty Manifests 5. Convert all stale $Header$/$Id$ CVS keywords to non-expanded Git $Id$ 5.1. Do not touch files with -kb/-ko keyword flags. Signed-off-by: Robin H. Johnson <robbat2@gentoo.org> X-Thanks: Alec Warner <antarus@gentoo.org> - did the GSoC 2006 migration tests X-Thanks: Robin H. Johnson <robbat2@gentoo.org> - infra guy, herding this project X-Thanks: Nguyen Thai Ngoc Duy <pclouds@gentoo.org> - Former Gentoo developer, wrote Git features for the migration X-Thanks: Brian Harring <ferringb@gentoo.org> - wrote much python to improve cvs2svn X-Thanks: Rich Freeman <rich0@gentoo.org> - validation scripts X-Thanks: Patrick Lauer <patrick@gentoo.org> - Gentoo dev, running new 2014 work in migration X-Thanks: Michał Górny <mgorny@gentoo.org> - scripts, QA, nagging X-Thanks: All of other Gentoo developers - many ideas and lots of paint on the bikeshed
Diffstat (limited to 'dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch')
-rw-r--r--dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch128
1 files changed, 128 insertions, 0 deletions
diff --git a/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch b/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch
new file mode 100644
index 00000000000..c179d47ef2d
--- /dev/null
+++ b/dev-libs/libxml2/files/libxml2-2.9.2-timsort.patch
@@ -0,0 +1,128 @@
+From 9b987f8c98763ee569bde90b5268b43474ca106c Mon Sep 17 00:00:00 2001
+From: Christopher Swenson <chris@caswenson.com>
+Date: Fri, 27 Feb 2015 14:55:49 +0800
+Subject: [PATCH] Fix timsort invariant loop re: Envisage article
+
+See http://envisage-project.eu/proving-android-java-and-python-sorting-algorithm-is-broken-and-how-to-fix-it/
+
+We use a "runLen" array of size 128, so it should be nearly impossible
+to have our implementation overflow.
+
+But in any case, the fix is relatively simple -- checking two extra
+conditions in the invariant calculation.
+
+I also took this opportunity to remove some redundancy in the
+left/right merge logic in the invariant loop.
+---
+ timsort.h | 74 +++++++++++++++++++++++++++++++++------------------------------
+ 1 file changed, 39 insertions(+), 35 deletions(-)
+
+diff --git a/timsort.h b/timsort.h
+index efa3aab..795f272 100644
+--- a/timsort.h
++++ b/timsort.h
+@@ -392,62 +392,66 @@ static void TIM_SORT_MERGE(SORT_TYPE *dst, const TIM_SORT_RUN_T *stack, const in
+
+ static int TIM_SORT_COLLAPSE(SORT_TYPE *dst, TIM_SORT_RUN_T *stack, int stack_curr, TEMP_STORAGE_T *store, const size_t size)
+ {
+- while (1)
+- {
+- int64_t A, B, C;
++ while (1) {
++ int64_t A, B, C, D;
++ int ABC, BCD, BD, CD;
++
+ /* if the stack only has one thing on it, we are done with the collapse */
+- if (stack_curr <= 1) break;
++ if (stack_curr <= 1) {
++ break;
++ }
++
+ /* if this is the last merge, just do it */
+- if ((stack_curr == 2) &&
+- (stack[0].length + stack[1].length == (int64_t) size))
+- {
++ if ((stack_curr == 2) && (stack[0].length + stack[1].length == size)) {
+ TIM_SORT_MERGE(dst, stack, stack_curr, store);
+ stack[0].length += stack[1].length;
+ stack_curr--;
+ break;
+ }
+ /* check if the invariant is off for a stack of 2 elements */
+- else if ((stack_curr == 2) && (stack[0].length <= stack[1].length))
+- {
++ else if ((stack_curr == 2) && (stack[0].length <= stack[1].length)) {
+ TIM_SORT_MERGE(dst, stack, stack_curr, store);
+ stack[0].length += stack[1].length;
+ stack_curr--;
+ break;
+- }
+- else if (stack_curr == 2)
++ } else if (stack_curr == 2) {
+ break;
++ }
+
+- A = stack[stack_curr - 3].length;
+- B = stack[stack_curr - 2].length;
+- C = stack[stack_curr - 1].length;
++ B = stack[stack_curr - 3].length;
++ C = stack[stack_curr - 2].length;
++ D = stack[stack_curr - 1].length;
+
+- /* check first invariant */
+- if (A <= B + C)
+- {
+- if (A < C)
+- {
+- TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
+- stack[stack_curr - 3].length += stack[stack_curr - 2].length;
+- stack[stack_curr - 2] = stack[stack_curr - 1];
+- stack_curr--;
+- }
+- else
+- {
+- TIM_SORT_MERGE(dst, stack, stack_curr, store);
+- stack[stack_curr - 2].length += stack[stack_curr - 1].length;
+- stack_curr--;
+- }
++ if (stack_curr >= 4) {
++ A = stack[stack_curr - 4].length;
++ ABC = (A <= B + C);
++ } else {
++ ABC = 0;
+ }
+- /* check second invariant */
+- else if (B <= C)
+- {
++
++ BCD = (B <= C + D) || ABC;
++ CD = (C <= D);
++ BD = (B < D);
++
++ /* Both invariants are good */
++ if (!BCD && !CD) {
++ break;
++ }
++
++ /* left merge */
++ if (BCD && !CD) {
++ TIM_SORT_MERGE(dst, stack, stack_curr - 1, store);
++ stack[stack_curr - 3].length += stack[stack_curr - 2].length;
++ stack[stack_curr - 2] = stack[stack_curr - 1];
++ stack_curr--;
++ } else {
++ /* right merge */
+ TIM_SORT_MERGE(dst, stack, stack_curr, store);
+ stack[stack_curr - 2].length += stack[stack_curr - 1].length;
+ stack_curr--;
+ }
+- else
+- break;
+ }
++
+ return stack_curr;
+ }
+
+--
+2.3.5
+