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

Unified 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 side-by-side diff with in-line comments
Download patch
Index: chrome/common/string_index.cc
diff --git a/chrome/common/string_index.cc b/chrome/common/string_index.cc
new file mode 100644
index 0000000000000000000000000000000000000000..ec97734d72e7304eef9cea3b81d23e5726c5c653
--- /dev/null
+++ b/chrome/common/string_index.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/common/string_index.h"
+
+#include "base/logging.h"
+
+// Constants
+static const std::string kInvalidStringIndex = "";
akalin 2011/10/14 10:16:29 static non-POD types are a no-no. use 'static con
+static const char kZeroDigit = 'A';
akalin 2011/10/14 10:16:29 prefer anon namespace
+static const char kMinDigit = 'B';
+static const char kMidDigit = 'N';
+static const char kMaxDigit = 'Z';
+static const int kMaxDigitValue = kMaxDigit - kZeroDigit;
+static const int kMidDigitValue = kMidDigit - kZeroDigit;
+static const int kFullDigitValue = (kMaxDigit + 1) - kZeroDigit;
+
+
+StringIndex::StringIndex(const std::string& str) : string_index_(str) {
+
+}
+
+StringIndex::StringIndex() : string_index_(kInvalidStringIndex) {
+}
+
+bool StringIndex::IsValid() const {
+ if (string_index_ == kInvalidStringIndex) {
akalin 2011/10/14 10:16:29 simply check for empty
+ return false;
+ }
+
+ 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
+ if (string_index_[i] < kZeroDigit || string_index_[i] > kMaxDigit) {
+ return false;
+ }
+ }
+
+ 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
+}
+
+bool StringIndex::LessThan(const StringIndex& other) const {
+ return string_index_ < other.string_index_;
akalin 2011/10/14 10:16:29 CHECK that both strings are valid (this goes for a
+}
+
+StringIndex StringIndex::CreateBetween(const StringIndex& other) const {
+ DCHECK(LessThan(other));
+
+ return CreateStringIndexBetween(*this, other);
+}
+
+StringIndex StringIndex::CreateBefore() const {
+ StringIndex start = StringIndex(std::string(string_index_.length(),
+ kZeroDigit));
+
+ return CreateStringIndexBetween(start, *this);
+}
+
+StringIndex StringIndex::CreateAfter() const {
+ std::string end = std::string(string_index_.length(), kMaxDigit);
+ if (end == string_index_) {
+ end += kMaxDigit;
+ }
+ StringIndex end_index = StringIndex(end);
+
+ return CreateStringIndexBetween(*this, end_index);
+}
+
+std::string StringIndex::ToString() const {
+ return string_index_;
+}
+
+int StringIndex::GetPositionValue(size_t i) const {
+ 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
+}
+
+StringIndex StringIndex::CreateStringIndexBetween(const StringIndex& start,
+ const StringIndex& end) {
+ DCHECK(start.LessThan(end));
+
+ std::string middle_string = ComputeMidpoint(start, end);
+ middle_string = RemoveTrailingZeros(middle_string);
+ DCHECK_GT(middle_string, start.ToString());
+ DCHECK_LT(middle_string, end.ToString());
+
+ return StringIndex(middle_string);
+}
+
+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
+ const StringIndex& end) {
+ 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
+ end.ToString().length());
+ std::string middle_string(max_size, kZeroDigit);
+
+ bool add_half = false;
+ for (size_t i = 0; i < max_size; ++i) {
+ int char_value = start.GetPositionValue(i);
+ char_value += end.GetPositionValue(i);
+
+ middle_string[i] += (char_value / 2);
+ if (add_half) {
+ AddHalf(i, middle_string);
+ }
+ add_half = (char_value % 2 == 1);
+ }
+
+ // We only add an extra digit if it is required for uniqueness, otherwise
+ // we accept a close to middle placement
+ 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
+ middle_string += kMidDigit;
+ }
+
+ return middle_string;
+}
+
+bool StringIndex::EqualValueIndexs(const std::string& rhs,
+ const std::string& lhs) {
+ return RemoveTrailingZeros(rhs) == RemoveTrailingZeros(lhs);
+}
+
+void StringIndex::AddHalf(size_t position, std::string& value) {
+ DCHECK_GT(position, static_cast<size_t>(0));
+ value[position] += kMidDigitValue;
+
+ for (size_t i = position; value[i] > kMaxDigit; --i) {
+ 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
+ value[i] -= kFullDigitValue;
+ ++value[i - 1];
+ }
+}
+
+std::string StringIndex::RemoveTrailingZeros(const std::string& value) {
+ DCHECK(!value.empty());
+
+ int end_position = value.length() - 1;
+ while (value[end_position] == kZeroDigit) {
+ --end_position;
+ }
+
+ return value.substr(0, end_position + 1);
+}

Powered by Google App Engine
This is Rietveld 408576698