| 1 | /* $Id$ |
|---|
| 2 | * |
|---|
| 3 | * Copyright (c) 2005-2007 Daisuke Maki <daisuke@endeworks.jp> |
|---|
| 4 | * All rights reserved. |
|---|
| 5 | */ |
|---|
| 6 | #ifndef __SENNA_INDEX_C__ |
|---|
| 7 | #define __SENNA_INDEX_C__ |
|---|
| 8 | #include "senna-perl.h" |
|---|
| 9 | |
|---|
| 10 | int |
|---|
| 11 | SennaPerl_Index_bootstrap() |
|---|
| 12 | { |
|---|
| 13 | HV *stash; |
|---|
| 14 | |
|---|
| 15 | stash = gv_stashpv("Senna::Costants", 1); |
|---|
| 16 | |
|---|
| 17 | newCONSTSUB(stash, "SEN_INDEX_NORMALIZE", newSViv(SEN_INDEX_NORMALIZE)); |
|---|
| 18 | newCONSTSUB(stash, "SEN_INDEX_SPLIT_ALPHA", newSViv(SEN_INDEX_SPLIT_ALPHA)); |
|---|
| 19 | newCONSTSUB(stash, "SEN_INDEX_SPLIT_DIGIT", newSViv(SEN_INDEX_SPLIT_DIGIT)); |
|---|
| 20 | newCONSTSUB(stash, "SEN_INDEX_SPLIT_SYMBOL", |
|---|
| 21 | newSViv(SEN_INDEX_SPLIT_SYMBOL)); |
|---|
| 22 | newCONSTSUB(stash, "SEN_INDEX_MORPH_ANALYSE", |
|---|
| 23 | newSViv(SEN_INDEX_MORPH_ANALYSE)); |
|---|
| 24 | newCONSTSUB(stash, "SEN_INDEX_NGRAM", newSViv(SEN_INDEX_NGRAM)); |
|---|
| 25 | newCONSTSUB(stash, "SEN_INDEX_DELIMITED", newSViv(SEN_INDEX_DELIMITED)); |
|---|
| 26 | newCONSTSUB(stash, "SEN_INDEX_ENABLE_SUFFIX_SEARCH", |
|---|
| 27 | newSViv(SEN_INDEX_ENABLE_SUFFIX_SEARCH)); |
|---|
| 28 | newCONSTSUB(stash, "SEN_INDEX_DISABLE_SUFFIX_SEARCH", |
|---|
| 29 | newSViv(SEN_INDEX_DISABLE_SUFFIX_SEARCH)); |
|---|
| 30 | newCONSTSUB(stash, "SEN_INDEX_WITH_VACUUM", newSViv(SEN_INDEX_WITH_VACUUM)); |
|---|
| 31 | |
|---|
| 32 | return 1; |
|---|
| 33 | } |
|---|
| 34 | |
|---|
| 35 | SV * |
|---|
| 36 | SennaPerl_Index_new(pkg, index) |
|---|
| 37 | char *pkg; |
|---|
| 38 | sen_index *index; |
|---|
| 39 | { |
|---|
| 40 | SennaPerl_Index *xs; |
|---|
| 41 | SV *sv; |
|---|
| 42 | |
|---|
| 43 | Newz(1234, xs, 1, SennaPerl_Index); |
|---|
| 44 | |
|---|
| 45 | xs->index = index; |
|---|
| 46 | xs->open = TRUE; |
|---|
| 47 | |
|---|
| 48 | XS_STRUCT2OBJ(sv, pkg, xs); |
|---|
| 49 | SvREADONLY_on(sv); |
|---|
| 50 | return sv; |
|---|
| 51 | } |
|---|
| 52 | |
|---|
| 53 | SV * |
|---|
| 54 | SennaPerl_Index_XS_create(pkg, path, key_size, flags, initial_n_segments, encoding) |
|---|
| 55 | char *pkg; |
|---|
| 56 | char *path; |
|---|
| 57 | int key_size; |
|---|
| 58 | int flags; |
|---|
| 59 | int initial_n_segments; |
|---|
| 60 | sen_encoding encoding; |
|---|
| 61 | { |
|---|
| 62 | sen_index *index; |
|---|
| 63 | SV *sv; |
|---|
| 64 | |
|---|
| 65 | index = sen_index_create(path, key_size, flags, initial_n_segments, encoding); |
|---|
| 66 | if (index == NULL) { |
|---|
| 67 | croak("Failed to create senna index (sen_index_create() returned NULL) "); |
|---|
| 68 | } |
|---|
| 69 | |
|---|
| 70 | return SennaPerl_Index_new(pkg, index); |
|---|
| 71 | } |
|---|
| 72 | |
|---|
| 73 | SV * |
|---|
| 74 | SennaPerl_Index_open(pkg, path) |
|---|
| 75 | char *pkg; |
|---|
| 76 | char *path; |
|---|
| 77 | { |
|---|
| 78 | sen_index *index; |
|---|
| 79 | int key_size; |
|---|
| 80 | SV *sv; |
|---|
| 81 | |
|---|
| 82 | index = sen_index_open(path); |
|---|
| 83 | if (index == NULL) { |
|---|
| 84 | croak("Failed to open senna index %s.", path); |
|---|
| 85 | } |
|---|
| 86 | |
|---|
| 87 | sv = SennaPerl_Index_new(pkg, index); |
|---|
| 88 | return sv; |
|---|
| 89 | } |
|---|
| 90 | |
|---|
| 91 | SV * |
|---|
| 92 | SennaPerl_Index_remove(self) |
|---|
| 93 | SV *self; |
|---|
| 94 | { |
|---|
| 95 | SennaPerl_Index *index; |
|---|
| 96 | char path[ SEN_MAX_PATH_SIZE ]; |
|---|
| 97 | |
|---|
| 98 | index = XS_STATE(SennaPerl_Index *, self); |
|---|
| 99 | if (! sen_index_path( index->index, path, SEN_MAX_PATH_SIZE) ) { |
|---|
| 100 | croak("sen_index_path() did not return a proper path"); |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | return sen_rc2obj( sen_index_remove( path ) ); |
|---|
| 104 | } |
|---|
| 105 | |
|---|
| 106 | SV * |
|---|
| 107 | SennaPerl_Index_close(obj) |
|---|
| 108 | SV *obj; |
|---|
| 109 | { |
|---|
| 110 | SennaPerl_Index *index; |
|---|
| 111 | index = XS_STATE(SennaPerl_Index *, obj); |
|---|
| 112 | if (index == NULL || ! index->open) { |
|---|
| 113 | return SennaPerl_Global_sen_rc2obj( sen_other_error ); |
|---|
| 114 | } else { |
|---|
| 115 | index->open = FALSE; |
|---|
| 116 | return SennaPerl_Global_sen_rc2obj( sen_index_close(index->index) ); |
|---|
| 117 | } |
|---|
| 118 | } |
|---|
| 119 | |
|---|
| 120 | void |
|---|
| 121 | SennaPerl_Index_DESTROY(obj) |
|---|
| 122 | SV *obj; |
|---|
| 123 | { |
|---|
| 124 | SennaPerl_Index *index; |
|---|
| 125 | index = XS_STATE(SennaPerl_Index *, obj); |
|---|
| 126 | |
|---|
| 127 | SennaPerl_Index_close(obj); |
|---|
| 128 | Safefree(index); |
|---|
| 129 | } |
|---|
| 130 | |
|---|
| 131 | SV * |
|---|
| 132 | SennaPerl_Index_path(obj) |
|---|
| 133 | SV *obj; |
|---|
| 134 | { |
|---|
| 135 | SennaPerl_Index *index; |
|---|
| 136 | char *buf; |
|---|
| 137 | SV *sv; |
|---|
| 138 | |
|---|
| 139 | index = XS_STATE(SennaPerl_Index *, obj); |
|---|
| 140 | buf = malloc(sizeof(char) * SEN_MAX_PATH_SIZE); |
|---|
| 141 | |
|---|
| 142 | sen_index_path(index->index, buf, SEN_MAX_PATH_SIZE); |
|---|
| 143 | sv = newSVpv( buf, strlen(buf) ); |
|---|
| 144 | free(buf); |
|---|
| 145 | return sv; |
|---|
| 146 | } |
|---|
| 147 | |
|---|
| 148 | SV * |
|---|
| 149 | SennaPerl_Index_update(obj, key, oldvalue, newvalue) |
|---|
| 150 | SV *obj; |
|---|
| 151 | SV *key; |
|---|
| 152 | SV *oldvalue; |
|---|
| 153 | SV *newvalue; |
|---|
| 154 | { |
|---|
| 155 | SennaPerl_Index *index = XS_STATE(SennaPerl_Index *, obj); |
|---|
| 156 | void *pkey = SennaPerl_Global_sv2key(key); |
|---|
| 157 | char *oldc = NULL; |
|---|
| 158 | char *newc = NULL; |
|---|
| 159 | STRLEN oldl = 0; |
|---|
| 160 | STRLEN newl = 0; |
|---|
| 161 | |
|---|
| 162 | /* XXX - Do we need to use SvPVbyte here? */ |
|---|
| 163 | if ( oldvalue != NULL && SvPOK(oldvalue)) { |
|---|
| 164 | oldc = SvPV(oldvalue, oldl); |
|---|
| 165 | } |
|---|
| 166 | |
|---|
| 167 | if ( newvalue != NULL && SvPOK(newvalue)) { |
|---|
| 168 | newc = SvPV(newvalue, newl); |
|---|
| 169 | } |
|---|
| 170 | |
|---|
| 171 | return sen_rc2obj( |
|---|
| 172 | sen_index_upd( index->index, pkey, oldc, oldl, newc, newl ) |
|---|
| 173 | ); |
|---|
| 174 | } |
|---|
| 175 | |
|---|
| 176 | SV * |
|---|
| 177 | SennaPerl_Index_insert(obj, key, value) |
|---|
| 178 | SV *obj; |
|---|
| 179 | SV *key; |
|---|
| 180 | SV *value; |
|---|
| 181 | { |
|---|
| 182 | return SennaPerl_Index_update(obj, key, NULL, value); |
|---|
| 183 | } |
|---|
| 184 | |
|---|
| 185 | SV * |
|---|
| 186 | SennaPerl_Index_select(obj, query) |
|---|
| 187 | SV *obj; |
|---|
| 188 | SV *query; |
|---|
| 189 | { |
|---|
| 190 | sen_rc rc; |
|---|
| 191 | char *string; |
|---|
| 192 | STRLEN string_len; |
|---|
| 193 | sen_records *records = sen_records_open(sen_rec_document, sen_rec_none, 0); |
|---|
| 194 | sen_sel_operator op; |
|---|
| 195 | sen_select_optarg *optarg = NULL; |
|---|
| 196 | SennaPerl_Index *index = XS_STATE(SennaPerl_Index *, obj); |
|---|
| 197 | |
|---|
| 198 | if (query == NULL || ! SvOK(query)) { |
|---|
| 199 | return &PL_sv_undef; |
|---|
| 200 | } |
|---|
| 201 | string = SvPV(query, string_len); |
|---|
| 202 | |
|---|
| 203 | rc = sen_index_select(index->index, string, string_len, records, op, optarg); |
|---|
| 204 | if (rc != sen_success) { |
|---|
| 205 | sen_records_close(records); |
|---|
| 206 | croak("sen_index_select() failed"); |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | return SennaPerl_Records_new("Senna::Records", records); |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | #endif /* __SENNA_INDEX_C__ */ |
|---|
| 213 | |
|---|