/* sorted-trigram-language-model.c generated by valac 0.26.2, the Vala compiler
 * generated from sorted-trigram-language-model.vala, do not modify */

/*
 * Copyright (C) 2012-2014 Daiki Ueno <ueno@gnu.org>
 * Copyright (C) 2012-2014 Red Hat, Inc.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <glib.h>
#include <glib-object.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
#include <gee.h>
#include <float.h>
#include <math.h>


#define KKC_TYPE_LANGUAGE_MODEL (kkc_language_model_get_type ())
#define KKC_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_LANGUAGE_MODEL, KkcLanguageModel))
#define KKC_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_LANGUAGE_MODEL, KkcLanguageModelClass))
#define KKC_IS_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_LANGUAGE_MODEL))
#define KKC_IS_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_LANGUAGE_MODEL))
#define KKC_LANGUAGE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_LANGUAGE_MODEL, KkcLanguageModelClass))

typedef struct _KkcLanguageModel KkcLanguageModel;
typedef struct _KkcLanguageModelClass KkcLanguageModelClass;
typedef struct _KkcLanguageModelPrivate KkcLanguageModelPrivate;

#define KKC_TYPE_LANGUAGE_MODEL_ENTRY (kkc_language_model_entry_get_type ())
typedef struct _KkcLanguageModelEntry KkcLanguageModelEntry;

#define KKC_TYPE_UNIGRAM_LANGUAGE_MODEL (kkc_unigram_language_model_get_type ())
#define KKC_UNIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_UNIGRAM_LANGUAGE_MODEL, KkcUnigramLanguageModel))
#define KKC_IS_UNIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_UNIGRAM_LANGUAGE_MODEL))
#define KKC_UNIGRAM_LANGUAGE_MODEL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), KKC_TYPE_UNIGRAM_LANGUAGE_MODEL, KkcUnigramLanguageModelIface))

typedef struct _KkcUnigramLanguageModel KkcUnigramLanguageModel;
typedef struct _KkcUnigramLanguageModelIface KkcUnigramLanguageModelIface;

#define KKC_TYPE_BIGRAM_LANGUAGE_MODEL (kkc_bigram_language_model_get_type ())
#define KKC_BIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_BIGRAM_LANGUAGE_MODEL, KkcBigramLanguageModel))
#define KKC_IS_BIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_BIGRAM_LANGUAGE_MODEL))
#define KKC_BIGRAM_LANGUAGE_MODEL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), KKC_TYPE_BIGRAM_LANGUAGE_MODEL, KkcBigramLanguageModelIface))

typedef struct _KkcBigramLanguageModel KkcBigramLanguageModel;
typedef struct _KkcBigramLanguageModelIface KkcBigramLanguageModelIface;

#define KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL (kkc_sorted_bigram_language_model_get_type ())
#define KKC_SORTED_BIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL, KkcSortedBigramLanguageModel))
#define KKC_SORTED_BIGRAM_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL, KkcSortedBigramLanguageModelClass))
#define KKC_IS_SORTED_BIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL))
#define KKC_IS_SORTED_BIGRAM_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL))
#define KKC_SORTED_BIGRAM_LANGUAGE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL, KkcSortedBigramLanguageModelClass))

typedef struct _KkcSortedBigramLanguageModel KkcSortedBigramLanguageModel;
typedef struct _KkcSortedBigramLanguageModelClass KkcSortedBigramLanguageModelClass;
typedef struct _KkcSortedBigramLanguageModelPrivate KkcSortedBigramLanguageModelPrivate;

#define KKC_TYPE_TRIGRAM_LANGUAGE_MODEL (kkc_trigram_language_model_get_type ())
#define KKC_TRIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_TRIGRAM_LANGUAGE_MODEL, KkcTrigramLanguageModel))
#define KKC_IS_TRIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_TRIGRAM_LANGUAGE_MODEL))
#define KKC_TRIGRAM_LANGUAGE_MODEL_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), KKC_TYPE_TRIGRAM_LANGUAGE_MODEL, KkcTrigramLanguageModelIface))

typedef struct _KkcTrigramLanguageModel KkcTrigramLanguageModel;
typedef struct _KkcTrigramLanguageModelIface KkcTrigramLanguageModelIface;

#define KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL (kkc_sorted_trigram_language_model_get_type ())
#define KKC_SORTED_TRIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, KkcSortedTrigramLanguageModel))
#define KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, KkcSortedTrigramLanguageModelClass))
#define KKC_IS_SORTED_TRIGRAM_LANGUAGE_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL))
#define KKC_IS_SORTED_TRIGRAM_LANGUAGE_MODEL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL))
#define KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, KkcSortedTrigramLanguageModelClass))

typedef struct _KkcSortedTrigramLanguageModel KkcSortedTrigramLanguageModel;
typedef struct _KkcSortedTrigramLanguageModelClass KkcSortedTrigramLanguageModelClass;
typedef struct _KkcSortedTrigramLanguageModelPrivate KkcSortedTrigramLanguageModelPrivate;

#define KKC_TYPE_INDEX_FILE (kkc_index_file_get_type ())
#define KKC_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_INDEX_FILE, KkcIndexFile))
#define KKC_IS_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_INDEX_FILE))
#define KKC_INDEX_FILE_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), KKC_TYPE_INDEX_FILE, KkcIndexFileIface))

typedef struct _KkcIndexFile KkcIndexFile;
typedef struct _KkcIndexFileIface KkcIndexFileIface;

#define KKC_TYPE_BLOOM_FILTER (kkc_bloom_filter_get_type ())
#define KKC_BLOOM_FILTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_BLOOM_FILTER, KkcBloomFilter))
#define KKC_BLOOM_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_BLOOM_FILTER, KkcBloomFilterClass))
#define KKC_IS_BLOOM_FILTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_BLOOM_FILTER))
#define KKC_IS_BLOOM_FILTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_BLOOM_FILTER))
#define KKC_BLOOM_FILTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_BLOOM_FILTER, KkcBloomFilterClass))

typedef struct _KkcBloomFilter KkcBloomFilter;
typedef struct _KkcBloomFilterClass KkcBloomFilterClass;
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))

#define KKC_TYPE_METADATA_FILE (kkc_metadata_file_get_type ())
#define KKC_METADATA_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_METADATA_FILE, KkcMetadataFile))
#define KKC_METADATA_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_METADATA_FILE, KkcMetadataFileClass))
#define KKC_IS_METADATA_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_METADATA_FILE))
#define KKC_IS_METADATA_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_METADATA_FILE))
#define KKC_METADATA_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_METADATA_FILE, KkcMetadataFileClass))

typedef struct _KkcMetadataFile KkcMetadataFile;
typedef struct _KkcMetadataFileClass KkcMetadataFileClass;

#define KKC_TYPE_LANGUAGE_MODEL_METADATA (kkc_language_model_metadata_get_type ())
#define KKC_LANGUAGE_MODEL_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_LANGUAGE_MODEL_METADATA, KkcLanguageModelMetadata))
#define KKC_LANGUAGE_MODEL_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_LANGUAGE_MODEL_METADATA, KkcLanguageModelMetadataClass))
#define KKC_IS_LANGUAGE_MODEL_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_LANGUAGE_MODEL_METADATA))
#define KKC_IS_LANGUAGE_MODEL_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_LANGUAGE_MODEL_METADATA))
#define KKC_LANGUAGE_MODEL_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_LANGUAGE_MODEL_METADATA, KkcLanguageModelMetadataClass))

typedef struct _KkcLanguageModelMetadata KkcLanguageModelMetadata;
typedef struct _KkcLanguageModelMetadataClass KkcLanguageModelMetadataClass;
#define _g_free0(var) (var = (g_free (var), NULL))

#define KKC_TYPE_MAPPED_INDEX_FILE (kkc_mapped_index_file_get_type ())
#define KKC_MAPPED_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_MAPPED_INDEX_FILE, KkcMappedIndexFile))
#define KKC_MAPPED_INDEX_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_MAPPED_INDEX_FILE, KkcMappedIndexFileClass))
#define KKC_IS_MAPPED_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_MAPPED_INDEX_FILE))
#define KKC_IS_MAPPED_INDEX_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_MAPPED_INDEX_FILE))
#define KKC_MAPPED_INDEX_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_MAPPED_INDEX_FILE, KkcMappedIndexFileClass))

typedef struct _KkcMappedIndexFile KkcMappedIndexFile;
typedef struct _KkcMappedIndexFileClass KkcMappedIndexFileClass;

#define KKC_TYPE_LOADED_INDEX_FILE (kkc_loaded_index_file_get_type ())
#define KKC_LOADED_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), KKC_TYPE_LOADED_INDEX_FILE, KkcLoadedIndexFile))
#define KKC_LOADED_INDEX_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), KKC_TYPE_LOADED_INDEX_FILE, KkcLoadedIndexFileClass))
#define KKC_IS_LOADED_INDEX_FILE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), KKC_TYPE_LOADED_INDEX_FILE))
#define KKC_IS_LOADED_INDEX_FILE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), KKC_TYPE_LOADED_INDEX_FILE))
#define KKC_LOADED_INDEX_FILE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), KKC_TYPE_LOADED_INDEX_FILE, KkcLoadedIndexFileClass))

typedef struct _KkcLoadedIndexFile KkcLoadedIndexFile;
typedef struct _KkcLoadedIndexFileClass KkcLoadedIndexFileClass;
#define _g_error_free0(var) ((var == NULL) ? NULL : (var = (g_error_free (var), NULL)))

struct _KkcLanguageModelEntry {
	gchar* input;
	gchar* output;
	guint id;
};

struct _KkcLanguageModel {
	GObject parent_instance;
	KkcLanguageModelPrivate * priv;
};

struct _KkcLanguageModelClass {
	GObjectClass parent_class;
	GeeCollection* (*unigram_entries) (KkcLanguageModel* self, const gchar* input);
	GeeCollection* (*entries) (KkcLanguageModel* self, const gchar* input);
	KkcLanguageModelEntry* (*get) (KkcLanguageModel* self, const gchar* input, const gchar* output);
	gboolean (*parse) (KkcLanguageModel* self, GError** error);
	void (*get_bos) (KkcLanguageModel* self, KkcLanguageModelEntry* result);
	void (*get_eos) (KkcLanguageModel* self, KkcLanguageModelEntry* result);
};

struct _KkcUnigramLanguageModelIface {
	GTypeInterface parent_iface;
	gdouble (*unigram_cost) (KkcUnigramLanguageModel* self, KkcLanguageModelEntry* entry);
	gdouble (*unigram_backoff) (KkcUnigramLanguageModel* self, KkcLanguageModelEntry* entry);
};

struct _KkcBigramLanguageModelIface {
	GTypeInterface parent_iface;
	gboolean (*has_bigram) (KkcBigramLanguageModel* self, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
	gdouble (*bigram_cost) (KkcBigramLanguageModel* self, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
	gdouble (*bigram_backoff) (KkcBigramLanguageModel* self, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
};

struct _KkcSortedBigramLanguageModel {
	KkcLanguageModel parent_instance;
	KkcSortedBigramLanguageModelPrivate * priv;
};

struct _KkcSortedBigramLanguageModelClass {
	KkcLanguageModelClass parent_class;
};

struct _KkcTrigramLanguageModelIface {
	GTypeInterface parent_iface;
	gboolean (*has_trigram) (KkcTrigramLanguageModel* self, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
	gdouble (*trigram_cost) (KkcTrigramLanguageModel* self, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
};

struct _KkcSortedTrigramLanguageModel {
	KkcSortedBigramLanguageModel parent_instance;
	KkcSortedTrigramLanguageModelPrivate * priv;
};

struct _KkcSortedTrigramLanguageModelClass {
	KkcSortedBigramLanguageModelClass parent_class;
};

struct _KkcIndexFileIface {
	GTypeInterface parent_iface;
	gchar* (*get_contents) (KkcIndexFile* self);
	gsize (*get_length) (KkcIndexFile* self);
};

struct _KkcSortedTrigramLanguageModelPrivate {
	KkcIndexFile* trigram_index;
	KkcBloomFilter* trigram_filter;
	guint32 last_value;
	guint32 last_pvalue;
	glong last_offset;
};


static gpointer kkc_sorted_trigram_language_model_parent_class = NULL;
extern gboolean kkc_use_mapped_index_file;
static KkcTrigramLanguageModelIface* kkc_sorted_trigram_language_model_kkc_trigram_language_model_parent_iface = NULL;

GType kkc_language_model_get_type (void) G_GNUC_CONST;
GType kkc_language_model_entry_get_type (void) G_GNUC_CONST;
KkcLanguageModelEntry* kkc_language_model_entry_dup (const KkcLanguageModelEntry* self);
void kkc_language_model_entry_free (KkcLanguageModelEntry* self);
void kkc_language_model_entry_copy (const KkcLanguageModelEntry* self, KkcLanguageModelEntry* dest);
void kkc_language_model_entry_destroy (KkcLanguageModelEntry* self);
GType kkc_unigram_language_model_get_type (void) G_GNUC_CONST;
GType kkc_bigram_language_model_get_type (void) G_GNUC_CONST;
GType kkc_sorted_bigram_language_model_get_type (void) G_GNUC_CONST;
GType kkc_trigram_language_model_get_type (void) G_GNUC_CONST;
GType kkc_sorted_trigram_language_model_get_type (void) G_GNUC_CONST;
GType kkc_index_file_get_type (void) G_GNUC_CONST;
GType kkc_bloom_filter_get_type (void) G_GNUC_CONST;
#define KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, KkcSortedTrigramLanguageModelPrivate))
enum  {
	KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_DUMMY_PROPERTY
};
static glong kkc_sorted_trigram_language_model_trigram_offset (KkcSortedTrigramLanguageModel* self, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
glong kkc_sorted_bigram_language_model_bigram_offset (KkcSortedBigramLanguageModel* self, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
gboolean kkc_bloom_filter_contains (KkcBloomFilter* self, guint32 b0, guint32 b1);
glong kkc_language_model_utils_bsearch_ngram (void* memory, glong start_offset, glong end_offset, glong record_size, guint8* needle, int needle_length1);
gchar* kkc_index_file_get_contents (KkcIndexFile* self);
gsize kkc_index_file_get_length (KkcIndexFile* self);
static gboolean kkc_sorted_trigram_language_model_real_has_trigram (KkcTrigramLanguageModel* base, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
static gdouble kkc_sorted_trigram_language_model_real_trigram_cost (KkcTrigramLanguageModel* base, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry);
gdouble kkc_language_model_utils_decode_cost (guint16 cost, gdouble min_cost);
gdouble kkc_sorted_bigram_language_model_get_min_cost (KkcSortedBigramLanguageModel* self);
static gboolean kkc_sorted_trigram_language_model_real_parse (KkcLanguageModel* base, GError** error);
gboolean kkc_language_model_parse (KkcLanguageModel* self, GError** error);
GType kkc_metadata_file_get_type (void) G_GNUC_CONST;
GType kkc_language_model_metadata_get_type (void) G_GNUC_CONST;
KkcLanguageModelMetadata* kkc_language_model_get_metadata (KkcLanguageModel* self);
const gchar* kkc_metadata_file_get_filename (KkcMetadataFile* self);
GType kkc_mapped_index_file_get_type (void) G_GNUC_CONST;
KkcMappedIndexFile* kkc_mapped_index_file_new (const gchar* filename, GError** error);
KkcMappedIndexFile* kkc_mapped_index_file_construct (GType object_type, const gchar* filename, GError** error);
GType kkc_loaded_index_file_get_type (void) G_GNUC_CONST;
KkcLoadedIndexFile* kkc_loaded_index_file_new (const gchar* filename, GError** error);
KkcLoadedIndexFile* kkc_loaded_index_file_construct (GType object_type, const gchar* filename, GError** error);
KkcBloomFilter* kkc_bloom_filter_new (const gchar* filename, GError** error);
KkcBloomFilter* kkc_bloom_filter_construct (GType object_type, const gchar* filename, GError** error);
KkcSortedTrigramLanguageModel* kkc_sorted_trigram_language_model_new (KkcLanguageModelMetadata* metadata, GError** error);
KkcSortedTrigramLanguageModel* kkc_sorted_trigram_language_model_construct (GType object_type, KkcLanguageModelMetadata* metadata, GError** error);
KkcSortedBigramLanguageModel* kkc_sorted_bigram_language_model_new (KkcLanguageModelMetadata* metadata, GError** error);
KkcSortedBigramLanguageModel* kkc_sorted_bigram_language_model_construct (GType object_type, KkcLanguageModelMetadata* metadata, GError** error);
static void kkc_sorted_trigram_language_model_finalize (GObject* obj);


static glong kkc_sorted_trigram_language_model_trigram_offset (KkcSortedTrigramLanguageModel* self, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry) {
	glong result = 0L;
	glong c = 0L;
	KkcLanguageModelEntry _tmp0_ = {0};
	KkcLanguageModelEntry _tmp1_ = {0};
	glong _tmp2_ = 0L;
	gboolean _tmp3_ = FALSE;
	glong _tmp4_ = 0L;
	guint32 _tmp5_ = 0U;
	gboolean _tmp10_ = FALSE;
	KkcBloomFilter* _tmp11_ = NULL;
	guint8* buffer = NULL;
	guint8* _tmp17_ = NULL;
	gint buffer_length1 = 0;
	gint _buffer_size_ = 0;
	guint8* p = NULL;
	guint8* _tmp18_ = NULL;
	gint _tmp18__length1 = 0;
	guint32 value = 0U;
	KkcLanguageModelEntry _tmp19_ = {0};
	guint _tmp20_ = 0U;
	guint8* _tmp21_ = NULL;
	guint8* _tmp22_ = NULL;
	guint32 pvalue = 0U;
	glong _tmp23_ = 0L;
	guint8* _tmp24_ = NULL;
	gint record_size = 0;
	glong offset = 0L;
	KkcIndexFile* _tmp25_ = NULL;
	gchar* _tmp26_ = NULL;
	KkcIndexFile* _tmp27_ = NULL;
	gsize _tmp28_ = 0UL;
	gint _tmp29_ = 0;
	gint _tmp30_ = 0;
	guint8* _tmp31_ = NULL;
	gint _tmp31__length1 = 0;
	glong _tmp32_ = 0L;
	KkcLanguageModelEntry _tmp33_ = {0};
	guint _tmp34_ = 0U;
	glong _tmp35_ = 0L;
	glong _tmp36_ = 0L;
	g_return_val_if_fail (self != NULL, 0L);
	g_return_val_if_fail (ppentry != NULL, 0L);
	g_return_val_if_fail (pentry != NULL, 0L);
	g_return_val_if_fail (entry != NULL, 0L);
	_tmp0_ = *ppentry;
	_tmp1_ = *pentry;
	_tmp2_ = kkc_sorted_bigram_language_model_bigram_offset ((KkcSortedBigramLanguageModel*) self, &_tmp0_, &_tmp1_);
	c = _tmp2_;
	_tmp4_ = c;
	_tmp5_ = self->priv->last_pvalue;
	if (_tmp4_ == ((glong) _tmp5_)) {
		KkcLanguageModelEntry _tmp6_ = {0};
		guint _tmp7_ = 0U;
		guint32 _tmp8_ = 0U;
		_tmp6_ = *entry;
		_tmp7_ = _tmp6_.id;
		_tmp8_ = self->priv->last_value;
		_tmp3_ = _tmp7_ == ((guint) _tmp8_);
	} else {
		_tmp3_ = FALSE;
	}
	if (_tmp3_) {
		glong _tmp9_ = 0L;
		_tmp9_ = self->priv->last_offset;
		result = _tmp9_;
		return result;
	}
	_tmp11_ = self->priv->trigram_filter;
	if (_tmp11_ != NULL) {
		KkcBloomFilter* _tmp12_ = NULL;
		KkcLanguageModelEntry _tmp13_ = {0};
		guint _tmp14_ = 0U;
		glong _tmp15_ = 0L;
		gboolean _tmp16_ = FALSE;
		_tmp12_ = self->priv->trigram_filter;
		_tmp13_ = *entry;
		_tmp14_ = _tmp13_.id;
		_tmp15_ = c;
		_tmp16_ = kkc_bloom_filter_contains (_tmp12_, (guint32) _tmp14_, (guint32) _tmp15_);
		_tmp10_ = !_tmp16_;
	} else {
		_tmp10_ = FALSE;
	}
	if (_tmp10_) {
		result = (glong) (-1);
		return result;
	}
	_tmp17_ = g_new0 (guint8, 8);
	buffer = _tmp17_;
	buffer_length1 = 8;
	_buffer_size_ = buffer_length1;
	_tmp18_ = buffer;
	_tmp18__length1 = buffer_length1;
	p = _tmp18_;
	_tmp19_ = *entry;
	_tmp20_ = _tmp19_.id;
	value = (guint32) _tmp20_;
	_tmp21_ = p;
	memcpy (_tmp21_, &value, (gsize) sizeof (guint32));
	_tmp22_ = p;
	p = _tmp22_ + 4;
	_tmp23_ = c;
	pvalue = (guint32) _tmp23_;
	_tmp24_ = p;
	memcpy (_tmp24_, &pvalue, (gsize) sizeof (guint32));
	record_size = 10;
	_tmp25_ = self->priv->trigram_index;
	_tmp26_ = kkc_index_file_get_contents (_tmp25_);
	_tmp27_ = self->priv->trigram_index;
	_tmp28_ = kkc_index_file_get_length (_tmp27_);
	_tmp29_ = record_size;
	_tmp30_ = record_size;
	_tmp31_ = buffer;
	_tmp31__length1 = buffer_length1;
	_tmp32_ = kkc_language_model_utils_bsearch_ngram (_tmp26_, (glong) 0, ((glong) _tmp28_) / _tmp29_, (glong) _tmp30_, _tmp31_, _tmp31__length1);
	offset = _tmp32_;
	_tmp33_ = *entry;
	_tmp34_ = _tmp33_.id;
	self->priv->last_value = (guint32) _tmp34_;
	_tmp35_ = c;
	self->priv->last_pvalue = (guint32) _tmp35_;
	_tmp36_ = offset;
	self->priv->last_offset = _tmp36_;
	result = offset;
	buffer = (g_free (buffer), NULL);
	return result;
}


static gboolean kkc_sorted_trigram_language_model_real_has_trigram (KkcTrigramLanguageModel* base, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry) {
	KkcSortedTrigramLanguageModel * self;
	gboolean result = FALSE;
	KkcLanguageModelEntry _tmp0_ = {0};
	KkcLanguageModelEntry _tmp1_ = {0};
	KkcLanguageModelEntry _tmp2_ = {0};
	glong _tmp3_ = 0L;
	self = (KkcSortedTrigramLanguageModel*) base;
	g_return_val_if_fail (ppentry != NULL, FALSE);
	g_return_val_if_fail (pentry != NULL, FALSE);
	g_return_val_if_fail (entry != NULL, FALSE);
	_tmp0_ = *ppentry;
	_tmp1_ = *pentry;
	_tmp2_ = *entry;
	_tmp3_ = kkc_sorted_trigram_language_model_trigram_offset (self, &_tmp0_, &_tmp1_, &_tmp2_);
	result = _tmp3_ >= ((glong) 0);
	return result;
}


static gdouble kkc_sorted_trigram_language_model_real_trigram_cost (KkcTrigramLanguageModel* base, KkcLanguageModelEntry* ppentry, KkcLanguageModelEntry* pentry, KkcLanguageModelEntry* entry) {
	KkcSortedTrigramLanguageModel * self;
	gdouble result = 0.0;
	glong offset = 0L;
	KkcLanguageModelEntry _tmp0_ = {0};
	KkcLanguageModelEntry _tmp1_ = {0};
	KkcLanguageModelEntry _tmp2_ = {0};
	glong _tmp3_ = 0L;
	glong _tmp4_ = 0L;
	guint8* p = NULL;
	KkcIndexFile* _tmp5_ = NULL;
	gchar* _tmp6_ = NULL;
	glong _tmp7_ = 0L;
	guint16 cost = 0U;
	guint8* _tmp8_ = NULL;
	guint16 _tmp9_ = 0U;
	gdouble _tmp10_ = 0.0;
	gdouble _tmp11_ = 0.0;
	gdouble _tmp12_ = 0.0;
	self = (KkcSortedTrigramLanguageModel*) base;
	g_return_val_if_fail (ppentry != NULL, 0.0);
	g_return_val_if_fail (pentry != NULL, 0.0);
	g_return_val_if_fail (entry != NULL, 0.0);
	_tmp0_ = *ppentry;
	_tmp1_ = *pentry;
	_tmp2_ = *entry;
	_tmp3_ = kkc_sorted_trigram_language_model_trigram_offset (self, &_tmp0_, &_tmp1_, &_tmp2_);
	offset = _tmp3_;
	_tmp4_ = offset;
	if (_tmp4_ < ((glong) 0)) {
		result = (gdouble) 0;
		return result;
	}
	_tmp5_ = self->priv->trigram_index;
	_tmp6_ = kkc_index_file_get_contents (_tmp5_);
	_tmp7_ = offset;
	p = (((guint8*) _tmp6_) + (_tmp7_ * 10)) + 8;
	_tmp8_ = p;
	cost = *((guint16*) _tmp8_);
	_tmp9_ = cost;
	_tmp10_ = kkc_sorted_bigram_language_model_get_min_cost ((KkcSortedBigramLanguageModel*) self);
	_tmp11_ = _tmp10_;
	_tmp12_ = kkc_language_model_utils_decode_cost (_tmp9_, _tmp11_);
	result = _tmp12_;
	return result;
}


static gboolean kkc_sorted_trigram_language_model_real_parse (KkcLanguageModel* base, GError** error) {
	KkcSortedTrigramLanguageModel * self;
	gboolean result = FALSE;
	gchar* prefix = NULL;
	KkcLanguageModelMetadata* _tmp0_ = NULL;
	KkcLanguageModelMetadata* _tmp1_ = NULL;
	const gchar* _tmp2_ = NULL;
	const gchar* _tmp3_ = NULL;
	gchar* _tmp4_ = NULL;
	gchar* _tmp5_ = NULL;
	gchar* _tmp6_ = NULL;
	gchar* _tmp7_ = NULL;
	gboolean _tmp8_ = FALSE;
	gchar* trigram_filter_filename = NULL;
	const gchar* _tmp23_ = NULL;
	gchar* _tmp24_ = NULL;
	GError * _inner_error_ = NULL;
	self = (KkcSortedTrigramLanguageModel*) base;
	KKC_LANGUAGE_MODEL_CLASS (kkc_sorted_trigram_language_model_parent_class)->parse ((KkcLanguageModel*) G_TYPE_CHECK_INSTANCE_CAST (self, KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL, KkcSortedBigramLanguageModel), &_inner_error_);
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		return FALSE;
	}
	_tmp0_ = kkc_language_model_get_metadata ((KkcLanguageModel*) self);
	_tmp1_ = _tmp0_;
	_tmp2_ = kkc_metadata_file_get_filename ((KkcMetadataFile*) _tmp1_);
	_tmp3_ = _tmp2_;
	_tmp4_ = g_path_get_dirname (_tmp3_);
	_tmp5_ = _tmp4_;
	_tmp6_ = g_build_filename (_tmp5_, "data", NULL);
	_tmp7_ = _tmp6_;
	_g_free0 (_tmp5_);
	prefix = _tmp7_;
	_tmp8_ = kkc_use_mapped_index_file;
	if (_tmp8_) {
		KkcMappedIndexFile* _tmp9_ = NULL;
		const gchar* _tmp10_ = NULL;
		gchar* _tmp11_ = NULL;
		gchar* _tmp12_ = NULL;
		KkcMappedIndexFile* _tmp13_ = NULL;
		KkcMappedIndexFile* _tmp14_ = NULL;
		KkcMappedIndexFile* _tmp15_ = NULL;
		_tmp10_ = prefix;
		_tmp11_ = g_strconcat (_tmp10_, ".3gram", NULL);
		_tmp12_ = _tmp11_;
		_tmp13_ = kkc_mapped_index_file_new (_tmp12_, &_inner_error_);
		_tmp14_ = _tmp13_;
		_g_free0 (_tmp12_);
		_tmp9_ = _tmp14_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			g_propagate_error (error, _inner_error_);
			_g_free0 (prefix);
			return FALSE;
		}
		_tmp15_ = _tmp9_;
		_tmp9_ = NULL;
		_g_object_unref0 (self->priv->trigram_index);
		self->priv->trigram_index = (KkcIndexFile*) _tmp15_;
		_g_object_unref0 (_tmp9_);
	} else {
		KkcLoadedIndexFile* _tmp16_ = NULL;
		const gchar* _tmp17_ = NULL;
		gchar* _tmp18_ = NULL;
		gchar* _tmp19_ = NULL;
		KkcLoadedIndexFile* _tmp20_ = NULL;
		KkcLoadedIndexFile* _tmp21_ = NULL;
		KkcLoadedIndexFile* _tmp22_ = NULL;
		_tmp17_ = prefix;
		_tmp18_ = g_strconcat (_tmp17_, ".3gram", NULL);
		_tmp19_ = _tmp18_;
		_tmp20_ = kkc_loaded_index_file_new (_tmp19_, &_inner_error_);
		_tmp21_ = _tmp20_;
		_g_free0 (_tmp19_);
		_tmp16_ = _tmp21_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			g_propagate_error (error, _inner_error_);
			_g_free0 (prefix);
			return FALSE;
		}
		_tmp22_ = _tmp16_;
		_tmp16_ = NULL;
		_g_object_unref0 (self->priv->trigram_index);
		self->priv->trigram_index = (KkcIndexFile*) _tmp22_;
		_g_object_unref0 (_tmp16_);
	}
	_tmp23_ = prefix;
	_tmp24_ = g_strconcat (_tmp23_, ".3gram.filter", NULL);
	trigram_filter_filename = _tmp24_;
	{
		KkcBloomFilter* _tmp25_ = NULL;
		const gchar* _tmp26_ = NULL;
		KkcBloomFilter* _tmp27_ = NULL;
		KkcBloomFilter* _tmp28_ = NULL;
		_tmp26_ = trigram_filter_filename;
		_tmp27_ = kkc_bloom_filter_new (_tmp26_, &_inner_error_);
		_tmp25_ = _tmp27_;
		if (G_UNLIKELY (_inner_error_ != NULL)) {
			goto __catch2_g_error;
		}
		_tmp28_ = _tmp25_;
		_tmp25_ = NULL;
		_g_object_unref0 (self->priv->trigram_filter);
		self->priv->trigram_filter = _tmp28_;
		_g_object_unref0 (_tmp25_);
	}
	goto __finally2;
	__catch2_g_error:
	{
		GError* e = NULL;
		const gchar* _tmp29_ = NULL;
		GError* _tmp30_ = NULL;
		const gchar* _tmp31_ = NULL;
		e = _inner_error_;
		_inner_error_ = NULL;
		_tmp29_ = trigram_filter_filename;
		_tmp30_ = e;
		_tmp31_ = _tmp30_->message;
		g_warning ("sorted-trigram-language-model.vala:102: can't load %s: %s", _tmp29_, _tmp31_);
		_g_error_free0 (e);
	}
	__finally2:
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		_g_free0 (trigram_filter_filename);
		_g_free0 (prefix);
		return FALSE;
	}
	result = TRUE;
	_g_free0 (trigram_filter_filename);
	_g_free0 (prefix);
	return result;
}


KkcSortedTrigramLanguageModel* kkc_sorted_trigram_language_model_construct (GType object_type, KkcLanguageModelMetadata* metadata, GError** error) {
	KkcSortedTrigramLanguageModel * self = NULL;
	KkcLanguageModelMetadata* _tmp0_ = NULL;
	GError * _inner_error_ = NULL;
	g_return_val_if_fail (metadata != NULL, NULL);
	_tmp0_ = metadata;
	self = (KkcSortedTrigramLanguageModel*) kkc_sorted_bigram_language_model_construct (object_type, _tmp0_, &_inner_error_);
	if (G_UNLIKELY (_inner_error_ != NULL)) {
		g_propagate_error (error, _inner_error_);
		_g_object_unref0 (self);
		return NULL;
	}
	return self;
}


KkcSortedTrigramLanguageModel* kkc_sorted_trigram_language_model_new (KkcLanguageModelMetadata* metadata, GError** error) {
	return kkc_sorted_trigram_language_model_construct (KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, metadata, error);
}


static void kkc_sorted_trigram_language_model_class_init (KkcSortedTrigramLanguageModelClass * klass) {
	kkc_sorted_trigram_language_model_parent_class = g_type_class_peek_parent (klass);
	g_type_class_add_private (klass, sizeof (KkcSortedTrigramLanguageModelPrivate));
	((KkcLanguageModelClass *) klass)->parse = kkc_sorted_trigram_language_model_real_parse;
	G_OBJECT_CLASS (klass)->finalize = kkc_sorted_trigram_language_model_finalize;
}


static void kkc_sorted_trigram_language_model_kkc_trigram_language_model_interface_init (KkcTrigramLanguageModelIface * iface) {
	kkc_sorted_trigram_language_model_kkc_trigram_language_model_parent_iface = g_type_interface_peek_parent (iface);
	iface->has_trigram = (gboolean (*)(KkcTrigramLanguageModel*, KkcLanguageModelEntry*, KkcLanguageModelEntry*, KkcLanguageModelEntry*)) kkc_sorted_trigram_language_model_real_has_trigram;
	iface->trigram_cost = (gdouble (*)(KkcTrigramLanguageModel*, KkcLanguageModelEntry*, KkcLanguageModelEntry*, KkcLanguageModelEntry*)) kkc_sorted_trigram_language_model_real_trigram_cost;
}


static void kkc_sorted_trigram_language_model_instance_init (KkcSortedTrigramLanguageModel * self) {
	self->priv = KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_GET_PRIVATE (self);
	self->priv->trigram_filter = NULL;
	self->priv->last_value = (guint32) 0;
	self->priv->last_pvalue = (guint32) 0;
	self->priv->last_offset = (glong) 0;
}


static void kkc_sorted_trigram_language_model_finalize (GObject* obj) {
	KkcSortedTrigramLanguageModel * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_SORTED_TRIGRAM_LANGUAGE_MODEL, KkcSortedTrigramLanguageModel);
	_g_object_unref0 (self->priv->trigram_index);
	_g_object_unref0 (self->priv->trigram_filter);
	G_OBJECT_CLASS (kkc_sorted_trigram_language_model_parent_class)->finalize (obj);
}


GType kkc_sorted_trigram_language_model_get_type (void) {
	static volatile gsize kkc_sorted_trigram_language_model_type_id__volatile = 0;
	if (g_once_init_enter (&kkc_sorted_trigram_language_model_type_id__volatile)) {
		static const GTypeInfo g_define_type_info = { sizeof (KkcSortedTrigramLanguageModelClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_sorted_trigram_language_model_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcSortedTrigramLanguageModel), 0, (GInstanceInitFunc) kkc_sorted_trigram_language_model_instance_init, NULL };
		static const GInterfaceInfo kkc_trigram_language_model_info = { (GInterfaceInitFunc) kkc_sorted_trigram_language_model_kkc_trigram_language_model_interface_init, (GInterfaceFinalizeFunc) NULL, NULL};
		GType kkc_sorted_trigram_language_model_type_id;
		kkc_sorted_trigram_language_model_type_id = g_type_register_static (KKC_TYPE_SORTED_BIGRAM_LANGUAGE_MODEL, "KkcSortedTrigramLanguageModel", &g_define_type_info, 0);
		g_type_add_interface_static (kkc_sorted_trigram_language_model_type_id, KKC_TYPE_TRIGRAM_LANGUAGE_MODEL, &kkc_trigram_language_model_info);
		g_once_init_leave (&kkc_sorted_trigram_language_model_type_id__volatile, kkc_sorted_trigram_language_model_type_id);
	}
	return kkc_sorted_trigram_language_model_type_id__volatile;
}



