File size: 2,913 Bytes
1ce325b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#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;  // Uninterpolated probability.
  float gamma; // Interpolation weight for lower order.
};

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;
    }

    // Would do operator++ but that can get confusing for a stream.
    void NextInMemory() {
      ReBase(&Value() + 1);
    }

    // Lower-case in deference to STL.
    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 {
      // Compiler should optimize this.
      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;
    }
    
    // manipulate msb to signal that ngram can be pruned
    /*mjd**********************************************************************/

    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();
    }

    /*mjd**********************************************************************/

  private:
    WordIndex *begin_, *end_;
};

const WordIndex kUNK = 0;
const WordIndex kBOS = 1;
const WordIndex kEOS = 2;

} // namespace builder
} // namespace lm

#endif // LM_BUILDER_NGRAM_H