Senna
view release on metacpan or search on metacpan
lib/Senna.xs view on Meta::CPAN
char *path;
int key_size;
int flags;
int initial_n_segments;
sen_encoding encoding;
PREINIT:
sen_index *index;
SV *sv;
CODE:
index = sen_index_create(path, key_size, flags, initial_n_segments, encoding);
if (index == NULL)
croak ("Failed to create senna index");
XS_STRUCT2OBJ(sv, class, index);
RETVAL = sv;
OUTPUT:
RETVAL
SV *
SIndex_xs_open(class, path)
char *class;
char *path;
PREINIT:
sen_index *index;
int key_size;
SV *sv;
CODE:
index = sen_index_open(path);
if (index == NULL)
croak ("Failed to open senna index");
/* Make sure that index does not have some unsupported key_size
*/
sen_index_info(index, &key_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
if (key_size != SEN_VARCHAR_KEY && key_size != SEN_INT_KEY)
croak("Senna::Index does not support key_size other than 0 or 4");
XS_STRUCT2OBJ(sv, class, index);
SvREADONLY_on(sv);
RETVAL = sv;
OUTPUT:
RETVAL
void
SIndex_info(self)
SV *self;
PREINIT:
sen_index *index;
int key_size;
int flags;
int initial_n_segments;
sen_encoding encoding;
unsigned int nrecords_keys;
unsigned int file_size_keys;
unsigned int nrecords_lexicon;
unsigned int file_size_lexicon;
unsigned int inv_seg_size;
unsigned int inv_chunk_size;
sen_rc rc;
PPCODE:
index = XS_STATE(sen_index *, self);
rc = sen_index_info(index,
&key_size, &flags, &initial_n_segments, &encoding,
&nrecords_keys, &file_size_keys, &nrecords_lexicon,
&file_size_lexicon, &inv_seg_size, &inv_chunk_size
);
if (rc != sen_success)
croak("Failed to call sen_index_info: %d", rc);
EXTEND(SP, 10);
mPUSHi(key_size);
mPUSHi(flags);
mPUSHi(initial_n_segments);
mPUSHi(encoding);
mPUSHi(nrecords_keys);
mPUSHi(file_size_keys);
mPUSHi(nrecords_lexicon);
mPUSHi(file_size_lexicon);
mPUSHi(inv_seg_size);
mPUSHi(inv_chunk_size);
SV *
SIndex_path(self)
SV *self;
PREINIT:
sen_index *index;
char path[SEN_MAX_PATH_SIZE];
CODE:
index = XS_STATE(sen_index *, self);
sen_index_path(index, path, SEN_MAX_PATH_SIZE);
RETVAL = newSVpv(path, 0);
OUTPUT:
RETVAL
SV *
SIndex_close(obj)
SV *obj;
PREINIT:
sen_index *index;
CODE:
index = XS_STATE(sen_index *, obj);
RETVAL = sen_rc2obj(sen_index_close(index));
OUTPUT:
RETVAL
SV *
SIndex_remove(self)
SV *self;
PREINIT:
sen_index *index;
char path[SEN_MAX_PATH_SIZE];
CODE:
index = XS_STATE(sen_index *, self);
if (! sen_index_path(index, path, SEN_MAX_PATH_SIZE))
croak("sen_index_path did not return a proper path");
RETVAL = sen_rc2obj(sen_index_remove(path));
OUTPUT:
RETVAL
SV *
SIndex_xs_rename(self, new)
SV *self;
char *new;
PREINIT:
sen_index *index;
char path[SEN_MAX_PATH_SIZE];
CODE:
index = XS_STATE(sen_index *, self);
if (! sen_index_path(index, path, SEN_MAX_PATH_SIZE))
croak("sen_index_path did not return a proper path");
RETVAL = sen_rc2obj(sen_index_rename(path, new));
OUTPUT:
RETVAL
void
SIndex_xs_select(self, query_sv, records, op_sv, optarg_sv)
SV *self;
SV *query_sv;
SV *records;
SV *op_sv;
SV *optarg_sv;
PREINIT:
SV *sv;
STRLEN query_len = 0;
sen_index *index;
sen_rc rc;
sen_records *r;
sen_select_optarg *optarg = NULL;
sen_sel_operator op = SvOK(op_sv) ? SvIV(op_sv) : 0;
char *query = NULL;
int need_optarg_free = 0;
int need_records_free = 0;
PPCODE:
index = XS_STATE(sen_index *, self);
if ( SvOK(query_sv) ) {
query = SvPV(query_sv, query_len);
}
if (! SvOK(records)) {
r = sen_records_open(sen_rec_document, sen_rec_none, 0);
need_records_free = 1;
} else {
r = XS_STATE(sen_records *, records);
}
if (SvOK(optarg_sv)) {
optarg = XS_STATE(sen_select_optarg *, optarg_sv);
if (optarg != NULL) {
Newz(1234, optarg, 1, sen_select_optarg);
optarg->mode = sen_sel_exact;
need_optarg_free = 1;
}
}
rc = sen_index_select(
index,
query,
#if (SENNA_MAJOR_VERSION >= 1)
query_len,
#endif
r,
op,
optarg
);
if (need_optarg_free) {
Safefree(optarg);
}
if (rc != sen_success) {
Safefree(r);
croak ("Failed to execute sen_index_select: rc = %d", rc);
}
if (GIMME_V == G_VOID) {
if (need_records_free) sen_records_close(r);
/* no op */;
} else if (GIMME_V == G_SCALAR) {
XS_STRUCT2OBJ(sv, "Senna::Records", r);
XPUSHs(sv);
} else {
char keybuf[SEN_MAX_KEY_SIZE];
int score;
int hits;
hits = sen_records_nhits(r);
if (hits <= 0)
return;
EXTEND(SP, hits);
while (sen_records_next(r, &keybuf, SEN_MAX_KEY_SIZE, &score)) {
/* Construct Senna::Record object */
lib/Senna.xs view on Meta::CPAN
new_values = SvOK(new) ? XS_STATE(sen_values *, new) : NULL;
sv2senna_key(index, key, &void_key);
RETVAL = sen_rc2obj(sen_index_update(index, key, section, old_values, new_values));
OUTPUT:
RETVAL
SV *
SIndex_xs_query_exec(self, query, op = sen_sel_or)
SV *self;
SV *query;
sen_sel_operator op;
PREINIT:
sen_index *i;
sen_query *q;
sen_records *r;
sen_rc rc;
SV *sv;
CODE:
i = XS_STATE(sen_index *, self);
q = XS_STATE(sen_query *, query);
Newz(1234, r, 1, sen_records);
rc = sen_query_exec(i, q, r, op);
if (rc != sen_success)
croak("sen_query_exec failed: rc = %d", rc);
XS_STRUCT2OBJ(sv, "Senna::Records", r);
RETVAL = sv;
OUTPUT:
RETVAL
MODULE = Senna PACKAGE = Senna::Records PREFIX=SRecords_
SV *
SRecords_xs_open(class, record_unit, subrec_unit, max_n_subrecs)
char *class;
sen_rec_unit record_unit;
sen_rec_unit subrec_unit;
unsigned int max_n_subrecs;
PREINIT:
sen_records *r;
SV *sv;
CODE:
r = sen_records_open(record_unit, subrec_unit, max_n_subrecs);
if (r == NULL)
croak("Failed to open sen_records");
XS_STRUCT2OBJ(sv, class, r);
RETVAL = sv;
OUTPUT:
RETVAL
void
SRecords_xs_next(self)
SV *self;
PREINIT:
sen_records *r;
sen_rc rc;
PPCODE:
r = XS_STATE(sen_records *, self);
if (GIMME_V == G_SCALAR) {
/* If we're being called in scalar context, then just return if
* we have a next record or not
*/
rc = sen_records_next(r, NULL, 0, NULL);
XPUSHs(rc == 0 ? &PL_sv_no : &PL_sv_yes);
} else {
/* Otherwise, grab the next entry along with other metadata */
SV *key_sv;
int score = 0;
int key_size = 0;
int section = 0;
int pos = 0;
int n_subrecs = 0;
sen_sym_info(r->keys, &key_size, NULL, NULL, NULL, NULL);
if (key_size == SEN_INT_KEY) {
long key;
rc = sen_records_next(r, &key, 0, &score);
sen_record_info(r, sen_records_curr_rec(r),
NULL, 0, NULL,
§ion, &pos, NULL, &n_subrecs);
key_sv = newSViv(key);
} else {
char key[SEN_MAX_KEY_SIZE];
rc = sen_records_next(r, &key, SEN_MAX_KEY_SIZE, &score);
sen_record_info(r, sen_records_curr_rec(r),
NULL, 0, NULL,
§ion, &pos, NULL, &n_subrecs);
key_sv = newSVpv(key, 0);
}
if (rc != 0) {
XPUSHs(key_sv);
XPUSHs(sv_2mortal(newSViv(score)));
XPUSHs(sv_2mortal(newSViv(section)));
XPUSHs(sv_2mortal(newSViv(pos)));
XPUSHs(sv_2mortal(newSViv(n_subrecs)));
}
}
SV *
SRecords_rewind(self)
SV *self;
PREINIT:
sen_records *r;
CODE:
r = XS_STATE(sen_records *, self);
RETVAL = sen_rc2obj(sen_records_rewind(r));
OUTPUT:
RETVAL
int
SRecords_nhits(self)
SV *self;
lib/Senna.xs view on Meta::CPAN
sen_id id;
unsigned int value;
PREINIT:
sen_sym *sym;
CODE:
sym = XS_STATE(sen_sym *, self);
RETVAL = sen_rc2obj(sen_sym_pocket_set(sym, id, value));
OUTPUT:
RETVAL
sen_id
SSymbol_xs_next(self, id)
SV *self;
sen_id id;
PREINIT:
sen_sym *sym;
CODE:
sym = XS_STATE(sen_sym *, self);
RETVAL = sen_sym_next(sym, id);
OUTPUT:
RETVAL
MODULE = Senna PACKAGE = Senna::Set PREFIX=SSet_
SV *
SSet_xs_open(class, key_size = SEN_VARCHAR_KEY, value_size = 0, n_entries = 0)
char *class;
unsigned int key_size;
unsigned int value_size;
unsigned int n_entries;
PREINIT:
SV *sv;
sen_set *set;
CODE:
set = sen_set_open(key_size, value_size, n_entries);
XS_STRUCT2OBJ(sv, class, set);
RETVAL = sv;
OUTPUT:
RETVAL
SV *
SSet_close(self)
SV *self;
PREINIT:
sen_set *set;
CODE:
set = XS_STATE(sen_set *, self);
RETVAL = sen_rc2obj(sen_set_close(set));
OUTPUT:
RETVAL
void
SSet_info(self)
SV *self;
PREINIT:
sen_rc rc;
sen_set *set;
unsigned int key_size;
unsigned int value_size;
unsigned int n_entries;
PPCODE:
set = XS_STATE(sen_set *, self);
rc = sen_set_info(set, &key_size, &value_size, &n_entries);
if (rc != sen_success)
croak ("Failed to call sen_set_info: %d", rc);
EXTEND(SP, 3);
PUSHs(sv_2mortal(newSViv(key_size)));
PUSHs(sv_2mortal(newSViv(value_size)));
PUSHs(sv_2mortal(newSViv(n_entries)));
MODULE = Senna PACKAGE = Senna::Snippet PREFIX=SSnip_
SV *
SSnip_xs_open(class, encoding, flags, width, max_results, default_open_tag_sv, default_close_tag_sv, mapping_sv)
char* class;
sen_encoding encoding;
int flags;
size_t width;
unsigned int max_results;
SV* default_open_tag_sv;
SV* default_close_tag_sv;
SV* mapping_sv;
PREINIT:
int mapping;
sen_snip *snip;
sen_perl_snip *perl_snip;
char *default_open_tag = NULL;
char *default_close_tag = NULL;
STRLEN default_open_tag_len = 0;
STRLEN default_close_tag_len = 0;
SV *sv;
CODE:
if (max_results > MAX_SNIP_RESULT_COUNT)
croak("Senna::Snippet::new(): max_results exceeds MAX_SNIP_RESULT_COUNT (%d)", MAX_SNIP_RESULT_COUNT);
if (SvPOK(default_open_tag_sv) && sv_len(default_open_tag_sv))
default_open_tag = SvPV(default_open_tag_sv, default_open_tag_len);
if (SvPOK(default_close_tag_sv) && sv_len(default_close_tag_sv))
default_close_tag = SvPV(default_close_tag_sv, default_close_tag_len);
mapping = SvTRUE(mapping_sv) ? -1 : 0;
Newz(1234, perl_snip, 1, sen_perl_snip);
if (default_open_tag == NULL)
croak("Senna::Snippet::new(): default_open_tag must be specified");
if (default_close_tag == NULL)
croak("Senna::Snippet::new(): default_close_tag must be specified");
perl_snip->open_tags_size = 1;
Newz(1234, perl_snip->open_tags, 1, char *);
Newz(1234, perl_snip->open_tags[perl_snip->open_tags_size - 1], default_open_tag_len + 1, char);
Copy(default_open_tag, perl_snip->open_tags[perl_snip->open_tags_size - 1], default_open_tag_len, char);
default_open_tag = perl_snip->open_tags[perl_snip->open_tags_size - 1];
perl_snip->close_tags_size = 1;
Newz(1234, perl_snip->close_tags, 1, char *);
lib/Senna.xs view on Meta::CPAN
sen_perl_snip *snip;
STRLEN opentag_len = 0;
STRLEN closetag_len = 0;
CODE:
snip = XS_STATE(sen_perl_snip *, self);
if (SvPOK(opentag_sv) && sv_len(opentag_sv) > 0) {
opentag = SvPV(opentag_sv, opentag_len);
snip->open_tags_size++;
Renew(snip->open_tags, snip->open_tags_size, char *);
Newz(1234, snip->open_tags[snip->open_tags_size - 1], opentag_len + 1, char);
Copy(opentag, snip->open_tags[snip->open_tags_size - 1], opentag_len, char);
opentag = snip->open_tags[snip->open_tags_size - 1];
}
if (SvPOK(closetag_sv) && sv_len(closetag_sv) > 0) {
closetag = SvPV(closetag_sv, closetag_len);
snip->close_tags_size++;
Renew(snip->close_tags, snip->close_tags_size, char *);
Newz(1234, snip->close_tags[snip->close_tags_size - 1], closetag_len + 1, char);
Copy(closetag, snip->close_tags[snip->close_tags_size - 1], closetag_len, char);
closetag = snip->close_tags[snip->close_tags_size - 1];
}
RETVAL = sen_rc2obj(
sen_snip_add_cond(
snip->snip,
keyword,
#if (SENNA_MAJOR_VERSION >= 1)
strlen(keyword),
#endif
opentag,
#if (SENNA_MAJOR_VERSION >= 1)
opentag_len,
#endif
closetag
#if (SENNA_MAJOR_VERSION >= 1)
,
closetag_len
#endif
)
);
OUTPUT:
RETVAL
void
SSnip_xs_exec(self, string)
SV *self;
char *string;
PREINIT:
sen_perl_snip *snip;
unsigned int nresults;
char *result;
#if (SENNA_MAJOR_VERSION >= 1)
unsigned int max_tagged_len;
#else
size_t max_tagged_len;
#endif
int i;
sen_rc rc;
PPCODE:
snip = XS_STATE(sen_perl_snip *, self);
sen_snip_exec(
snip->snip,
string,
#if (SENNA_MAJOR_VERSION >= 1)
strlen(string),
#endif
&nresults,
&max_tagged_len
);
EXTEND(SP, nresults);
Newz(1234, result, max_tagged_len, char);
for(i = 0; i < nresults; i++) {
rc = sen_snip_get_result(
snip->snip,
i,
result
#if (SENNA_MAJOR_VERSION >= 1)
,
&max_tagged_len
#endif
);
if (rc != sen_success)
croak("Call to sen_snip_get_result returned %d", rc);
PUSHs(sv_2mortal(newSVpv(result, 0)));
}
Safefree(result);
void
DESTROY(self)
SV *self;
PREINIT:
sen_perl_snip *snip;
int i;
PPCODE:
snip = XS_STATE(sen_perl_snip *, self);
sen_snip_close(snip->snip);
for(i = 0; i < snip->open_tags_size; i++) {
Safefree(snip->open_tags[i]);
}
Safefree(snip->open_tags);
for(i = 0; i < snip->close_tags_size; i++) {
Safefree(snip->close_tags[i]);
}
Safefree(snip->close_tags);
MODULE = Senna PACKAGE = Senna::OptArg::Sort PREFIX=SOSort_
SV *
SOSort_xs_new(class, mode, compar = NULL, compar_arg = NULL)
char *class;
sen_sort_mode mode;
CV *compar;
AV *compar_arg;
PREINIT:
sen_sort_optarg *optarg;
SV *sv;
CODE:
Newz(1234, optarg, 1, sen_sort_optarg);
optarg->mode = mode;
if (SvOK(compar)) {
optarg->compar = &sen_sort_optarg_cb;
/* The callback arguments are always the CV of the callback,
* the AV of the argument list, and key_size of the index.
*/
Newz(1234, optarg->compar_arg, 2, void *);
((void **)optarg->compar_arg)[0] = compar;
if (SvOK(compar_arg) && SvTYPE(compar_arg) == SVt_PVCV)
((void **)optarg->compar_arg)[1] = SvREFCNT_inc(compar_arg);
}
XS_STRUCT2OBJ(sv, class, optarg);
RETVAL = sv;
OUTPUT:
RETVAL
sen_sort_mode
SOSort_mode(self)
SV *self;
PREINIT:
sen_sort_optarg *optarg;
CODE:
optarg = XS_STATE(sen_sort_optarg *, self);
RETVAL = optarg->mode;
OUTPUT:
RETVAL
CV *
SOSort_compar(self)
SV *self;
PREINIT:
sen_sort_optarg *optarg;
void **args;
CODE:
optarg = XS_STATE(sen_sort_optarg *, self);
/* The CV is always placed in the first element of ->compar_arg */
args = (void **) optarg->compar_arg;
if (args[0] == NULL)
XSRETURN_UNDEF;
RETVAL = (CV *) args[0];
OUTPUT:
RETVAL
void
SOSort_compar_arg(self)
SV *self;
PREINIT:
sen_sort_optarg *optarg;
void **args;
PPCODE:
optarg = XS_STATE(sen_sort_optarg *, self);
/* The CV is always placed in the second element of ->func_arg */
args = (void **) optarg->compar_arg;
if (GIMME_V == G_SCALAR) {
AV *av;
if (args[1] == NULL)
return;
av = (AV *) args[1];
EXTEND(SP, 1);
PUSHs(newRV_noinc((SV *) av));
} else {
AV *av;
int i;
int len;
SV **svr;
av = (AV *) args[1];
len = av_len(av) + 1;
if (len <= 0)
return;
EXTEND(SP, len);
for (i = 0; i < len; i++) {
svr = av_fetch(av, i - 1, 0);
if (*svr != NULL && SvOK(*svr)) {
PUSHs(*svr);
}
}
}
void
SOSort_DESTROY(self)
SV *self;
PREINIT:
sen_sort_optarg *optarg;
CODE:
optarg = XS_STATE(sen_sort_optarg *, self);
if (optarg->compar_arg != NULL) {
void **args = (void **) optarg->compar_arg;
if (args[0] != NULL)
SvREFCNT_dec((CV *) args[0]);
if (args[1] != NULL)
SvREFCNT_dec((AV *) args[1]);
Safefree(args);
}
Safefree(optarg);
MODULE = Senna PACKAGE = Senna::OptArg::Select PREFIX=SOSelect_
SV *
SOSelect_xs_new(class, mode, similarity_threshold, max_interval, weight_vector, func = NULL, func_args = NULL)
char *class;
sen_sel_mode mode;
int similarity_threshold;
int max_interval;
lib/Senna.xs view on Meta::CPAN
if (SvOK(func)) {
int key_size;
void **args;
optarg->func = &sen_select_optarg_cb;
/* The callback arguments are always the CV of the callback,
* the AV of the argument list, and key_size of the index.
*/
Newz(1234, args, 2, void *);
args[0] = (void *) func;
if (SvOK(func_args))
args[1] = (void *) func_args;
optarg->func_arg = (void *) args;
}
XS_STRUCT2OBJ(sv, class, optarg);
RETVAL = sv;
OUTPUT:
RETVAL
sen_sel_mode
SOSelect_mode(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
CODE:
optarg = XS_STATE(sen_select_optarg *, self);
RETVAL = optarg->mode;
OUTPUT:
RETVAL
int
SOSelect_similarity_threshold(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
CODE:
optarg = XS_STATE(sen_select_optarg *, self);
RETVAL = optarg->similarity_threshold;
OUTPUT:
RETVAL
int
SOSelect_max_interval(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
CODE:
optarg = XS_STATE(sen_select_optarg *, self);
RETVAL = optarg->max_interval;
OUTPUT:
RETVAL
void
SOSelect_weight_vector(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
PPCODE:
optarg = XS_STATE(sen_select_optarg *, self);
if (optarg->vector_size <= 0)
return;
if (GIMME_V == G_SCALAR) {
AV *av = newAV();
int i;
EXTEND(SP, 1);
av_extend(av, optarg->vector_size - 1);
for (i = 0; i < optarg->vector_size; i++) {
av_push(av, newSViv(optarg->weight_vector[i]));
}
PUSHs(newRV_inc((SV *) av));
} else {
int i;
EXTEND(SP, optarg->vector_size);
for (i = 0; i < optarg->vector_size; i++) {
PUSHs(newSViv(optarg->weight_vector[i]));
}
}
CV *
SOSelect_func(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
void **args;
CODE:
optarg = XS_STATE(sen_select_optarg *, self);
/* The CV is always placed in the first element of ->func_arg */
args = (void **) optarg->func_arg;
if (args[0] == NULL)
XSRETURN_UNDEF;
RETVAL = (CV *) args[0];
OUTPUT:
RETVAL
void
SOSelect_func_arg(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
void **args;
PPCODE:
optarg = XS_STATE(sen_select_optarg *, self);
/* The CV is always placed in the second element of ->func_arg */
args = (void **) optarg->func_arg;
if (GIMME_V == G_SCALAR) {
AV *av;
if (args[1] == NULL)
return;
av = (AV *) args[1];
EXTEND(SP, 1);
PUSHs(newRV_noinc((SV *) av));
} else {
AV *av;
int i;
int len;
SV **svr;
av = (AV *) args[1];
len = av_len(av) + 1;
if (len <= 0)
return;
EXTEND(SP, len);
for (i = 0; i < len; i++) {
svr = av_fetch(av, i - 1, 0);
if (*svr != NULL && SvOK(*svr)) {
PUSHs(*svr);
}
}
}
SV *
SOSelect_DESTROY(self)
SV *self;
PREINIT:
sen_select_optarg *optarg;
CODE:
optarg = XS_STATE(sen_select_optarg *, self);
if (optarg->weight_vector != NULL)
Safefree(optarg->weight_vector);
if (optarg->func_arg != NULL) {
void **args = (void **) optarg->func_arg;
if (args[0] != NULL)
SvREFCNT_dec((CV *) args[0]);
if (args[1] != NULL)
SvREFCNT_dec((AV *) args[1]);
Safefree(optarg->func_arg);
}
Safefree(optarg);
MODULE = Senna PACKAGE = Senna::Values PREFIX=SValues_
SV *
SValues_open(class)
char *class;
PREINIT:
( run in 1.410 second using v1.01-cache-2.11-cpan-5511b514fd6 )