#include "trie.h"
extern "C" {
namespace {
class FindCallback {
public:
typedef int (*Func)(void *, marisa_uint32, size_t);
FindCallback(Func func, void *first_arg)
: func_(func), first_arg_(first_arg) {}
FindCallback(const FindCallback &callback)
: func_(callback.func_), first_arg_(callback.first_arg_) {}
bool operator()(marisa::UInt32 key_id, std::size_t key_length) const {
return func_(first_arg_, key_id, key_length) != 0;
}
private:
Func func_;
void *first_arg_;
// Disallows assignment.
FindCallback &operator=(const FindCallback &);
};
class PredictCallback {
public:
typedef int (*Func)(void *, marisa_uint32, const char *, size_t);
PredictCallback(Func func, void *first_arg)
: func_(func), first_arg_(first_arg) {}
PredictCallback(const PredictCallback &callback)
: func_(callback.func_), first_arg_(callback.first_arg_) {}
bool operator()(marisa::UInt32 key_id, const std::string &key) const {
return func_(first_arg_, key_id, key.c_str(), key.length()) != 0;
}
private:
Func func_;
void *first_arg_;
// Disallows assignment.
PredictCallback &operator=(const PredictCallback &);
};
} // namespace
struct marisa_trie_ {
public:
marisa_trie_() : trie(), mapper() {}
marisa::Trie trie;
marisa::Mapper mapper;
private:
// Disallows copy and assignment.
marisa_trie_(const marisa_trie_ &);
marisa_trie_ &operator=(const marisa_trie_ &);
};
marisa_status marisa_init(marisa_trie **h) {
if ((h == NULL) || (*h != NULL)) {
return MARISA_HANDLE_ERROR;
}
*h = new (std::nothrow) marisa_trie_();
return (*h != NULL) ? MARISA_OK : MARISA_MEMORY_ERROR;
}
marisa_status marisa_end(marisa_trie *h) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
delete h;
return MARISA_OK;
}
marisa_status marisa_build(marisa_trie *h, const char * const *keys,
size_t num_keys, const size_t *key_lengths, const double *key_weights,
marisa_uint32 *key_ids, int flags) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.build(keys, num_keys, key_lengths, key_weights, key_ids, flags);
h->mapper.clear();
return MARISA_OK;
}
marisa_status marisa_mmap(marisa_trie *h, const char *filename,
long offset, int whence) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.mmap(&h->mapper, filename, offset, whence);
return MARISA_OK;
}
marisa_status marisa_map(marisa_trie *h, const void *ptr, size_t size) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.map(ptr, size);
h->mapper.clear();
return MARISA_OK;
}
marisa_status marisa_load(marisa_trie *h, const char *filename,
long offset, int whence) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.load(filename, offset, whence);
h->mapper.clear();
return MARISA_OK;
}
marisa_status marisa_fread(marisa_trie *h, FILE *file) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.fread(file);
h->mapper.clear();
return MARISA_OK;
}
marisa_status marisa_read(marisa_trie *h, int fd) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.read(fd);
h->mapper.clear();
return MARISA_OK;
}
marisa_status marisa_save(const marisa_trie *h, const char *filename,
int trunc_flag, long offset, int whence) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.save(filename, trunc_flag != 0, offset, whence);
return MARISA_OK;
}
marisa_status marisa_fwrite(const marisa_trie *h, FILE *file) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.fwrite(file);
return MARISA_OK;
}
marisa_status marisa_write(const marisa_trie *h, int fd) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.write(fd);
return MARISA_OK;
}
marisa_status marisa_restore(const marisa_trie *h, marisa_uint32 key_id,
char *key_buf, size_t key_buf_size, size_t *key_length) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (key_length == NULL) {
return MARISA_PARAM_ERROR;
}
*key_length = h->trie.restore(key_id, key_buf, key_buf_size);
return MARISA_OK;
}
marisa_status marisa_lookup(const marisa_trie *h,
const char *ptr, size_t length, marisa_uint32 *key_id) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (key_id == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*key_id = h->trie.lookup(ptr);
} else {
*key_id = h->trie.lookup(ptr, length);
}
return MARISA_OK;
}
marisa_status marisa_find(const marisa_trie *h,
const char *ptr, size_t length,
marisa_uint32 *key_ids, size_t *key_lengths,
size_t max_num_results, size_t *num_results) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (num_results == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*num_results = h->trie.find(ptr, key_ids, key_lengths, max_num_results);
} else {
*num_results = h->trie.find(ptr, length,
key_ids, key_lengths, max_num_results);
}
return MARISA_OK;
}
marisa_status marisa_find_first(const marisa_trie *h,
const char *ptr, size_t length,
marisa_uint32 *key_id, size_t *key_length) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (key_id == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*key_id = h->trie.find_first(ptr, key_length);
} else {
*key_id = h->trie.find_first(ptr, length, key_length);
}
return MARISA_OK;
}
marisa_status marisa_find_last(const marisa_trie *h,
const char *ptr, size_t length,
marisa_uint32 *key_id, size_t *key_length) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (key_id == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*key_id = h->trie.find_last(ptr, key_length);
} else {
*key_id = h->trie.find_last(ptr, length, key_length);
}
return MARISA_OK;
}
marisa_status marisa_find_callback(const marisa_trie *h,
const char *ptr, size_t length,
int (*callback)(void *, marisa_uint32, size_t),
void *first_arg_to_callback) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (callback == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
h->trie.find_callback(ptr,
::FindCallback(callback, first_arg_to_callback));
} else {
h->trie.find_callback(ptr, length,
::FindCallback(callback, first_arg_to_callback));
}
return MARISA_OK;
}
marisa_status marisa_predict(const marisa_trie *h,
const char *ptr, size_t length, marisa_uint32 *key_ids,
size_t max_num_results, size_t *num_results) {
return marisa_predict_breadth_first(h, ptr, length,
key_ids, max_num_results, num_results);
}
marisa_status marisa_predict_breadth_first(const marisa_trie *h,
const char *ptr, size_t length, marisa_uint32 *key_ids,
size_t max_num_results, size_t *num_results) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (num_results == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*num_results = h->trie.predict_breadth_first(
ptr, key_ids, NULL, max_num_results);
} else {
*num_results = h->trie.predict_breadth_first(
ptr, length, key_ids, NULL, max_num_results);
}
return MARISA_OK;
}
marisa_status marisa_predict_depth_first(const marisa_trie *h,
const char *ptr, size_t length, marisa_uint32 *key_ids,
size_t max_num_results, size_t *num_results) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (num_results == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
*num_results = h->trie.predict_depth_first(
ptr, key_ids, NULL, max_num_results);
} else {
*num_results = h->trie.predict_depth_first(
ptr, length, key_ids, NULL, max_num_results);
}
return MARISA_OK;
}
marisa_status marisa_predict_callback(const marisa_trie *h,
const char *ptr, size_t length,
int (*callback)(void *, marisa_uint32, const char *, size_t),
void *first_arg_to_callback) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
} else if (callback == NULL) {
return MARISA_PARAM_ERROR;
}
if (length == MARISA_ZERO_TERMINATED) {
h->trie.predict_callback(ptr,
::PredictCallback(callback, first_arg_to_callback));
} else {
h->trie.predict_callback(ptr, length,
::PredictCallback(callback, first_arg_to_callback));
}
return MARISA_OK;
}
size_t marisa_get_num_tries(const marisa_trie *h) {
return (h != NULL) ? h->trie.num_tries() : 0;
}
size_t marisa_get_num_keys(const marisa_trie *h) {
return (h != NULL) ? h->trie.num_keys() : 0;
}
size_t marisa_get_num_nodes(const marisa_trie *h) {
return (h != NULL) ? h->trie.num_nodes() : 0;
}
size_t marisa_get_total_size(const marisa_trie *h) {
return (h != NULL) ? h->trie.total_size() : 0;
}
marisa_status marisa_clear(marisa_trie *h) {
if (h == NULL) {
return MARISA_HANDLE_ERROR;
}
h->trie.clear();
h->mapper.clear();
return MARISA_OK;
}
} // extern "C"