1 /*
2 * Copyright (c) 2003 Nara Institute of Science and Technology
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name Nara Institute of Science and Technology may not be used to
15 * endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY Nara Institute of Science and Technology
19 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
21 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE Nara Institute
22 * of Science and Technology BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
24 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * $Id: dartsdic.cpp,v 1.4 2008/05/16 04:59:21 masayu-a Exp $
31 */
32
33 #include <string>
34 #include <vector>
35 #include <map>
36 #include <iostream>
37 #include <darts.h>
38 extern "C" {
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include "dartsdic.h"
42 #include "chalib.h"
43 }
44
45 typedef Darts::DoubleArrayImpl<char, unsigned char, long, unsigned long>
46 DoubleArrayL;
47
48 struct _darts_t {
49 DoubleArrayL *da;
50 cha_mmap_t *da_mmap;
51 cha_mmap_t *lex_mmap;
52 cha_mmap_t *dat_mmap;
53 };
54
55 typedef std::multimap<std::string, long> Hash;
56 typedef Hash::value_type HashVal;
57
58 struct _da_build_t {
59 Hash *entries;
60 std::string* path;
61 };
62
63 darts_t *
da_open(char * daname,char * lexname,char * datname)64 da_open(char *daname, char *lexname, char *datname)
65 {
66 darts_t *da;
67 DoubleArrayL *darts = new DoubleArrayL;
68
69 da = (darts_t*)cha_malloc(sizeof(darts_t));
70 da->da_mmap = cha_mmap_file(daname);
71 darts->set_array(cha_mmap_map(da->da_mmap));
72 da->da = darts;
73 da->lex_mmap = cha_mmap_file(lexname);
74 da->dat_mmap = cha_mmap_file(datname);
75
76 return da;
77 }
78
79 int
da_lookup(darts_t * da,char * key,int key_len,long * indecies,int num)80 da_lookup(darts_t *da, char *key, int key_len, long *indecies, int num)
81 {
82 return da->da
83 ->commonPrefixSearch(key, indecies, num, key_len);
84 }
85
86 long
da_exact_lookup(darts_t * da,char * key,int key_len)87 da_exact_lookup(darts_t *da, char *key, int key_len)
88 {
89 return da->da
90 ->exactMatchSearch<long>(key, key_len);
91
92 }
93
94 #define lex_map(d) cha_mmap_map((d)->lex_mmap)
95 #define dat_map(d) cha_mmap_map((d)->dat_mmap)
96
97 int
da_get_lex(darts_t * da,long index,da_lex_t * lex_data,int * key_len)98 da_get_lex(darts_t *da, long index, da_lex_t *lex_data, int *key_len)
99 {
100 int num, i;
101 char *base = (char *)lex_map(da) + index;
102
103 *key_len = ((short *)base)[0];
104 num = ((short *)base)[1];
105 base += sizeof(short) * 2;
106
107 for (i = 0; i < num; i++) {
108 memcpy((void*)(lex_data + i),
109 (void*)base, sizeof(da_lex_t));
110 base += sizeof(da_lex_t);
111 }
112
113 return num;
114 }
115
116 void *
da_get_lex_base(darts_t * da)117 da_get_lex_base(darts_t *da)
118 {
119 return lex_map(da);
120 }
121
122 void *
da_get_dat_base(darts_t * da)123 da_get_dat_base(darts_t *da)
124 {
125 return dat_map(da);
126 }
127
128 da_build_t *
da_build_new(char * path)129 da_build_new(char *path)
130 {
131 da_build_t *builder;
132
133 builder = (da_build_t*)cha_malloc(sizeof(da_build_t));
134 builder->entries = new Hash;
135 builder->path = new std::string(path);
136
137 return builder;
138 }
139
140 void
da_build_add(da_build_t * builder,char * key,long val)141 da_build_add(da_build_t *builder, char *key, long val)
142 {
143 builder->entries->insert(HashVal(key, val));
144 }
145
146 static int
redump_lex(size_t key_len,std::vector<long> & indices,char * tmpfile,FILE * lexfile)147 redump_lex(size_t key_len, std::vector<long>& indices,
148 char* tmpfile, FILE* lexfile)
149 {
150 long index = ftell(lexfile);
151 short buf;
152
153 buf = (short)key_len;
154 fwrite(&buf, sizeof(short), 1, lexfile);
155 buf = (short)indices.size();
156 fwrite(&buf, sizeof(short), 1, lexfile);
157 for (std::vector<long>::iterator i = indices.begin();
158 i != indices.end(); i++) {
159 da_lex_t* lex = (da_lex_t*)(tmpfile + *i);
160 fwrite(lex, sizeof(da_lex_t), 1, lexfile);
161 }
162
163 return index;
164 }
165
166 int
da_build_dump(da_build_t * builder,char * tmpfile,FILE * lexfile)167 da_build_dump(da_build_t* builder, char* tmpfile, FILE* lexfile)
168 {
169 Hash::iterator i, last;
170 Hash* entries = builder->entries;
171 const char** keys = new const char*[entries->size()];
172 size_t* lens = new size_t[entries->size()];
173 long* vals = new long[entries->size()];
174 int size = 0;
175 std::vector<long> lex_indices;
176
177 std::cerr << entries->size() << " entries" << std::endl;
178
179 i = entries->begin();
180 while (i != entries->end()) {
181 const std::string& key = i->first;
182 last = entries->upper_bound(key);
183 lex_indices.clear();
184 for (; i != last; i++) {
185 lex_indices.push_back(i->second);
186 }
187 lens[size] = key.size();
188 keys[size] = (const char*) key.data();
189 vals[size] = redump_lex(lens[size], lex_indices, tmpfile, lexfile);
190 if (vals[size] < 0) {
191 std::cerr << "Unexpected error at " << key << std::endl;
192 cha_exit_perror("build darts file");
193 }
194 size++;
195 }
196 std::cerr << size << " keys" << std::endl;
197
198 DoubleArrayL da;
199 da.build(size, (const char**) keys, lens, vals);
200 da.save(builder->path->c_str(), "wb");
201
202 return builder->entries->size();
203 }
204