annotate liboctave/oct-sort.cc @ 8678:e2b4c19c455c

redo changeset 4238f2600a17 with fixes to sorting
author Jaroslav Hajek <highegg@gmail.com>
date Wed, 04 Feb 2009 16:05:01 +0100
parents 0168d22e6bba
children 314be237cd5b
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
1 /*
7017
a1dbe9d80eee [project @ 2007-10-12 21:27:11 by jwe]
jwe
parents: 7016
diff changeset
2 Copyright (C) 2003, 2004, 2005, 2006, 2007 David Bateman
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
3 Copyright (C) 2008 Jaroslav Hajek
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
4
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
5 This file is part of Octave.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
6
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
7 Octave is free software; you can redistribute it and/or modify it
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
8 under the terms of the GNU General Public License as published by the
7016
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6959
diff changeset
9 Free Software Foundation; either version 3 of the License, or (at your
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6959
diff changeset
10 option) any later version.
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
11
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
12 Octave is distributed in the hope that it will be useful, but WITHOUT
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
15 for more details.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
16
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
7016
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6959
diff changeset
18 along with Octave; see the file COPYING. If not, see
93c65f2a5668 [project @ 2007-10-12 06:40:56 by jwe]
jwe
parents: 6959
diff changeset
19 <http://www.gnu.org/licenses/>.
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
20
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
21 Code stolen in large part from Python's, listobject.c, which itself had
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
22 no license header. However, thanks to Tim Peters for the parts of the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
23 code I ripped-off.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
24
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
25 As required in the Python license the short description of the changes
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
26 made are
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
27
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
28 * convert the sorting code in listobject.cc into a generic class,
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
29 replacing PyObject* with the type of the class T.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
30
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
31 * replaced usages of malloc, free, memcpy and memmove by standard C++
8678
e2b4c19c455c redo changeset 4238f2600a17 with fixes to sorting
Jaroslav Hajek <highegg@gmail.com>
parents: 8206
diff changeset
32 new [], delete [] and std::copy and std::copy_backward. Note that replacing
e2b4c19c455c redo changeset 4238f2600a17 with fixes to sorting
Jaroslav Hajek <highegg@gmail.com>
parents: 8206
diff changeset
33 memmove by std::copy is possible if the destination starts before the source.
e2b4c19c455c redo changeset 4238f2600a17 with fixes to sorting
Jaroslav Hajek <highegg@gmail.com>
parents: 8206
diff changeset
34 If not, std::copy_backward needs to be used.
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
35
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
36
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
37 The Python license is
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
38
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
39 PSF LICENSE AGREEMENT FOR PYTHON 2.3
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
40 --------------------------------------
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
41
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
42 1. This LICENSE AGREEMENT is between the Python Software Foundation
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
43 ("PSF"), and the Individual or Organization ("Licensee") accessing and
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
44 otherwise using Python 2.3 software in source or binary form and its
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
45 associated documentation.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
46
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
47 2. Subject to the terms and conditions of this License Agreement, PSF
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
48 hereby grants Licensee a nonexclusive, royalty-free, world-wide
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
49 license to reproduce, analyze, test, perform and/or display publicly,
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
50 prepare derivative works, distribute, and otherwise use Python 2.3
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
51 alone or in any derivative version, provided, however, that PSF's
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
52 License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
53 2001, 2002, 2003 Python Software Foundation; All Rights Reserved" are
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
54 retained in Python 2.3 alone or in any derivative version prepared by
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
55 Licensee.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
56
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
57 3. In the event Licensee prepares a derivative work that is based on
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
58 or incorporates Python 2.3 or any part thereof, and wants to make
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
59 the derivative work available to others as provided herein, then
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
60 Licensee hereby agrees to include in any such work a brief summary of
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
61 the changes made to Python 2.3.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
62
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
63 4. PSF is making Python 2.3 available to Licensee on an "AS IS"
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
64 basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
65 IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
66 DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
67 FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 2.3 WILL NOT
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
68 INFRINGE ANY THIRD PARTY RIGHTS.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
69
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
70 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
71 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
72 A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3,
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
73 OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
74
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
75 6. This License Agreement will automatically terminate upon a material
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
76 breach of its terms and conditions.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
77
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
78 7. Nothing in this License Agreement shall be deemed to create any
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
79 relationship of agency, partnership, or joint venture between PSF and
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
80 Licensee. This License Agreement does not grant permission to use PSF
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
81 trademarks or trade name in a trademark sense to endorse or promote
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
82 products or services of Licensee, or any third party.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
83
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
84 8. By copying, installing or otherwise using Python 2.3, Licensee
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
85 agrees to be bound by the terms and conditions of this License
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
86 Agreement.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
87 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
88
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
89 #ifdef HAVE_CONFIG_H
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
90 #include <config.h>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
91 #endif
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
92
5883
1de9a198a303 [project @ 2006-07-14 18:10:30 by jwe]
jwe
parents: 5760
diff changeset
93 #include <cassert>
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
94 #include <algorithm>
7480
93826ba0d078 compilation fixes
Jason Riedy
parents: 7433
diff changeset
95 #include <cstring>
5883
1de9a198a303 [project @ 2006-07-14 18:10:30 by jwe]
jwe
parents: 5760
diff changeset
96
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
97 #include "lo-mappers.h"
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
98 #include "quit.h"
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
99 #include "oct-sort.h"
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
100
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
101 #ifndef IFLT
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
102 #define IFLT(a,b) if (compare ? compare ((a), (b)) : ((a) < (b)))
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
103 #endif
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
104
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
105 template <class T>
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
106 octave_sort<T>::octave_sort (void) : compare (0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
107 {
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
108 merge_init ();
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
109 merge_getmem (1024);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
110 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
111
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
112 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
113 octave_sort<T>::octave_sort (bool (*comp) (T, T)) : compare (comp)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
114 {
4998
3f3d6eec0a2c [project @ 2004-09-15 21:00:01 by jwe]
jwe
parents: 4882
diff changeset
115 merge_init ();
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
116 merge_getmem (1024);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
117 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
118
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
119 /* Reverse a slice of a list in place, from lo up to (exclusive) hi. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
120 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
121 void
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
122 octave_sort<T>::reverse_slice (T *lo, T *hi)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
123 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
124 --hi;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
125 while (lo < hi)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
126 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
127 T t = *lo;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
128 *lo = *hi;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
129 *hi = t;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
130 ++lo;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
131 --hi;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
132 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
133 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
134
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
135 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
136 void
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
137 octave_sort<T>::binarysort (T *lo, T *hi, T *start)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
138 {
6959
47f4f4e88166 [project @ 2007-10-04 20:43:32 by jwe]
jwe
parents: 6482
diff changeset
139 T *l, *p, *r;
47f4f4e88166 [project @ 2007-10-04 20:43:32 by jwe]
jwe
parents: 6482
diff changeset
140 T pivot;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
141
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
142 if (lo == start)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
143 ++start;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
144
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
145 for (; start < hi; ++start)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
146 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
147 /* set l to where *start belongs */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
148 l = lo;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
149 r = start;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
150 pivot = *r;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
151 /* Invariants:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
152 * pivot >= all in [lo, l).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
153 * pivot < all in [r, start).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
154 * The second is vacuously true at the start.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
155 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
156 do
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
157 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
158 p = l + ((r - l) >> 1);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
159 IFLT (pivot, *p)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
160 r = p;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
161 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
162 l = p+1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
163 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
164 while (l < r);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
165 /* The invariants still hold, so pivot >= all in [lo, l) and
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
166 pivot < all in [l, start), so pivot belongs at l. Note
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
167 that if there are elements equal to pivot, l points to the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
168 first slot after them -- that's why this sort is stable.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
169 Slide over to make room.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
170 Caution: using memmove is much slower under MSVC 5;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
171 we're not usually moving many slots. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
172 for (p = start; p > l; --p)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
173 *p = *(p-1);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
174 *l = pivot;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
175 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
176
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
177 return;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
178 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
179
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
180 /*
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
181 Return the length of the run beginning at lo, in the slice [lo, hi). lo < hi
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
182 is required on entry. "A run" is the longest ascending sequence, with
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
183
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
184 lo[0] <= lo[1] <= lo[2] <= ...
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
185
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
186 or the longest descending sequence, with
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
187
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
188 lo[0] > lo[1] > lo[2] > ...
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
189
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
190 DESCENDING is set to false in the former case, or to true in the latter.
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
191 For its intended use in a stable mergesort, the strictness of the defn of
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
192 "descending" is needed so that the caller can safely reverse a descending
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
193 sequence without violating stability (strict > ensures there are no equal
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
194 elements to get out of order).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
195
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
196 Returns -1 in case of error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
197 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
198 template <class T>
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
199 octave_idx_type
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
200 octave_sort<T>::count_run (T *lo, T *hi, bool& descending)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
201 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
202 octave_idx_type n;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
203
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
204 descending = false;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
205 ++lo;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
206 if (lo == hi)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
207 return 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
208
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
209 n = 2;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
210
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
211 IFLT (*lo, *(lo-1))
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
212 {
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
213 descending = true;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
214 for (lo = lo+1; lo < hi; ++lo, ++n)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
215 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
216 IFLT (*lo, *(lo-1))
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
217 ;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
218 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
219 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
220 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
221 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
222 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
223 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
224 for (lo = lo+1; lo < hi; ++lo, ++n)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
225 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
226 IFLT (*lo, *(lo-1))
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
227 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
228 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
229 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
230
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
231 return n;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
232 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
233
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
234 /*
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
235 Locate the proper position of key in a sorted vector; if the vector contains
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
236 an element equal to key, return the position immediately to the left of
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
237 the leftmost equal element. [gallop_right() does the same except returns
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
238 the position to the right of the rightmost equal element (if any).]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
239
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
240 "a" is a sorted vector with n elements, starting at a[0]. n must be > 0.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
241
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
242 "hint" is an index at which to begin the search, 0 <= hint < n. The closer
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
243 hint is to the final result, the faster this runs.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
244
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
245 The return value is the int k in 0..n such that
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
246
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
247 a[k-1] < key <= a[k]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
248
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
249 pretending that *(a-1) is minus infinity and a[n] is plus infinity. IOW,
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
250 key belongs at index k; or, IOW, the first k elements of a should precede
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
251 key, and the last n-k should follow key.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
252
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
253 Returns -1 on error. See listsort.txt for info on the method.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
254 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
255 template <class T>
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
256 octave_idx_type
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
257 octave_sort<T>::gallop_left (T key, T *a, octave_idx_type n, octave_idx_type hint)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
258 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
259 octave_idx_type ofs;
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
260 octave_idx_type lastofs;
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
261 octave_idx_type k;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
262
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
263 a += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
264 lastofs = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
265 ofs = 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
266 IFLT (*a, key)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
267 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
268 /* a[hint] < key -- gallop right, until
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
269 * a[hint + lastofs] < key <= a[hint + ofs]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
270 */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
271 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
272 while (ofs < maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
273 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
274 IFLT (a[ofs], key)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
275 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
276 lastofs = ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
277 ofs = (ofs << 1) + 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
278 if (ofs <= 0) /* int overflow */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
279 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
280 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
281 else /* key <= a[hint + ofs] */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
282 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
283 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
284 if (ofs > maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
285 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
286 /* Translate back to offsets relative to &a[0]. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
287 lastofs += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
288 ofs += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
289 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
290 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
291 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
292 /* key <= a[hint] -- gallop left, until
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
293 * a[hint - ofs] < key <= a[hint - lastofs]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
294 */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
295 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
296 while (ofs < maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
297 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
298 IFLT (*(a-ofs), key)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
299 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
300 /* key <= a[hint - ofs] */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
301 lastofs = ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
302 ofs = (ofs << 1) + 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
303 if (ofs <= 0) /* int overflow */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
304 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
305 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
306 if (ofs > maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
307 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
308 /* Translate back to positive offsets relative to &a[0]. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
309 k = lastofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
310 lastofs = hint - ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
311 ofs = hint - k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
312 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
313 a -= hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
314
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
315 /* Now a[lastofs] < key <= a[ofs], so key belongs somewhere to the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
316 * right of lastofs but no farther right than ofs. Do a binary
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
317 * search, with invariant a[lastofs-1] < key <= a[ofs].
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
318 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
319 ++lastofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
320 while (lastofs < ofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
321 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
322 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
323
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
324 IFLT (a[m], key)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
325 lastofs = m+1; /* a[m] < key */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
326 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
327 ofs = m; /* key <= a[m] */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
328 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
329
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
330 return ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
331 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
332
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
333 /*
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
334 Exactly like gallop_left(), except that if key already exists in a[0:n],
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
335 finds the position immediately to the right of the rightmost equal value.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
336
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
337 The return value is the int k in 0..n such that
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
338
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
339 a[k-1] <= key < a[k]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
340
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
341 or -1 if error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
342
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
343 The code duplication is massive, but this is enough different given that
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
344 we're sticking to "<" comparisons that it's much harder to follow if
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
345 written as one routine with yet another "left or right?" flag.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
346 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
347 template <class T>
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
348 octave_idx_type
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
349 octave_sort<T>::gallop_right (T key, T *a, octave_idx_type n, octave_idx_type hint)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
350 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
351 octave_idx_type ofs;
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
352 octave_idx_type lastofs;
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
353 octave_idx_type k;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
354
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
355 a += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
356 lastofs = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
357 ofs = 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
358 IFLT (key, *a)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
359 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
360 /* key < a[hint] -- gallop left, until
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
361 * a[hint - ofs] <= key < a[hint - lastofs]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
362 */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
363 const octave_idx_type maxofs = hint + 1; /* &a[0] is lowest */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
364 while (ofs < maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
365 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
366 IFLT (key, *(a-ofs))
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
367 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
368 lastofs = ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
369 ofs = (ofs << 1) + 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
370 if (ofs <= 0) /* int overflow */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
371 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
372 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
373 else /* a[hint - ofs] <= key */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
374 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
375 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
376 if (ofs > maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
377 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
378 /* Translate back to positive offsets relative to &a[0]. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
379 k = lastofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
380 lastofs = hint - ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
381 ofs = hint - k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
382 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
383 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
384 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
385 /* a[hint] <= key -- gallop right, until
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
386 * a[hint + lastofs] <= key < a[hint + ofs]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
387 */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
388 const octave_idx_type maxofs = n - hint; /* &a[n-1] is highest */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
389 while (ofs < maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
390 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
391 IFLT (key, a[ofs])
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
392 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
393 /* a[hint + ofs] <= key */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
394 lastofs = ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
395 ofs = (ofs << 1) + 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
396 if (ofs <= 0) /* int overflow */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
397 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
398 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
399 if (ofs > maxofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
400 ofs = maxofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
401 /* Translate back to offsets relative to &a[0]. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
402 lastofs += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
403 ofs += hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
404 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
405 a -= hint;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
406
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
407 /* Now a[lastofs] <= key < a[ofs], so key belongs somewhere to the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
408 * right of lastofs but no farther right than ofs. Do a binary
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
409 * search, with invariant a[lastofs-1] <= key < a[ofs].
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
410 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
411 ++lastofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
412 while (lastofs < ofs)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
413 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
414 octave_idx_type m = lastofs + ((ofs - lastofs) >> 1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
415
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
416 IFLT (key, a[m])
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
417 ofs = m; /* key < a[m] */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
418 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
419 lastofs = m+1; /* a[m] <= key */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
420 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
421
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
422 return ofs;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
423 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
424
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
425 /* Conceptually a MergeState's constructor. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
426 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
427 void
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
428 octave_sort<T>::merge_init (void)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
429 {
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
430 ms.a = 0;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
431 ms.alloced = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
432 ms.n = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
433 ms.min_gallop = MIN_GALLOP;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
434 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
435
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
436 /* Free all the temp memory owned by the MergeState. This must be called
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
437 * when you're done with a MergeState, and may be called before then if
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
438 * you want to free the temp memory early.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
439 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
440 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
441 void
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
442 octave_sort<T>::merge_freemem (void)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
443 {
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
444 delete [] ms.a;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
445 ms.alloced = 0;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
446 ms.a = 0;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
447 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
448
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
449 static inline octave_idx_type
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
450 roundupsize (octave_idx_type n)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
451 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
452 unsigned int nbits = 3;
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
453 octave_idx_type n2 = static_cast<octave_idx_type> (n) >> 8;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
454
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
455 /* Round up:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
456 * If n < 256, to a multiple of 8.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
457 * If n < 2048, to a multiple of 64.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
458 * If n < 16384, to a multiple of 512.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
459 * If n < 131072, to a multiple of 4096.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
460 * If n < 1048576, to a multiple of 32768.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
461 * If n < 8388608, to a multiple of 262144.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
462 * If n < 67108864, to a multiple of 2097152.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
463 * If n < 536870912, to a multiple of 16777216.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
464 * ...
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
465 * If n < 2**(5+3*i), to a multiple of 2**(3*i).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
466 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
467 * This over-allocates proportional to the list size, making room
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
468 * for additional growth. The over-allocation is mild, but is
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
469 * enough to give linear-time amortized behavior over a long
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
470 * sequence of appends() in the presence of a poorly-performing
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
471 * system realloc() (which is a reality, e.g., across all flavors
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
472 * of Windows, with Win9x behavior being particularly bad -- and
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
473 * we've still got address space fragmentation problems on Win9x
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
474 * even with this scheme, although it requires much longer lists to
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
475 * provoke them than it used to).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
476 */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
477 while (n2)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
478 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
479 n2 >>= 3;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
480 nbits += 3;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
481 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
482
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
483 return ((n >> nbits) + 1) << nbits;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
484 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
485
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
486 /* Ensure enough temp memory for 'need' array slots is available.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
487 * Returns 0 on success and -1 if the memory can't be gotten.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
488 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
489 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
490 int
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
491 octave_sort<T>::merge_getmem (octave_idx_type need)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
492 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
493 if (need <= ms.alloced)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
494 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
495
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
496 need = roundupsize (need);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
497 /* Don't realloc! That can cost cycles to copy the old data, but
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
498 * we don't care what's in the block.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
499 */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
500 merge_freemem ();
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
501 ms.a = new T[need];
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
502 if (ms.a)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
503 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
504 ms.alloced = need;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
505 return 0;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
506 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
507 merge_freemem (); /* reset to sane state */
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
508
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
509 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
510 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
511
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
512 #define MERGE_GETMEM(NEED) ((NEED) <= ms.alloced ? 0 : merge_getmem (NEED))
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
513
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
514 /* Merge the na elements starting at pa with the nb elements starting at pb
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
515 * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
516 * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
517 * merge, and should have na <= nb. See listsort.txt for more info.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
518 * Return 0 if successful, -1 if error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
519 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
520 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
521 int
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
522 octave_sort<T>::merge_lo (T *pa, octave_idx_type na, T *pb, octave_idx_type nb)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
523 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
524 octave_idx_type k;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
525 T *dest;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
526 int result = -1; /* guilty until proved innocent */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
527 octave_idx_type min_gallop = ms.min_gallop;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
528
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
529 if (MERGE_GETMEM (na) < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
530 return -1;
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
531 std::copy (pa, pa + na, ms.a);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
532 dest = pa;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
533 pa = ms.a;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
534
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
535 *dest++ = *pb++;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
536 --nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
537 if (nb == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
538 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
539 if (na == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
540 goto CopyB;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
541
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
542 for (;;)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
543 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
544 octave_idx_type acount = 0; /* # of times A won in a row */
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
545 octave_idx_type bcount = 0; /* # of times B won in a row */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
546
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
547 /* Do the straightforward thing until (if ever) one run
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
548 * appears to win consistently.
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
549 */
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
550 for (;;)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
551 {
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
552
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
553 IFLT (*pb, *pa)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
554 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
555 *dest++ = *pb++;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
556 ++bcount;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
557 acount = 0;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
558 --nb;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
559 if (nb == 0)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
560 goto Succeed;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
561 if (bcount >= min_gallop)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
562 break;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
563 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
564 else
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
565 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
566 *dest++ = *pa++;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
567 ++acount;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
568 bcount = 0;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
569 --na;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
570 if (na == 1)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
571 goto CopyB;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
572 if (acount >= min_gallop)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
573 break;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
574 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
575 }
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
576
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
577 /* One run is winning so consistently that galloping may
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
578 * be a huge win. So try that, and continue galloping until
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
579 * (if ever) neither run appears to be winning consistently
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
580 * anymore.
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
581 */
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
582 ++min_gallop;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
583 do
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
584 {
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
585 min_gallop -= min_gallop > 1;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
586 ms.min_gallop = min_gallop;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
587 k = gallop_right (*pb, pa, na, 0);
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
588 acount = k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
589 if (k)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
590 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
591 if (k < 0)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
592 goto Fail;
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
593 std::copy (pa, pa + k, dest);
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
594 dest += k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
595 pa += k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
596 na -= k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
597 if (na == 1)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
598 goto CopyB;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
599 /* na==0 is impossible now if the comparison
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
600 * function is consistent, but we can't assume
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
601 * that it is.
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
602 */
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
603 if (na == 0)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
604 goto Succeed;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
605 }
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
606 *dest++ = *pb++;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
607 --nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
608 if (nb == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
609 goto Succeed;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
610
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
611 k = gallop_left (*pa, pb, nb, 0);
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
612 bcount = k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
613 if (k)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
614 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
615 if (k < 0)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
616 goto Fail;
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
617 std::copy (pb, pb + k, dest);
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
618 dest += k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
619 pb += k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
620 nb -= k;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
621 if (nb == 0)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
622 goto Succeed;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
623 }
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
624 *dest++ = *pa++;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
625 --na;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
626 if (na == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
627 goto CopyB;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
628 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
629 while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
630
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
631 ++min_gallop; /* penalize it for leaving galloping mode */
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
632 ms.min_gallop = min_gallop;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
633 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
634
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
635 Succeed:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
636 result = 0;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
637
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
638 Fail:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
639 if (na)
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
640 std::copy (pa, pa + na, dest);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
641 return result;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
642
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
643 CopyB:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
644 /* The last element of pa belongs at the end of the merge. */
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
645 std::copy (pb, pb + nb, dest);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
646 dest[nb] = *pa;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
647
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
648 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
649 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
650
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
651 /* Merge the na elements starting at pa with the nb elements starting at pb
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
652 * in a stable way, in-place. na and nb must be > 0, and pa + na == pb.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
653 * Must also have that *pb < *pa, that pa[na-1] belongs at the end of the
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
654 * merge, and should have na >= nb. See listsort.txt for more info.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
655 * Return 0 if successful, -1 if error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
656 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
657 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
658 int
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
659 octave_sort<T>::merge_hi (T *pa, octave_idx_type na, T *pb, octave_idx_type nb)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
660 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
661 octave_idx_type k;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
662 T *dest;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
663 int result = -1; /* guilty until proved innocent */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
664 T *basea;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
665 T *baseb;
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
666 octave_idx_type min_gallop = ms.min_gallop;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
667
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
668 if (MERGE_GETMEM (nb) < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
669 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
670 dest = pb + nb - 1;
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
671 std::copy (pb, pb + nb, ms.a);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
672 basea = pa;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
673 baseb = ms.a;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
674 pb = ms.a + nb - 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
675 pa += na - 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
676
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
677 *dest-- = *pa--;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
678 --na;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
679 if (na == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
680 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
681 if (nb == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
682 goto CopyA;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
683
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
684 for (;;)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
685 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
686 octave_idx_type acount = 0; /* # of times A won in a row */
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
687 octave_idx_type bcount = 0; /* # of times B won in a row */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
688
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
689 /* Do the straightforward thing until (if ever) one run
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
690 * appears to win consistently.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
691 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
692 for (;;)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
693 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
694 IFLT (*pb, *pa)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
695 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
696 *dest-- = *pa--;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
697 ++acount;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
698 bcount = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
699 --na;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
700 if (na == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
701 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
702 if (acount >= min_gallop)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
703 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
704 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
705 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
706 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
707 *dest-- = *pb--;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
708 ++bcount;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
709 acount = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
710 --nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
711 if (nb == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
712 goto CopyA;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
713 if (bcount >= min_gallop)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
714 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
715 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
716 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
717
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
718 /* One run is winning so consistently that galloping may
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
719 * be a huge win. So try that, and continue galloping until
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
720 * (if ever) neither run appears to be winning consistently
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
721 * anymore.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
722 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
723 ++min_gallop;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
724 do
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
725 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
726 min_gallop -= min_gallop > 1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
727 ms.min_gallop = min_gallop;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
728 k = gallop_right (*pb, basea, na, na-1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
729 if (k < 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
730 goto Fail;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
731 k = na - k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
732 acount = k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
733 if (k)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
734 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
735 dest -= k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
736 pa -= k;
8678
e2b4c19c455c redo changeset 4238f2600a17 with fixes to sorting
Jaroslav Hajek <highegg@gmail.com>
parents: 8206
diff changeset
737 std::copy_backward (pa+1, pa+1 + k, dest+1 + k);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
738 na -= k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
739 if (na == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
740 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
741 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
742 *dest-- = *pb--;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
743 --nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
744 if (nb == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
745 goto CopyA;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
746
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
747 k = gallop_left (*pa, baseb, nb, nb-1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
748 if (k < 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
749 goto Fail;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
750 k = nb - k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
751 bcount = k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
752 if (k)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
753 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
754 dest -= k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
755 pb -= k;
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
756 std::copy (pb+1, pb+1 + k, dest+1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
757 nb -= k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
758 if (nb == 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
759 goto CopyA;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
760 /* nb==0 is impossible now if the comparison
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
761 * function is consistent, but we can't assume
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
762 * that it is.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
763 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
764 if (nb == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
765 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
766 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
767 *dest-- = *pa--;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
768 --na;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
769 if (na == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
770 goto Succeed;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
771 } while (acount >= MIN_GALLOP || bcount >= MIN_GALLOP);
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
772 ++min_gallop; /* penalize it for leaving galloping mode */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
773 ms.min_gallop = min_gallop;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
774 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
775
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
776 Succeed:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
777 result = 0;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
778
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
779 Fail:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
780 if (nb)
8206
0168d22e6bba fix sorting of non-POD objects
Jaroslav Hajek <highegg@gmail.com>
parents: 7929
diff changeset
781 std::copy (baseb, baseb + nb, dest-(nb-1));
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
782 return result;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
783
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
784 CopyA:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
785 /* The first element of pb belongs at the front of the merge. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
786 dest -= na;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
787 pa -= na;
8678
e2b4c19c455c redo changeset 4238f2600a17 with fixes to sorting
Jaroslav Hajek <highegg@gmail.com>
parents: 8206
diff changeset
788 std::copy_backward (pa+1, pa+1 + na, dest+1 + na);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
789 *dest = *pb;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
790
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
791 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
792 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
793
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
794 /* Merge the two runs at stack indices i and i+1.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
795 * Returns 0 on success, -1 on error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
796 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
797 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
798 int
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
799 octave_sort<T>::merge_at (octave_idx_type i)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
800 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
801 T *pa, *pb;
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
802 octave_idx_type na, nb;
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
803 octave_idx_type k;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
804
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
805 pa = ms.pending[i].base;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
806 na = ms.pending[i].len;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
807 pb = ms.pending[i+1].base;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
808 nb = ms.pending[i+1].len;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
809
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
810 /* Record the length of the combined runs; if i is the 3rd-last
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
811 * run now, also slide over the last run (which isn't involved
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
812 * in this merge). The current run i+1 goes away in any case.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
813 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
814 ms.pending[i].len = na + nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
815 if (i == ms.n - 3)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
816 ms.pending[i+1] = ms.pending[i+2];
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
817 --ms.n;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
818
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
819 /* Where does b start in a? Elements in a before that can be
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
820 * ignored (already in place).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
821 */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
822 k = gallop_right (*pb, pa, na, 0);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
823 if (k < 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
824 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
825 pa += k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
826 na -= k;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
827 if (na == 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
828 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
829
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
830 /* Where does a end in b? Elements in b after that can be
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
831 * ignored (already in place).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
832 */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
833 nb = gallop_left (pa[na-1], pb, nb, nb-1);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
834 if (nb <= 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
835 return nb;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
836
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
837 /* Merge what remains of the runs, using a temp array with
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
838 * min(na, nb) elements.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
839 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
840 if (na <= nb)
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
841 return merge_lo (pa, na, pb, nb);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
842 else
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
843 return merge_hi (pa, na, pb, nb);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
844 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
845
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
846 /* Examine the stack of runs waiting to be merged, merging adjacent runs
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
847 * until the stack invariants are re-established:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
848 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
849 * 1. len[-3] > len[-2] + len[-1]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
850 * 2. len[-2] > len[-1]
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
851 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
852 * See listsort.txt for more info.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
853 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
854 * Returns 0 on success, -1 on error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
855 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
856 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
857 int
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
858 octave_sort<T>::merge_collapse (void)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
859 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
860 struct s_slice *p = ms.pending;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
861
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
862 while (ms.n > 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
863 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
864 octave_idx_type n = ms.n - 2;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
865 if (n > 0 && p[n-1].len <= p[n].len + p[n+1].len)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
866 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
867 if (p[n-1].len < p[n+1].len)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
868 --n;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
869 if (merge_at (n) < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
870 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
871 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
872 else if (p[n].len <= p[n+1].len)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
873 {
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
874 if (merge_at (n) < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
875 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
876 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
877 else
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
878 break;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
879 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
880
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
881 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
882 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
883
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
884 /* Regardless of invariants, merge all runs on the stack until only one
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
885 * remains. This is used at the end of the mergesort.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
886 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
887 * Returns 0 on success, -1 on error.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
888 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
889 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
890 int
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
891 octave_sort<T>::merge_force_collapse (void)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
892 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
893 struct s_slice *p = ms.pending;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
894
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
895 while (ms.n > 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
896 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
897 octave_idx_type n = ms.n - 2;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
898 if (n > 0 && p[n-1].len < p[n+1].len)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
899 --n;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
900 if (merge_at (n) < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
901 return -1;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
902 }
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
903
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
904 return 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
905 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
906
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
907 /* Compute a good value for the minimum run length; natural runs shorter
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
908 * than this are boosted artificially via binary insertion.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
909 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
910 * If n < 64, return n (it's too small to bother with fancy stuff).
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
911 * Else if n is an exact power of 2, return 32.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
912 * Else return an int k, 32 <= k <= 64, such that n/k is close to, but
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
913 * strictly less than, an exact power of 2.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
914 *
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
915 * See listsort.txt for more info.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
916 */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
917 template <class T>
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
918 octave_idx_type
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
919 octave_sort<T>::merge_compute_minrun (octave_idx_type n)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
920 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
921 octave_idx_type r = 0; /* becomes 1 if any 1 bits are shifted off */
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
922
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
923 while (n >= 64)
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
924 {
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
925 r |= n & 1;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
926 n >>= 1;
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
927 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
928
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
929 return n + r;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
930 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
931
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
932 template <class T>
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
933 void
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
934 octave_sort<T>::sort (T *v, octave_idx_type elements)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
935 {
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
936 /* Re-initialize the Mergestate as this might be the second time called */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
937 ms.n = 0;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
938 ms.min_gallop = MIN_GALLOP;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
939
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
940 if (elements > 1)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
941 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
942 octave_idx_type nremaining = elements;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
943 T *lo = v;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
944 T *hi = v + elements;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
945
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
946 /* March over the array once, left to right, finding natural runs,
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
947 * and extending short natural runs to minrun elements.
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
948 */
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
949 octave_idx_type minrun = merge_compute_minrun (nremaining);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
950 do
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
951 {
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
952 bool descending;
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
953 octave_idx_type n;
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
954
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
955 /* Identify next run. */
7929
30b952e90c29 misc 64-bit fixes
John W. Eaton <jwe@octave.org>
parents: 7480
diff changeset
956 n = count_run (lo, hi, descending);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
957 if (n < 0)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
958 goto fail;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
959 if (descending)
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
960 reverse_slice (lo, lo + n);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
961 /* If short, extend to min(minrun, nremaining). */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
962 if (n < minrun)
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
963 {
7433
402168152bb9 [project @ 2008-01-31 18:59:09 by dbateman]
dbateman
parents: 7234
diff changeset
964 const octave_idx_type force = nremaining <= minrun ? nremaining : minrun;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
965 binarysort (lo, lo + force, lo + n);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
966 n = force;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
967 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
968 /* Push run onto pending-runs stack, and maybe merge. */
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
969 assert (ms.n < MAX_MERGE_PENDING);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
970 ms.pending[ms.n].base = lo;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
971 ms.pending[ms.n].len = n;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
972 ++ms.n;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
973 if (merge_collapse () < 0)
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
974 goto fail;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
975 /* Advance to find next run. */
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
976 lo += n;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
977 nremaining -= n;
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
978 }
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
979 while (nremaining);
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
980
7234
6992e9face25 [project @ 2007-11-30 20:45:42 by jwe]
jwe
parents: 7017
diff changeset
981 merge_force_collapse ();
4851
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
982 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
983
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
984 fail:
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
985 return;
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
986 }
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
987
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
988 /*
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
989 ;;; Local Variables: ***
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
990 ;;; mode: C++ ***
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
991 ;;; End: ***
047ff938b0d9 [project @ 2004-04-06 17:12:14 by jwe]
jwe
parents:
diff changeset
992 */