source: git/src/namecompare.cc @ 6b71b92

RELEASE/1.2debug-cidebug-ci-sanitisersstereowalls-data
Last change on this file since 6b71b92 was 6b71b92, checked in by Olly Betts <olly@…>, 8 years ago

Reduce file loading time by a few percent

The station name compare function is something of a hot spot, and
optimising it a bit yields a nice improvement.

  • Property mode set to 100644
File size: 2.2 KB
RevLine 
[0bd66ac]1/* namecompare.cc */
2/* Ordering function for station names */
[6b71b92]3/* Copyright (C) 1991-2002,2004,2012,2016 Olly Betts
[0bd66ac]4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18 */
19
20#ifdef HAVE_CONFIG_H
21# include <config.h>
22#endif
23
24#include "namecompare.h"
25
26inline bool u_digit(unsigned ch) {
[6b71b92]27    return (ch - unsigned('0')) <= unsigned('9' - '0');
[0bd66ac]28}
29
30int name_cmp(const wxString &a, const wxString &b, int separator) {
31   size_t i = 0;
[6b71b92]32   size_t shorter = std::min(a.size(), b.size());
33   while (i != shorter) {
34      int cha = a[i];
35      int chb = b[i];
[0bd66ac]36      /* check for end of non-numeric prefix */
37      if (u_digit(cha)) {
38         /* sort numbers numerically and before non-numbers */
39         size_t sa, sb, ea, eb;
40         int res;
41
42         if (!u_digit(chb)) return chb == separator ? 1 : -1;
43
44         sa = i;
45         while (sa != a.size() && a[sa] == '0') sa++;
46         ea = sa;
[6b71b92]47         while (ea != a.size() && u_digit(a[ea])) ea++;
[0bd66ac]48
49         sb = i;
50         while (sb != b.size() && b[sb] == '0') sb++;
51         eb = sb;
[6b71b92]52         while (eb != b.size() && u_digit(b[eb])) eb++;
[0bd66ac]53
54         /* shorter sorts first */
55         res = (ea - sa) - (eb - sb);
56         /* same length, all digits, so character value compare sorts
57          * numerically */
58         for (size_t j = sa; !res && j != ea; ++j) {
59            res = a[j] - b[j - sa + sb];
60         }
61         /* more leading zeros sorts first */
62         if (!res) res = sb - sa;
63         if (res) return res;
64
65         /* if numbers match, sort by suffix */
66         i = ea;
67         continue;
68      }
69
70      if (cha != chb) {
71         if (cha == separator) return -1;
72         if (u_digit(chb) || chb == separator) return 1;
73         return cha - chb;
74      }
75
76      i++;
77   }
[6b71b92]78   return int(a.size()) - int(b.size());
[0bd66ac]79}
Note: See TracBrowser for help on using the repository browser.