2 * Á¹ÔÎó¤ò°·¤¦¤¿¤á¤Î¥³¡¼¥É
4 * (1) ¹ÔÎó(sparse_matrix)¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òºîÀ®¤·¹ÔÎó¤ÎÍ×ÁǤòÀßÄꤹ¤ë
5 * (2) ¹ÔÎ󤫤é¹ÔÎ󥤥᡼¥¸(matrix_image)¤òºîÀ®¤¹¤ë
6 * * ¹ÔÎ󥤥᡼¥¸¤ònetwork byteorder¤Ç¥Õ¥¡¥¤¥ë¤Ë½ñ¤½Ð¤¹
7 * (3) ¹ÔÎ󥤥᡼¥¸¤òÆɤ߹þ¤ß(or mmap¤¹¤ë)Í×ÁǤ˥¢¥¯¥»¥¹¤¹¤ë
11 * sparse matrix crammer
13 * sparse matrix storage uses following 2 sparse arrays
15 * *array of cells in a row
18 * sparse row crammed row
28 * (?:1 means non-all 0 row)
30 * crammed row cram shift count
31 * 1:1 . . -> .. shift 0
32 * 3:1 . . -> .. shift 2
33 * 7:1 . . . -> ... shift 4
38 * ....... unified array of (value.column) pair
41 * image[0] : length of hashed row array
42 * image[1] : length of crammed cell array
43 * image[2 ~ 2+image[0]-1] : hashed row array
44 * image[2+image[0] ~ 2+image[0]+image[1]-1] : hashed row array
46 * Copyright (C) 2005 TABATA Yusuke
50 This library is free software; you can redistribute it and/or
51 modify it under the terms of the GNU Lesser General Public
52 License as published by the Free Software Foundation; either
53 version 2 of the License, or (at your option) any later version.
55 This library is distributed in the hope that it will be useful,
56 but WITHOUT ANY WARRANTY; without even the implied warranty of
57 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
58 Lesser General Public License for more details.
60 You should have received a copy of the GNU Lesser General Public
61 License along with this library; if not, write to the Free Software
62 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
67 #include <anthy/diclib.h>
69 #include <anthy/matrix.h>
71 /* maximum length allowed for hash chain */
72 #define MAX_FAILURE 50
78 struct list_elm *next;
79 /* bypass to mitigate O(n) insertion cost */
80 struct list_elm *orig_next;
90 * sparse array has two representation
92 * (1) list and (2) hashed array
93 * build list first and sparse_array_make_array() to build hashed array
94 * this stores one value and one pointer
98 /* list representation */
101 struct list_elm head;
103 /* array representation */
105 struct array_elm *array;
108 static struct sparse_array *
109 sparse_array_new(void)
111 struct sparse_array *a = malloc(sizeof(struct sparse_array));
115 a->head.orig_next = NULL;
124 insert_elm_after(struct list_elm *elm, int idx, int val, void *ptr)
126 struct list_elm *new_elm = malloc(sizeof(struct list_elm));
127 new_elm->value = val;
128 new_elm->index = idx;
131 new_elm->next = elm->next;
132 new_elm->orig_next = elm->next;
137 sparse_array_set(struct sparse_array *sa, int idx, int val, void *ptr)
142 if (e->index == idx) {
143 /* find same index and update */
149 if (e->index < idx && (!e->next || idx < e->next->index)) {
150 insert_elm_after(e, idx, val, ptr);
156 if (e->orig_next && e->orig_next->index < idx) {
166 hash(int val, int max, int nth)
179 sparse_array_try_make_array(struct sparse_array *s)
185 s->array = malloc(sizeof(struct array_elm) * s->array_len);
186 for (i = 0; i < s->array_len; i++) {
187 s->array[i].index = -1;
191 for (e = s->head.next; e; e = e->next) {
195 int h = hash(e->index, s->array_len, n);
196 if (s->array[h].index == -1) {
197 /* find unused element in this array */
199 s->array[h].index = e->index;
200 s->array[h].value = e->value;
201 s->array[h].ptr = e->ptr;
205 if (n > MAX_FAILURE) {
206 /* too much collision */
216 sparse_array_make_array(struct sparse_array *s)
218 /* estimate length */
219 if (s->elm_count == 1) {
222 s->array_len = s->elm_count;
224 while (sparse_array_try_make_array(s)) {
225 /* expand a little */
232 static struct array_elm *
233 sparse_array_get(struct sparse_array *s, int index, struct array_elm *arg)
238 int h = hash(index, s->array_len, n);
239 if (s->array[h].index == index) {
244 if (n == MAX_FAILURE) {
249 struct list_elm *e = e = s->head.next;
251 if (e->index == index) {
252 arg->value = e->value;
257 if (e->orig_next && e->orig_next->index < index) {
269 sparse_array_get_int(struct sparse_array *s, int index)
271 struct array_elm elm;
272 if (sparse_array_get(s, index, &elm)) {
279 sparse_array_get_ptr(struct sparse_array *s, int index)
281 struct array_elm elm;
282 if (sparse_array_get(s, index, &elm)) {
289 struct sparse_matrix {
291 struct sparse_array *row_array;
292 /* image information */
298 struct sparse_matrix *
299 anthy_sparse_matrix_new()
301 struct sparse_matrix *m = malloc(sizeof(struct sparse_matrix));
302 m->row_array = sparse_array_new();
307 static struct sparse_array *
308 find_row(struct sparse_matrix *m, int row, int create)
310 struct sparse_array *a;
311 a = sparse_array_get_ptr(m->row_array, row);
318 /* allocate a new row */
319 a = sparse_array_new();
320 sparse_array_set(m->row_array, row, 0, a);
327 anthy_sparse_matrix_set(struct sparse_matrix *m, int row, int column,
328 int value, void *ptr)
330 struct sparse_array *a;
331 a = find_row(m, row, 1);
332 sparse_array_set(a, column, value, ptr);
337 anthy_sparse_matrix_get_int(struct sparse_matrix *m, int row, int column)
339 struct sparse_array *a;
341 a = find_row(m, row, 1);
345 for (e = &a->head; e; e = e->next) {
346 if (e->index == column) {
355 anthy_sparse_matrix_make_matrix(struct sparse_matrix *m)
357 struct array_elm *ae;
361 sparse_array_make_array(m->row_array);
363 for (i = 0; i < m->row_array->array_len; i++) {
364 struct sparse_array *row;
365 ae = &m->row_array->array[i];
368 if (ae->index == -1) {
373 sparse_array_make_array(row);
374 offset += row->array_len;
376 m->array_length = offset;
380 struct matrix_image *
381 anthy_matrix_image_new(struct sparse_matrix *s)
383 struct matrix_image *mi;
387 mi = malloc(sizeof(struct matrix_image));
388 mi->size = 2 + s->row_array->array_len * 2 + s->array_length * 2;
389 mi->image = malloc(sizeof(int) * mi->size);
390 mi->image[0] = s->row_array->array_len;
391 mi->image[1] = s->array_length;
394 for (i = 0; i < s->row_array->array_len; i++) {
395 struct array_elm *ae;
396 ae = &s->row_array->array[i];
397 mi->image[offset + i*2] = ae->index;
398 mi->image[offset + i*2 + 1] = ae->value;
401 offset = 2 + s->row_array->array_len * 2;
402 for (i = 0; i < s->row_array->array_len; i++) {
403 struct array_elm *ae;
404 struct sparse_array *sa;
406 ae = &s->row_array->array[i];
407 if (ae->index == -1) {
414 for (j = 0; j < sa->array_len; j++) {
415 struct array_elm *cell = &sa->array[j];
416 mi->image[offset] = cell->index;
417 if (cell->index == -1) {
418 mi->image[offset + 1] = -1;
420 mi->image[offset + 1] = cell->value;
430 read_int(int *image, int idx, int en)
433 return anthy_dic_ntohl(image[idx]);
439 do_matrix_peek(int *image, int row, int col, int en)
441 int n, h, shift, next_shift;
442 int row_array_len = read_int(image, 0, en);
443 int column_array_len;
447 if (row_array_len == 0) {
451 h = hash(row, row_array_len, n);
452 if (read_int(image, 2+ h * 2, en) == row) {
453 shift = read_int(image, 2+h*2+1, en);
456 if (read_int(image, 2+ h * 2, en) == -1) {
459 if (n > MAX_FAILURE) {
464 /* find shift count of next row */
465 if (h == row_array_len - 1) {
467 next_shift = read_int(image, 1, en);
470 next_shift = read_int(image, 2+h*2+2+1, en);
473 /* crammed width of this row */
474 column_array_len = next_shift - shift;
476 /* cells in this image */
477 cell_offset = 2 + row_array_len * 2;
479 h = hash(col, column_array_len, n);
480 if (read_int(image, cell_offset + shift * 2+ h * 2, en) == col) {
481 return read_int(image, cell_offset + shift * 2 + h*2+1, en);
483 if (read_int(image, cell_offset + shift * 2+ h * 2, en) == -1) {
487 if (n > MAX_FAILURE) {
496 anthy_matrix_image_peek(int *image, int row, int col)
501 return do_matrix_peek(image, row, col, 1);
505 /* for debug purpose */
507 sparse_array_dump(struct sparse_array *s)
511 printf("list(%d):", s->elm_count);
512 for (e = s->head.next; e; e = e->next) {
513 printf(" %d:%d(%x)", e->index, e->value, (unsigned long)e->ptr);
519 printf("array(%d):", s->array_len);
520 for (i = 0; i < s->array_len; i ++) {
521 struct array_elm *ae = &s->array[i];
522 if (ae->index != -1) {
523 printf(" %d:%d,%d(%x)", i, ae->index, ae->value, (unsigned long)ae->ptr);
531 /* for debug purpose */
533 sparse_matrix_dump(struct sparse_matrix *m)
536 struct array_elm *ae;
539 for (e = m->row_array->head.next; e; e = e->next) {
540 sparse_array_dump(e->ptr);
544 printf("\nnumber of row=%d, row array size=%d, cell array size=%d\n\n",
545 m->nr_rows, m->row_array->array_len, m->array_length);
547 for (i = 0; i < m->row_array->array_len; i++) {
548 struct array_elm *ae;
549 ae = &m->row_array->array[i];
550 if (ae->index != -1) {
551 printf(" [%d] row=%d, shift=%d\n", i, ae->index, ae->value);
556 for (i = 0; i < m->row_array->array_len; i++) {
557 struct array_elm *ae;
558 struct sparse_array *sa;
560 ae = &m->row_array->array[i];
565 for (j = 0; j < sa->array_len; j++) {
566 struct array_elm *cell = &sa->array[j];
567 if (cell->index != -1) {
568 printf(" [%d] column=%d, value=%d\n", offset, cell->index, cell->value);