诸暨麻将添加redis
Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

165 wiersze
5.8 KiB

  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // https://developers.google.com/protocol-buffers/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are
  7. // met:
  8. //
  9. // * Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // * Redistributions in binary form must reproduce the above
  12. // copyright notice, this list of conditions and the following disclaimer
  13. // in the documentation and/or other materials provided with the
  14. // distribution.
  15. // * Neither the name of Google Inc. nor the names of its
  16. // contributors may be used to endorse or promote products derived from
  17. // this software without specific prior written permission.
  18. //
  19. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22. // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23. // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25. // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26. // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27. // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28. // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30. #ifndef GOOGLE_PROTOBUF_COMPILER_SCC_H__
  31. #define GOOGLE_PROTOBUF_COMPILER_SCC_H__
  32. #include <map>
  33. #include <google/protobuf/stubs/logging.h>
  34. #include <google/protobuf/stubs/common.h>
  35. #include <google/protobuf/descriptor.h>
  36. #include <google/protobuf/port_def.inc>
  37. namespace google {
  38. namespace protobuf {
  39. namespace compiler {
  40. // Description of each strongly connected component. Note that the order
  41. // of both the descriptors in this SCC and the order of children is
  42. // deterministic.
  43. struct SCC {
  44. std::vector<const Descriptor*> descriptors;
  45. std::vector<const SCC*> children;
  46. const Descriptor* GetRepresentative() const { return descriptors[0]; }
  47. // All messages must necessarily be in the same file.
  48. const FileDescriptor* GetFile() const { return descriptors[0]->file(); }
  49. };
  50. // This class is used for analyzing the SCC for each message, to ensure linear
  51. // instead of quadratic performance, if we do this per message we would get
  52. // O(V*(V+E)).
  53. template <class DepsGenerator>
  54. class PROTOC_EXPORT SCCAnalyzer {
  55. public:
  56. explicit SCCAnalyzer() : index_(0) {}
  57. const SCC* GetSCC(const Descriptor* descriptor) {
  58. if (cache_.count(descriptor)) return cache_[descriptor].scc;
  59. return DFS(descriptor).scc;
  60. }
  61. private:
  62. struct NodeData {
  63. const SCC* scc; // if null it means its still on the stack
  64. int index;
  65. int lowlink;
  66. };
  67. std::map<const Descriptor*, NodeData> cache_;
  68. std::vector<const Descriptor*> stack_;
  69. int index_;
  70. std::vector<std::unique_ptr<SCC>> garbage_bin_;
  71. SCC* CreateSCC() {
  72. garbage_bin_.emplace_back(new SCC());
  73. return garbage_bin_.back().get();
  74. }
  75. // Tarjan's Strongly Connected Components algo
  76. NodeData DFS(const Descriptor* descriptor) {
  77. // Must not have visited already.
  78. GOOGLE_DCHECK_EQ(cache_.count(descriptor), 0);
  79. // Mark visited by inserting in map.
  80. NodeData& result = cache_[descriptor];
  81. // Initialize data structures.
  82. result.index = result.lowlink = index_++;
  83. stack_.push_back(descriptor);
  84. // Recurse the fields / nodes in graph
  85. for (auto dep : DepsGenerator()(descriptor)) {
  86. GOOGLE_CHECK(dep);
  87. if (cache_.count(dep) == 0) {
  88. // unexplored node
  89. NodeData child_data = DFS(dep);
  90. result.lowlink = std::min(result.lowlink, child_data.lowlink);
  91. } else {
  92. NodeData child_data = cache_[dep];
  93. if (child_data.scc == nullptr) {
  94. // Still in the stack_ so we found a back edge
  95. result.lowlink = std::min(result.lowlink, child_data.index);
  96. }
  97. }
  98. }
  99. if (result.index == result.lowlink) {
  100. // This is the root of a strongly connected component
  101. SCC* scc = CreateSCC();
  102. while (true) {
  103. const Descriptor* scc_desc = stack_.back();
  104. scc->descriptors.push_back(scc_desc);
  105. // Remove from stack
  106. stack_.pop_back();
  107. cache_[scc_desc].scc = scc;
  108. if (scc_desc == descriptor) break;
  109. }
  110. // The order of descriptors is random and depends how this SCC was
  111. // discovered. In-order to ensure maximum stability we sort it by name.
  112. std::sort(scc->descriptors.begin(), scc->descriptors.end(),
  113. [](const Descriptor* a, const Descriptor* b) {
  114. return a->full_name() < b->full_name();
  115. });
  116. AddChildren(scc);
  117. }
  118. return result;
  119. }
  120. // Add the SCC's that are children of this SCC to its children.
  121. void AddChildren(SCC* scc) {
  122. std::set<const SCC*> seen;
  123. for (auto descriptor : scc->descriptors) {
  124. for (auto child_msg : DepsGenerator()(descriptor)) {
  125. GOOGLE_CHECK(child_msg);
  126. const SCC* child = GetSCC(child_msg);
  127. if (child == scc) continue;
  128. if (seen.insert(child).second) {
  129. scc->children.push_back(child);
  130. }
  131. }
  132. }
  133. }
  134. // This is necessary for compiler bug in msvc2015.
  135. GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(SCCAnalyzer);
  136. };
  137. } // namespace compiler
  138. } // namespace protobuf
  139. } // namespace google
  140. #include <google/protobuf/port_undef.inc>
  141. #endif // GOOGLE_PROTOBUF_COMPILER_SCC_H__