27
27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
30
#include "base/base.h"
34
#include "base/file_stream.h"
35
#include "base/util.h"
36
#include "converter/connector.h"
37
#include "storage/sparse_array_image.h"
31
#include "base/singleton.h"
32
#include "converter/connector_interface.h"
33
#include "converter/sparse_connector.h"
41
ConnectorInterface *ConnectorInterface::OpenFromArray(const char *ptr,
43
const int16 *image = reinterpret_cast<const int16*>(ptr);
44
if (image[0] == kDenseConnectorMagic) {
45
VLOG(1) << "DenseConector";
46
return new DenseConnector(ptr, size);
47
} else if (image[0] == kSparseConnectorMagic) {
48
VLOG(1) << "SparseConector";
49
return new SparseConnector(ptr, size);
51
LOG(FATAL) << "unsuported Connector image";
55
///////////////////////////////////////////////////////////////////////
56
// DenseConnector implementations
57
DenseConnector::DenseConnector(const char *ptr, size_t size)
58
: matrix_(NULL), lsize_(0), rsize_(0) {
59
matrix_ = reinterpret_cast<const int16*>(ptr);
60
lsize_ = static_cast<int>(matrix_[2]);
61
rsize_ = static_cast<int>(matrix_[3]);
62
CHECK(static_cast<int>(lsize_ * rsize_ + 4) ==
63
size / sizeof(matrix_[0]))
64
<< "connection table is broken";
68
DenseConnector::~DenseConnector() {}
70
void DenseConnector::CompileImage(const int16 *matrix,
71
uint16 lsize, uint16 rsize,
72
const char *binary_file) {
73
OutputFileStream ofs(binary_file, ios::binary|ios::out);
74
CHECK(ofs) << "permission denied: " << binary_file;
75
uint16 magic = kDenseConnectorMagic;
76
ofs.write(reinterpret_cast<const char*>(&magic), sizeof(magic));
77
// write one more value to align matrix image in 4 bytes.
79
ofs.write(reinterpret_cast<const char*>(&magic), sizeof(magic));
80
ofs.write(reinterpret_cast<const char*>(&lsize), sizeof(lsize));
81
ofs.write(reinterpret_cast<const char*>(&rsize), sizeof(rsize));
82
ofs.write(reinterpret_cast<const char*>(&matrix[0]),
83
sizeof(matrix[0]) * lsize * rsize);
87
///////////////////////////////////////////////////////////////////////
88
// SparseConnector implementations
89
SparseConnector::SparseConnector(const char *ptr, size_t size)
90
: default_cost_(NULL) {
91
// |magic(2byte)|null(2byte)|lsize(2byte)|rsize(2byte)
92
// |default_cost..|sparse_image
93
const size_t kHeaderSize = 8;
94
CHECK_GT(size, kHeaderSize);
95
const uint16 *image = reinterpret_cast<const uint16*>(ptr);
96
const uint16 lsize = image[2];
99
default_cost_ = reinterpret_cast<const int16 *>(ptr);
100
const size_t default_cost_size = sizeof(default_cost_[0]) * lsize;
102
ptr += default_cost_size;
104
CHECK_GT(size, default_cost_size + kHeaderSize);
106
const size_t array_image_size= size - kHeaderSize - default_cost_size;
107
array_image_.reset(new SparseArrayImage(ptr, array_image_size));
110
SparseConnector::~SparseConnector() {}
112
int SparseConnector::GetTransitionCost(uint16 rid, uint16 lid) const {
113
const int pos = array_image_->Peek(EncodeKey(rid, lid));
114
if (pos == SparseArrayImage::kInvalidValueIndex) {
115
return default_cost_[rid];
117
return array_image_->GetValue(pos);
120
void SparseConnector::CompileImage(const int16 *matrix,
121
uint16 lsize, uint16 rsize,
122
const char *binary_file) {
123
LOG(INFO) << "compiling matrix with " << lsize * rsize;
125
SparseArrayBuilder builder;
126
vector<int16> default_cost(lsize);
127
fill(default_cost.begin(), default_cost.end(), static_cast<int16>(0));
129
for (int lid = 0; lid < lsize; ++lid) {
130
for (int rid = 0; rid < rsize; ++rid) {
131
const int16 c = matrix[lid + lsize * rid];
132
if (ConnectorInterface::kInvalidCost != c) {
133
default_cost[lid] = max(default_cost[lid], c); // save default cost
138
for (int lid = 0; lid < lsize; ++lid) {
139
for (int rid = 0; rid < rsize; ++rid) {
140
const int16 c = matrix[lid + lsize * rid];
141
if (c != default_cost[lid]) {
142
builder.AddValue(EncodeKey(lid, rid), c);
149
OutputFileStream ofs(binary_file, ios::binary|ios::out);
150
CHECK(ofs) << "permission denied: " << binary_file;
152
CHECK_EQ(lsize, default_cost.size());
154
uint16 magic = kSparseConnectorMagic;
155
ofs.write(reinterpret_cast<const char*>(&magic), sizeof(magic));
156
// write one more value to align matrix image in 4 bytes.
158
ofs.write(reinterpret_cast<const char*>(&magic), sizeof(magic));
159
ofs.write(reinterpret_cast<const char*>(&lsize), sizeof(lsize));
160
ofs.write(reinterpret_cast<const char*>(&rsize), sizeof(rsize));
161
ofs.write(reinterpret_cast<const char*>(&default_cost[0]),
162
sizeof(default_cost[0]) * default_cost.size());
163
ofs.write(builder.GetImage(), builder.GetSize());
39
#include "converter/embedded_connection_data.h"
41
class SparseConnectorInitializer {
43
SparseConnectorInitializer()
44
: connector_(new SparseConnector(
45
kConnectionData_data, kConnectionData_size)) {}
46
virtual ~SparseConnectorInitializer() {
50
SparseConnector *Get() const {
55
SparseConnector *connector_;
58
ConnectorInterface *g_connector = NULL;
61
ConnectorInterface *ConnectorFactory::GetConnector() {
62
if (g_connector == NULL) {
63
return Singleton<SparseConnectorInitializer>::get()->Get();
166
68
} // namespace mozc