xpcom/glue/nsQuickSort.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     3 /*-
     4  * Copyright (c) 1992, 1993
     5  *	The Regents of the University of California.  All rights reserved.
     6  *
     7  * Redistribution and use in source and binary forms, with or without
     8  * modification, are permitted provided that the following conditions
     9  * are met:
    10  * 1. Redistributions of source code must retain the above copyright
    11  *    notice, this list of conditions and the following disclaimer.
    12  * 2. Redistributions in binary form must reproduce the above copyright
    13  *    notice, this list of conditions and the following disclaimer in the
    14  *    documentation and/or other materials provided with the distribution.
    15  * 3. Neither the name of the University nor the names of its contributors
    16  *    may be used to endorse or promote products derived from this software
    17  *    without specific prior written permission.
    18  *
    19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
    20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
    23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
    25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
    28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
    29  * SUCH DAMAGE.
    30  */
    32 /* We need this because Solaris' version of qsort is broken and
    33  * causes array bounds reads.
    34  */
    36 #include <stdlib.h>
    37 #include "nsAlgorithm.h"
    38 #include "nsQuickSort.h"
    40 extern "C" {
    42 #if !defined(DEBUG) && (defined(__cplusplus) || defined(__gcc))
    43 # ifndef INLINE
    44 #  define INLINE inline
    45 # endif
    46 #else
    47 # define INLINE
    48 #endif
    50 typedef int		 cmp_t(const void *, const void *, void *);
    51 static INLINE char	*med3(char *, char *, char *, cmp_t *, void *);
    52 static INLINE void	swapfunc(char *, char *, int, int);
    54 /*
    55  * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
    56  */
    57 #define swapcode(TYPE, parmi, parmj, n) { 		\
    58 	long i = (n) / sizeof (TYPE); 			\
    59 	TYPE *pi = (TYPE *) (parmi); 			\
    60 	TYPE *pj = (TYPE *) (parmj); 			\
    61 	do { 						\
    62 		TYPE	t = *pi;			\
    63 		*pi++ = *pj;				\
    64 		*pj++ = t;				\
    65         } while (--i > 0);				\
    66 }
    68 #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
    69 	es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
    71 static INLINE void
    72 swapfunc(char *a, char *b, int n, int swaptype)
    73 {
    74 	if(swaptype <= 1)
    75 		swapcode(long, a, b, n)
    76 	else
    77 		swapcode(char, a, b, n)
    78 }
    80 #define swap(a, b)					\
    81 	if (swaptype == 0) {				\
    82 		long t = *(long *)(a);			\
    83 		*(long *)(a) = *(long *)(b);		\
    84 		*(long *)(b) = t;			\
    85 	} else						\
    86 		swapfunc((char *)a, (char*)b, (int)es, swaptype)
    88 #define vecswap(a, b, n) 	if ((n) > 0) swapfunc((char *)a, (char *)b, (int)n, swaptype)
    90 static INLINE char *
    91 med3(char *a, char *b, char *c, cmp_t* cmp, void *data)
    92 {
    93 	return cmp(a, b, data) < 0 ?
    94 	       (cmp(b, c, data) < 0 ? b : (cmp(a, c, data) < 0 ? c : a ))
    95               :(cmp(b, c, data) > 0 ? b : (cmp(a, c, data) < 0 ? a : c ));
    96 }
    98 void NS_QuickSort (
    99 	void *a,
   100 	unsigned int n,
   101     unsigned int es,
   102 	cmp_t *cmp,
   103 	void *data
   104     )
   105 {
   106 	char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
   107 	int d, r, swaptype;
   109 loop:	SWAPINIT(a, es);
   110 	/* Use insertion sort when input is small */
   111 	if (n < 7) {
   112 		for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
   113 			for (pl = pm; pl > (char *)a && cmp(pl - es, pl, data) > 0;
   114 			     pl -= es)
   115 				swap(pl, pl - es);
   116 		return;
   117 	}
   118 	/* Choose pivot */
   119 	pm = (char *)a + (n / 2) * es;
   120 	if (n > 7) {
   121 		pl = (char *)a;
   122 		pn = (char *)a + (n - 1) * es;
   123 		if (n > 40) {
   124 			d = (n / 8) * es;
   125 			pl = med3(pl, pl + d, pl + 2 * d, cmp, data);
   126 			pm = med3(pm - d, pm, pm + d, cmp, data);
   127 			pn = med3(pn - 2 * d, pn - d, pn, cmp, data);
   128 		}
   129 		pm = med3(pl, pm, pn, cmp, data);
   130 	}
   131 	swap(a, pm);
   132 	pa = pb = (char *)a + es;
   134 	pc = pd = (char *)a + (n - 1) * es;
   135 	/* loop invariants:
   136 	 * [a, pa) = pivot
   137 	 * [pa, pb) < pivot
   138 	 * [pb, pc + es) unprocessed
   139 	 * [pc + es, pd + es) > pivot
   140 	 * [pd + es, pn) = pivot
   141 	 */
   142 	for (;;) {
   143 		while (pb <= pc && (r = cmp(pb, a, data)) <= 0) {
   144 			if (r == 0) {
   145 				swap(pa, pb);
   146 				pa += es;
   147 			}
   148 			pb += es;
   149 		}
   150 		while (pb <= pc && (r = cmp(pc, a, data)) >= 0) {
   151 			if (r == 0) {
   152 				swap(pc, pd);
   153 				pd -= es;
   154 			}
   155 			pc -= es;
   156 		}
   157 		if (pb > pc)
   158 			break;
   159 		swap(pb, pc);
   160 		pb += es;
   161 		pc -= es;
   162 	}
   163 	/* Move pivot values */
   164 	pn = (char *)a + n * es;
   165 	r = XPCOM_MIN(pa - (char *)a, pb - pa);
   166 	vecswap(a, pb - r, r);
   167 	r = XPCOM_MIN<size_t>(pd - pc, pn - pd - es);
   168 	vecswap(pb, pn - r, r);
   169 	/* Recursively process partitioned items */
   170 	if ((r = pb - pa) > (int)es)
   171         NS_QuickSort(a, r / es, es, cmp, data);
   172 	if ((r = pd - pc) > (int)es) {
   173 		/* Iterate rather than recurse to save stack space */
   174 		a = pn - r;
   175 		n = r / es;
   176 		goto loop;
   177 	}
   178 /*		NS_QuickSort(pn - r, r / es, es, cmp, data);*/
   179 }
   181 }
   183 #undef INLINE
   184 #undef swapcode
   185 #undef SWAPINIT
   186 #undef swap
   187 #undef vecswap

mercurial