partition_log.hxx
Go to the documentation of this file.
1 /*===========================================================================================================
2  *
3  * SHA - Simple Hybesis Algorithms
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/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_SORT_PARTITION_LOG_HXX
21 #define MODULE_SORT_PARTITION_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 // STD includes
31 #include <iterator>
32 
33 namespace SHA_Logger
34 {
37  template <typename IT, typename Compare = std::less_equal<typename std::iterator_traits<IT>::value_type>>
39  {
40  public:
43  static const String GetName() { return "Partition"; }
44 
47  static bool WriteInfo(Writer& writer) { return true; }
48 
51  static bool WriteDoc(Writer& writer) { return true; }
52 
55  static bool WriteSrc(Writer& writer) { return true; }
56 
57  // Assert correct JSON construction.
58  ~PartitionLog() { assert(this->writer->IsComplete()); }
59 
65  static IT Build(Ostream& os, Options opts,
66  const IT& begin, const IT& pivot, const IT& end, const int offSet = 0)
67  {
68  std::unique_ptr<PartitionLog> builder = std::unique_ptr<PartitionLog>(new PartitionLog(os));
69  return builder->Write(opts, begin, pivot, end, offSet);
70  }
71 
76  static IT Build(Writer& writer, Options opts,
77  const IT& begin, const IT& pivot, const IT& end, const int offSet = 0)
78  {
79  return Write(writer, opts, begin, pivot, end, offSet);
80  }
81 
82  private:
83  PartitionLog(Ostream& os) : stream(std::unique_ptr<Stream>(new Stream(os))),
84  writer(std::unique_ptr<Writer>(new Writer(*this->stream))) {}
85  PartitionLog operator=(PartitionLog&) {} // Not Implemented
86 
87  IT Write(Options opts, const IT& begin, const IT& pivot, const IT& end, const int offset)
88  { return Write(*this->writer, opts, begin, pivot, end, offset); }
89 
90  static IT Write(Writer& writer, Options opts,
91  const IT& begin, const IT& pivot, const IT& end, const int offset)
92  {
93  writer.StartObject();
94 
95  // Do not write sequence if no data to be processed
96  const int _seqSize = static_cast<int>(std::distance(begin, end));
97  if (_seqSize < 2 || pivot == end)
98  {
99  Comment::Build(writer, "Sequence size too small to be processed.", 0);
100  // @todo return pivot
101  Operation::Return<bool>(writer, true);
102  return pivot;
103  }
104 
105  // Write description
106  Algo_Traits<PartitionLog>::Build(writer, opts);
107 
108  // Write parameters
109  WriteParameters(writer, opts, begin, pivot, end, offset);
110 
111  // Write computation
112  auto newPivot = WriteComputation(writer, begin, pivot, end, offset);
113 
114  writer.EndObject();
115 
116  return newPivot;
117  }
118 
120  static bool WriteParameters(Writer& writer, Options opts,
121  const IT& begin, const IT& pivot, const IT& end, const int offset)
122  {
123  const int _pivIdx = static_cast<int>(std::distance(begin,pivot));
124  writer.Key("parameters");
125  writer.StartArray();
126  if (opts & OpIsSub)
127  {
128  const int _seqSize = static_cast<int>(std::distance(begin, end));
129  Iterator::Build(writer, kSeqName, "begin", offset);
130  Iterator::Build(writer, kSeqName, "pivot", offset + _pivIdx);
131  Iterator::Build(writer, kSeqName, "end", offset + _seqSize);
132  }
133  else
134  {
135  Array<IT>::Build(writer, kSeqName, "begin", begin, "end", end);
136  Iterator::Build(writer, kSeqName, "pivot", _pivIdx);
137  }
138  writer.EndArray();
139 
140  return true;
141  }
142 
144  static IT WriteComputation
145  (Writer& writer, const IT& begin, const IT& pivot, const IT& end, const int offset)
146  {
147  // Not part of the logs
148  auto _seqSize = static_cast<int>(std::distance(begin, end));
149  int _itIdx = offset;
150  int _storeIdx = offset;
151 
152  // Local logged variables
153  writer.Key("locals");
154  writer.StartArray();
155  auto it = Iterator::BuildIt<IT>(writer, kSeqName, "it", offset, begin, "Cur IT");
156  Iterator::BuildIt<IT>(writer, kSeqName, "last", offset + _seqSize - 1, end - 1, "Lst IT");
158  BuildValue(writer, "pivotValue", *pivot, "Keet pivot val.");
159  auto store = Iterator::BuildIt<IT>(writer, kSeqName, "store", offset, begin, "Store IT");
160  writer.EndArray();
161 
162  writer.Key("logs");
163  writer.StartArray();
164  Comment::Build(writer, "Start Partitinning", 0);
165 
166  Comment::Build(writer, "Put the pivot at the end for convenience", 0);
167  Operation::Swap(writer, "pivot", "last");
168  std::swap(*pivot, *(end - 1));
169 
170  Comment::Build(writer, "Swap each element with ", 0);
171  for (it = begin; it != end - 1; ++it, Operation::Set<int>(writer, "it", ++_itIdx))
172  {
173  if (Compare()(*it, pivotValue))
174  {
175  Comment::Build(writer, "it <= pivot: swap(it, store).", 1);
176  Operation::Swap(writer, "store", "it");
177  Operation::Set<int>(writer, "store", ++_storeIdx);
178  std::swap(*store, *it);
179  ++store;
180  } else
181  Comment::Build(writer, "pivot > it : Ignore element.", 1);
182  }
183 
184  Comment::Build(writer, "Replace the pivot at its good position and replace its value.", 0);
185  Operation::Set<int>(writer, "pivot", _storeIdx);
186  Operation::Swap(writer, "store", "last");
187  std::swap(*(end - 1), *store);
188 
189  // @todo Return Iterator
190  Operation::Return<bool>(writer, true);
191  writer.EndArray();
192  return store;
193  }
194 
195  std::unique_ptr<Stream> stream; // Stream wrapper
196  std::unique_ptr<Writer> writer; // Writer used to fill the stream
197  };
198 }
199 
200 #endif // MODULE_SORT_PARTITION_HXX
static bool WriteSrc(Writer &writer)
static Ostream & Build(Ostream &os, const String &message, int level=0, const String extent="normal")
Definition: comment.hxx:43
static IT Build(Writer &writer, Options opts, const IT &begin, const IT &pivot, const IT &end, const int offSet=0)
const std::string String
Definition: typedef.hxx:36
IT Write(Options opts, const IT &begin, const IT &pivot, const IT &end, const int offset)
static Ostream & Build(Ostream &os, Options opts)
Definition: algorithm.hxx:39
PartitionLog operator=(PartitionLog &)
static IT Write(Writer &writer, Options opts, const IT &begin, const IT &pivot, const IT &end, const int offset)
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 const String GetName()
static Ostream & Build(Ostream &os, const String &parentId, const String &name, int index, const String &comment="")
Definition: iterator.hxx:43
rapidjson::OStreamWrapper Stream
Definition: typedef.hxx:32
static const std::string kSeqName
Definition: typedef.hxx:41
static bool WriteDoc(Writer &writer)
static bool WriteParameters(Writer &writer, Options opts, const IT &begin, const IT &pivot, const IT &end, const int offset)
std::unique_ptr< Writer > writer
static bool WriteInfo(Writer &writer)
std::ostream Ostream
Definition: typedef.hxx:37
std::unique_ptr< Stream > stream
static IT Build(Ostream &os, Options opts, const IT &begin, const IT &pivot, const IT &end, const int offSet=0)
rapidjson::PrettyWriter< Stream > Writer
Definition: typedef.hxx:33
static IT WriteComputation(Writer &writer, const IT &begin, const IT &pivot, const IT &end, const int offset)
static Ostream & Swap(Ostream &os, const String &aName, const String &bName)
Definition: operation.hxx:79