JaffarPlus
High-performance best-first search optimizer for tool-assisted speedruns
Loading...
Searching...
No Matches
inputHistoryRaw.hpp
Go to the documentation of this file.
1#pragma once
2
10#include "inputHistory.hpp"
11#include <atomic>
12#include <cstring>
13#include <jaffarCommon/bitwise.hpp>
14#include <jaffarCommon/exceptions.hpp>
15#include <jaffarCommon/logger.hpp>
16#include <vector>
17
18namespace jaffarPlus
19{
20
23class InputHistoryRaw final : public InputHistory
24{
25public:
29 InputHistoryRaw(const uint32_t maxInputIndex, const uint32_t maxSize) : _maxSize(maxSize)
30 {
31 _bits = jaffarCommon::bitwise::getEncodingBitsForElementCount(maxInputIndex);
32 const size_t bytes = (_maxSize * _bits + 7) / 8;
33 _buffer.resize(bytes, 0);
34 }
35
36 void reset() override { std::memset(_buffer.data(), 0, _buffer.size()); }
37
38 void pushInput(const size_t stepCount, const InputSet::inputIndex_t input) override
39 {
40 if (stepCount < _maxSize)
41 setInput(stepCount, input);
42 else if (_truncationWarned.exchange(true) == false)
43 jaffarCommon::logger::log("[J+] Warning: input history exceeded its maximum size (%u). Longer solutions are truncated; raise 'Store Input History / Max Size'.\n", _maxSize);
44 }
45
46 void serializeCold(jaffarCommon::serializer::Base& s) const override { s.pushContiguous(_buffer.data(), _buffer.size()); }
47 void deserializeCold(jaffarCommon::deserializer::Base& d) override { d.popContiguous(_buffer.data(), _buffer.size()); }
48 void serializeFull(jaffarCommon::serializer::Base& s) const override { serializeCold(s); }
49 void deserializeFull(jaffarCommon::deserializer::Base& d, const size_t /*stepCount*/) override { deserializeCold(d); }
50
51 std::string toString(const std::map<InputSet::inputIndex_t, std::string>& inputStringMap, const size_t stepCount) const override
52 {
53 std::string out;
54 for (size_t i = 0; i < stepCount && i < _maxSize; i++)
55 {
56 const auto idx = getInput(i);
57 if (inputStringMap.contains(idx) == false) JAFFAR_THROW_RUNTIME("Move Index %u not found in runner\n", idx);
58 out += inputStringMap.at(idx) + std::string("\n");
59 }
60 return out;
61 }
62
63 size_t getColdSize() const override { return _buffer.size(); }
64 size_t getFullSize() const override { return _buffer.size(); }
65
66 void captureColdToFull(const void* cold, void* full) const override { memcpy(full, cold, _buffer.size()); }
67
68private:
70 __INLINE__ void setInput(const size_t step, const InputSet::inputIndex_t input)
71 {
72 jaffarCommon::bitwise::bitcopy(_buffer.data(), _buffer.size(), step, &input, sizeof(InputSet::inputIndex_t), 0, 1, _bits);
73 }
75 __INLINE__ InputSet::inputIndex_t getInput(const size_t step) const
76 {
78 jaffarCommon::bitwise::bitcopy(&idx, sizeof(InputSet::inputIndex_t), 0, _buffer.data(), _buffer.size(), step, 1, _bits);
79 return idx;
80 }
81
82 const uint32_t _maxSize;
83 size_t _bits = 0;
84 std::vector<uint8_t> _buffer;
85 static inline std::atomic<bool> _truncationWarned = false;
86};
87
88} // namespace jaffarPlus
Stores the full bit-packed input sequence in every state (JaffarPlus's classic behavior): self-contai...
const uint32_t _maxSize
Maximum number of steps recorded.
std::string toString(const std::map< InputSet::inputIndex_t, std::string > &inputStringMap, const size_t stepCount) const override
Reconstructs the path as a newline-separated string of input strings (the solution).
void pushInput(const size_t stepCount, const InputSet::inputIndex_t input) override
Records one applied input at path position stepCount (the runner's current step counter).
void deserializeFull(jaffarCommon::deserializer::Base &d, const size_t) override
Restores the cursor from a "full" representation.
void setInput(const size_t step, const InputSet::inputIndex_t input)
Writes the input index for step into the bit-packed buffer.
void deserializeCold(jaffarCommon::deserializer::Base &d) override
Restores the cursor from a "cold" representation (the count is restored by the runner).
void captureColdToFull(const void *cold, void *full) const override
Converts a stored cold path into a self-contained full one (best/worst snapshot).
std::vector< uint8_t > _buffer
Bit-packed input sequence.
InputSet::inputIndex_t getInput(const size_t step) const
Reads the input index recorded for step from the bit-packed buffer.
void serializeFull(jaffarCommon::serializer::Base &s) const override
Writes the self-contained "full" path representation (for standalone snapshot buffers),...
void reset() override
Resets the cursor to the empty path.
void serializeCold(jaffarCommon::serializer::Base &s) const override
Writes the compact "cold" path representation (stored in each StateDb slot), excluding the count.
size_t getColdSize() const override
Size, in bytes, of the cold path representation in a StateDb slot (EXCLUDING the runner's count).
static std::atomic< bool > _truncationWarned
Set once after the first over-Max-Size push.
size_t _bits
Bits used to encode one input index.
InputHistoryRaw(const uint32_t maxInputIndex, const uint32_t maxSize)
Constructs the strategy and sizes the per-state bit-packed buffer.
size_t getFullSize() const override
Size, in bytes, of the full (self-contained) path representation in a snapshot buffer (EXCLUDING the ...
Abstract strategy for remembering the input path that produced each search state.
size_t inputIndex_t
Type used to index an input.
Definition inputSet.hpp:29
Abstract interface for how a search remembers the sequence of inputs ("path") that produced each stat...