Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: chrome/common/string_index.cc

Issue 8236002: Create StringOrdinal to allow placement of strings in sorted lists (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Changing StringIndex to a class Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/common/string_index.h"
6
7 #include "base/logging.h"
8
9 // Constants
10 static const std::string kInvalidStringIndex = "";
akalin 2011/10/14 10:16:29 static non-POD types are a no-no. use 'static con
11 static const char kZeroDigit = 'A';
akalin 2011/10/14 10:16:29 prefer anon namespace
12 static const char kMinDigit = 'B';
13 static const char kMidDigit = 'N';
14 static const char kMaxDigit = 'Z';
15 static const int kMaxDigitValue = kMaxDigit - kZeroDigit;
16 static const int kMidDigitValue = kMidDigit - kZeroDigit;
17 static const int kFullDigitValue = (kMaxDigit + 1) - kZeroDigit;
18
19
20 StringIndex::StringIndex(const std::string& str) : string_index_(str) {
21
22 }
23
24 StringIndex::StringIndex() : string_index_(kInvalidStringIndex) {
25 }
26
27 bool StringIndex::IsValid() const {
28 if (string_index_ == kInvalidStringIndex) {
akalin 2011/10/14 10:16:29 simply check for empty
29 return false;
30 }
31
32 for (size_t i = 0; i < string_index_.length(); ++i) {
akalin 2011/10/14 10:16:29 better to do this computation in the constructor a
33 if (string_index_[i] < kZeroDigit || string_index_[i] > kMaxDigit) {
34 return false;
35 }
36 }
37
38 return (string_index_[string_index_.length() - 1] > kZeroDigit);
akalin 2011/10/14 10:16:29 and it must also be <= maxdigit
csharp1 2011/10/14 16:52:36 This is already checked in the above for loop. We
39 }
40
41 bool StringIndex::LessThan(const StringIndex& other) const {
42 return string_index_ < other.string_index_;
akalin 2011/10/14 10:16:29 CHECK that both strings are valid (this goes for a
43 }
44
45 StringIndex StringIndex::CreateBetween(const StringIndex& other) const {
46 DCHECK(LessThan(other));
47
48 return CreateStringIndexBetween(*this, other);
49 }
50
51 StringIndex StringIndex::CreateBefore() const {
52 StringIndex start = StringIndex(std::string(string_index_.length(),
53 kZeroDigit));
54
55 return CreateStringIndexBetween(start, *this);
56 }
57
58 StringIndex StringIndex::CreateAfter() const {
59 std::string end = std::string(string_index_.length(), kMaxDigit);
60 if (end == string_index_) {
61 end += kMaxDigit;
62 }
63 StringIndex end_index = StringIndex(end);
64
65 return CreateStringIndexBetween(*this, end_index);
66 }
67
68 std::string StringIndex::ToString() const {
69 return string_index_;
70 }
71
72 int StringIndex::GetPositionValue(size_t i) const {
73 return i < string_index_.length() ? string_index_[i] - kZeroDigit : 0;
akalin 2011/10/14 10:16:29 use parenthesis to the clauses of the ternary oper
74 }
75
76 StringIndex StringIndex::CreateStringIndexBetween(const StringIndex& start,
77 const StringIndex& end) {
78 DCHECK(start.LessThan(end));
79
80 std::string middle_string = ComputeMidpoint(start, end);
81 middle_string = RemoveTrailingZeros(middle_string);
82 DCHECK_GT(middle_string, start.ToString());
83 DCHECK_LT(middle_string, end.ToString());
84
85 return StringIndex(middle_string);
86 }
87
88 std::string StringIndex::ComputeMidpoint(const StringIndex& start,
akalin 2011/10/14 10:16:29 so when i asked you to decomp this function out, I
89 const StringIndex& end) {
90 size_t max_size = std::max(start.ToString().length(),
akalin 2011/10/14 10:16:29 #include <algorithm> for max
akalin 2011/10/14 10:16:29 CHECK that both start and end are valid
akalin 2011/10/14 10:16:29 rather than calling ToString() multiple times, set
91 end.ToString().length());
92 std::string middle_string(max_size, kZeroDigit);
93
94 bool add_half = false;
95 for (size_t i = 0; i < max_size; ++i) {
96 int char_value = start.GetPositionValue(i);
97 char_value += end.GetPositionValue(i);
98
99 middle_string[i] += (char_value / 2);
100 if (add_half) {
101 AddHalf(i, middle_string);
102 }
103 add_half = (char_value % 2 == 1);
104 }
105
106 // We only add an extra digit if it is required for uniqueness, otherwise
107 // we accept a close to middle placement
108 if (add_half && EqualValueIndexs(middle_string,start.ToString())) {
csharp1 2011/10/13 16:07:08 Note that if middle_string.length() > max_size it
akalin 2011/10/14 10:16:29 if start is valid (which it should be if you check
109 middle_string += kMidDigit;
110 }
111
112 return middle_string;
113 }
114
115 bool StringIndex::EqualValueIndexs(const std::string& rhs,
116 const std::string& lhs) {
117 return RemoveTrailingZeros(rhs) == RemoveTrailingZeros(lhs);
118 }
119
120 void StringIndex::AddHalf(size_t position, std::string& value) {
121 DCHECK_GT(position, static_cast<size_t>(0));
122 value[position] += kMidDigitValue;
123
124 for (size_t i = position; value[i] > kMaxDigit; --i) {
125 DCHECK(i > 0);
akalin 2011/10/14 10:16:29 DCHECK_GT
akalin 2011/10/14 10:16:29 better to CHECK -- if this fails, you'll do an out
126 value[i] -= kFullDigitValue;
127 ++value[i - 1];
128 }
129 }
130
131 std::string StringIndex::RemoveTrailingZeros(const std::string& value) {
132 DCHECK(!value.empty());
133
134 int end_position = value.length() - 1;
135 while (value[end_position] == kZeroDigit) {
136 --end_position;
137 }
138
139 return value.substr(0, end_position + 1);
140 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698