binary_log.hxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * SHA-L - Simple Hybesis Algorithm Logger
4  *
5  * Copyright (c) Michael Jeulin-Lagarrigue
6  *
7  * Licensed under the MIT License, you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * https://github.com/michael-jeulinl/Simple-Hybesis-Algorithms-Logger/blob/master/LICENSE
11  *
12  * Unless required by applicable law or agreed to in writing, software distributed under the License is
13  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and limitations under the License.
15  *
16  * The above copyright notice and this permission notice shall be included in all copies or
17  * substantial portions of the Software.
18  *
19  *=========================================================================================================*/
20 #ifndef MODULE_SEARCH_BINARY_LOG_HXX
21 #define MODULE_SEARCH_BINARY_LOG_HXX
22 
23 #include <Logger/algorithm.hxx>
24 #include <Logger/array.hxx>
25 #include <Logger/comment.hxx>
26 #include <Logger/operation.hxx>
27 #include <Logger/typedef.hxx>
28 #include <Logger/value.hxx>
29 
30 namespace SHA_Logger
31 {
34  template <typename IT, typename T, typename IsEqualT>
35  class BinaryLog
36  {
37  public:
40  static const String GetName() { return "Binary_Sort"; }
41 
44  static bool WriteInfo(Writer& writer) { return true; }
45 
48  static bool WriteDoc(Writer& writer) { return true; }
49 
52  static bool WriteSrc(Writer& writer) { return true; }
53 
54  // Assert correct JSON construction.
55  ~BinaryLog() { assert(this->writer->IsComplete()); }
56 
62  static Ostream& Build(Ostream& os, Options opts, const IT& begin, const IT& end, const T& key)
63  {
64  std::unique_ptr<BinaryLog> builder = std::unique_ptr<BinaryLog>(new BinaryLog(os));
65  builder->Write(opts, begin, end, key);
66 
67  return os;
68  }
69 
74  static Writer& Build(Writer& writer, Options opts, const IT& begin, const IT& end, const T& key)
75  {
76  Write(writer, opts, begin, end, key);
77 
78  return writer;
79  }
80 
81  private:
82  BinaryLog(Ostream& os) : stream(std::unique_ptr<Stream>(new Stream(os))),
83  writer(std::unique_ptr<Writer>(new Writer(*this->stream))) {}
84  BinaryLog operator=(BinaryLog&) {} // Not Implemented
85 
86  bool Write(Options opts, const IT& begin, const IT& end, const T& key)
87  { return Write(*this->writer, opts, begin, end, key); }
88 
89  static bool Write(Writer& writer, Options opts, const IT& begin, const IT& end, const T& key)
90  {
91  writer.StartObject();
92 
93  // Write description
94  Algo_Traits<BinaryLog>::Build(writer, opts);
95 
96  // Write parameters
97  WriteParameters(writer, begin, end, key);
98 
99  // Write computation
100  WriteComputation(writer, begin, end, key);
101 
102  writer.EndObject();
103 
104  return true;
105  }
106 
108  static bool WriteParameters(Writer& writer, const IT& begin, const IT& end, const T& key)
109  {
110  writer.Key("parameters");
111  writer.StartArray();
112  Array<IT>::Build(writer, kSeqName, "begin", begin, "end", end);
113  Value<T>::Build(writer, "key", key);
114  writer.EndArray();
115 
116  return true;
117  }
118 
120  static bool WriteComputation(Writer& writer, const IT& begin, const IT& end, const T& key)
121  {
122  // Not part of the logs
123  int _lowIdx = 0;
124 
125  // Local logged variables
126  writer.Key("locals");
127  writer.StartArray();
128  auto index = Value<int>::BuildValue(writer, "index", -1);
129  auto seqSize = Value<int>::BuildValue(writer, "seqSize", static_cast<int>(std::distance(begin, end)));
130  auto lowIt = Iterator::BuildIt<IT>(writer, kSeqName, "lowIt", 0, begin);
131  auto highIt = Iterator::BuildIt<IT>(writer, kSeqName, "highIt", seqSize + 1, end);
132  auto middleIt = Iterator::BuildIt<IT>(writer, kSeqName, "middleIt", seqSize / 2,
133  lowIt + seqSize / 2, "Initiate index on the middle element of the sequence");
134  writer.EndArray();
135 
136  // Log algorithm operations
137  writer.Key("logs");
138  writer.StartArray();
139  Comment::Build(writer, "Start Binary Search", 0);
140  while (lowIt < highIt && index < 0)
141  {
142  if (IsEqualT()(key, *middleIt))
143  {
144  index = static_cast<int>(std::distance(begin, middleIt));
145 
146  Comment::Build(writer, "Found!", 1);
147  Operation::Set<int>(writer, "index", index);
148  break;
149  }
150  else if (key > *middleIt)
151  {
152  lowIt = middleIt + 1;
153  _lowIdx += seqSize / 2 + 1;
154  seqSize -= seqSize / 2 + 1;
155 
156  Comment::Build(writer, "(key > current): search upper sequence.", 1);
157  Operation::Set<int>(writer, "lowIt", _lowIdx);
158  }
159  else
160  {
161  highIt = middleIt;
162 
163  Comment::Build(writer, "(key < current): search lower sequence.", 1);
164  Operation::Set<int>(writer, "highIt", seqSize / 2);
165  seqSize -= seqSize / 2;
166  }
167 
168  middleIt = lowIt + seqSize / 2;
169  Comment::Build(writer, "Select the middle element of the remaining sequence.", 1);
170  Operation::Set<int>(writer, "middleIt", _lowIdx + seqSize / 2);
171  }
172 
173  // Logs failure
174  if (index < 0)
175  Comment::Build(writer, "Key not found.", 0);
176 
177  Operation::Return<int>(writer, index);
178  writer.EndArray();
179  return true;
180  }
181 
182  std::unique_ptr<Stream> stream; // Stream wrapper
183  std::unique_ptr<Writer> writer; // Writer used to fill the stream
184  };
185 }
186 
187 #endif // MODULE_SEARCH_BINARY_LOG_HXX
std::unique_ptr< Writer > writer
Definition: binary_log.hxx:183
static Writer & Build(Writer &writer, Options opts, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:74
static Ostream & Build(Ostream &os, const String &name, const T &value, const String &comment="")
Definition: value.hxx:44
static Ostream & Build(Ostream &os, const String &message, int level=0, const String extent="normal")
Definition: comment.hxx:43
const std::string String
Definition: typedef.hxx:36
static Ostream & Build(Ostream &os, Options opts)
Definition: algorithm.hxx:39
static bool WriteSrc(Writer &writer)
Definition: binary_log.hxx:52
static const T & BuildValue(Writer &writer, const String &name, const T &value, const String &comment="")
Definition: value.hxx:57
static bool WriteInfo(Writer &writer)
Definition: binary_log.hxx:44
static Ostream & Build(Ostream &os, const String &name, const String &beginName, const IT &begin, const String &endName, const IT &end)
Definition: array.hxx:42
static Ostream & Build(Ostream &os, Options opts, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:62
static const String GetName()
Definition: binary_log.hxx:40
rapidjson::OStreamWrapper Stream
Definition: typedef.hxx:32
bool Write(Options opts, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:86
static const std::string kSeqName
Definition: typedef.hxx:41
BinaryLog(Ostream &os)
Definition: binary_log.hxx:82
static bool Write(Writer &writer, Options opts, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:89
static bool WriteDoc(Writer &writer)
Definition: binary_log.hxx:48
static bool WriteComputation(Writer &writer, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:120
BinaryLog operator=(BinaryLog &)
Definition: binary_log.hxx:84
std::ostream Ostream
Definition: typedef.hxx:37
std::unique_ptr< Stream > stream
Definition: binary_log.hxx:182
static bool WriteParameters(Writer &writer, const IT &begin, const IT &end, const T &key)
Definition: binary_log.hxx:108
rapidjson::PrettyWriter< Stream > Writer
Definition: typedef.hxx:33