|
#ifndef LM_BUILDER_NGRAM_H |
|
#define LM_BUILDER_NGRAM_H |
|
|
|
#include "lm/weights.hh" |
|
#include "lm/word_index.hh" |
|
|
|
#include <cstddef> |
|
|
|
#include <assert.h> |
|
#include <stdint.h> |
|
#include <string.h> |
|
|
|
namespace lm { |
|
namespace builder { |
|
|
|
struct Uninterpolated { |
|
float prob; |
|
float gamma; |
|
}; |
|
|
|
union Payload { |
|
uint64_t count; |
|
Uninterpolated uninterp; |
|
ProbBackoff complete; |
|
}; |
|
|
|
class NGram { |
|
public: |
|
NGram(void *begin, std::size_t order) |
|
: begin_(static_cast<WordIndex*>(begin)), end_(begin_ + order) {} |
|
|
|
const uint8_t *Base() const { return reinterpret_cast<const uint8_t*>(begin_); } |
|
uint8_t *Base() { return reinterpret_cast<uint8_t*>(begin_); } |
|
|
|
void ReBase(void *to) { |
|
std::size_t difference = end_ - begin_; |
|
begin_ = reinterpret_cast<WordIndex*>(to); |
|
end_ = begin_ + difference; |
|
} |
|
|
|
|
|
void NextInMemory() { |
|
ReBase(&Value() + 1); |
|
} |
|
|
|
|
|
const WordIndex *begin() const { return begin_; } |
|
WordIndex *begin() { return begin_; } |
|
const WordIndex *end() const { return end_; } |
|
WordIndex *end() { return end_; } |
|
|
|
const Payload &Value() const { return *reinterpret_cast<const Payload *>(end_); } |
|
Payload &Value() { return *reinterpret_cast<Payload *>(end_); } |
|
|
|
uint64_t &Count() { return Value().count; } |
|
uint64_t Count() const { return Value().count; } |
|
|
|
std::size_t Order() const { return end_ - begin_; } |
|
|
|
static std::size_t TotalSize(std::size_t order) { |
|
return order * sizeof(WordIndex) + sizeof(Payload); |
|
} |
|
std::size_t TotalSize() const { |
|
|
|
return TotalSize(Order()); |
|
} |
|
static std::size_t OrderFromSize(std::size_t size) { |
|
std::size_t ret = (size - sizeof(Payload)) / sizeof(WordIndex); |
|
assert(size == TotalSize(ret)); |
|
return ret; |
|
} |
|
|
|
|
|
|
|
|
|
bool IsMarked() const { |
|
return Value().count >> (sizeof(Value().count) * 8 - 1); |
|
} |
|
|
|
void Mark() { |
|
Value().count |= (1ul << (sizeof(Value().count) * 8 - 1)); |
|
} |
|
|
|
void Unmark() { |
|
Value().count &= ~(1ul << (sizeof(Value().count) * 8 - 1)); |
|
} |
|
|
|
uint64_t UnmarkedCount() const { |
|
return Value().count & ~(1ul << (sizeof(Value().count) * 8 - 1)); |
|
} |
|
|
|
uint64_t CutoffCount() const { |
|
return IsMarked() ? 0 : UnmarkedCount(); |
|
} |
|
|
|
|
|
|
|
private: |
|
WordIndex *begin_, *end_; |
|
}; |
|
|
|
const WordIndex kUNK = 0; |
|
const WordIndex kBOS = 1; |
|
const WordIndex kEOS = 2; |
|
|
|
} |
|
} |
|
|
|
#endif |
|
|