/* sorted-trigram-language-model.c generated by valac 0.56.19, 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 "libkkc/libkkc.h"
#include <glib-object.h>
#include <glib.h>
#include <string.h>
#include <float.h>
#include <math.h>

#if !defined(VALA_STRICT_C)
#if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ >= 14)
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
#elif defined(__clang__) && (__clang_major__ >= 16)
#pragma clang diagnostic ignored "-Wincompatible-function-pointer-types"
#pragma clang diagnostic ignored "-Wincompatible-pointer-types"
#endif
#endif

#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;
enum  {
	KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_0_PROPERTY,
	KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_NUM_PROPERTIES
};
static GParamSpec* kkc_sorted_trigram_language_model_properties[KKC_SORTED_TRIGRAM_LANGUAGE_MODEL_NUM_PROPERTIES];
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#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 _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 gint KkcSortedTrigramLanguageModel_private_offset;
static gpointer kkc_sorted_trigram_language_model_parent_class = NULL;
static KkcTrigramLanguageModelIface * kkc_sorted_trigram_language_model_kkc_trigram_language_model_parent_iface = NULL;

VALA_EXTERN GType kkc_index_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN GType kkc_bloom_filter_get_type (void) G_GNUC_CONST ;
static glong kkc_sorted_trigram_language_model_trigram_offset (KkcSortedTrigramLanguageModel* self,
                                                        KkcLanguageModelEntry* ppentry,
                                                        KkcLanguageModelEntry* pentry,
                                                        KkcLanguageModelEntry* entry);
VALA_EXTERN gboolean kkc_bloom_filter_contains (KkcBloomFilter* self,
                                    guint32 b0,
                                    guint32 b1);
VALA_EXTERN glong kkc_language_model_utils_bsearch_ngram (void* memory,
                                              glong start_offset,
                                              glong end_offset,
                                              glong record_size,
                                              guint8* needle,
                                              gint needle_length1);
VALA_EXTERN gchar* kkc_index_file_get_contents (KkcIndexFile* self);
VALA_EXTERN 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);
VALA_EXTERN gdouble kkc_language_model_utils_decode_cost (guint16 cost,
                                              gdouble min_cost);
static gboolean kkc_sorted_trigram_language_model_real_parse (KkcLanguageModel* base,
                                                       GError** error);
VALA_EXTERN GType kkc_mapped_index_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN KkcMappedIndexFile* kkc_mapped_index_file_new (const gchar* filename,
                                               GError** error);
VALA_EXTERN KkcMappedIndexFile* kkc_mapped_index_file_construct (GType object_type,
                                                     const gchar* filename,
                                                     GError** error);
VALA_EXTERN GType kkc_loaded_index_file_get_type (void) G_GNUC_CONST ;
VALA_EXTERN KkcLoadedIndexFile* kkc_loaded_index_file_new (const gchar* filename,
                                               GError** error);
VALA_EXTERN KkcLoadedIndexFile* kkc_loaded_index_file_construct (GType object_type,
                                                     const gchar* filename,
                                                     GError** error);
VALA_EXTERN KkcBloomFilter* kkc_bloom_filter_new (const gchar* filename,
                                      GError** error);
VALA_EXTERN KkcBloomFilter* kkc_bloom_filter_construct (GType object_type,
                                            const gchar* filename,
                                            GError** error);
static void kkc_sorted_trigram_language_model_finalize (GObject * obj);
static GType kkc_sorted_trigram_language_model_get_type_once (void);

static inline gpointer
kkc_sorted_trigram_language_model_get_instance_private (KkcSortedTrigramLanguageModel* self)
{
	return G_STRUCT_MEMBER_P (self, KkcSortedTrigramLanguageModel_private_offset);
}

static glong
kkc_sorted_trigram_language_model_trigram_offset (KkcSortedTrigramLanguageModel* self,
                                                  KkcLanguageModelEntry* ppentry,
                                                  KkcLanguageModelEntry* pentry,
                                                  KkcLanguageModelEntry* entry)
{
	glong c = 0L;
	KkcLanguageModelEntry _tmp0_;
	KkcLanguageModelEntry _tmp1_;
	gboolean _tmp2_ = FALSE;
	gboolean _tmp4_ = FALSE;
	KkcBloomFilter* _tmp5_;
	guint8* buffer = NULL;
	guint8* _tmp8_;
	gint buffer_length1;
	gint _buffer_size_;
	guint8* p = NULL;
	guint8* _tmp9_;
	gint _tmp9__length1;
	guint32 value = 0U;
	KkcLanguageModelEntry _tmp10_;
	guint8* _tmp11_;
	guint8* _tmp12_;
	guint32 pvalue = 0U;
	guint8* _tmp13_;
	gint record_size = 0;
	glong offset = 0L;
	KkcIndexFile* _tmp14_;
	gchar* _tmp15_;
	KkcIndexFile* _tmp16_;
	guint8* _tmp17_;
	gint _tmp17__length1;
	KkcLanguageModelEntry _tmp18_;
	glong result;
	g_return_val_if_fail (self != NULL, -1L);
	g_return_val_if_fail (ppentry != NULL, -1L);
	g_return_val_if_fail (pentry != NULL, -1L);
	g_return_val_if_fail (entry != NULL, -1L);
	_tmp0_ = *ppentry;
	_tmp1_ = *pentry;
	c = kkc_sorted_bigram_language_model_bigram_offset ((KkcSortedBigramLanguageModel*) self, &_tmp0_, &_tmp1_);
	if (c == ((glong) self->priv->last_pvalue)) {
		KkcLanguageModelEntry _tmp3_;
		_tmp3_ = *entry;
		_tmp2_ = _tmp3_.id == ((guint) self->priv->last_value);
	} else {
		_tmp2_ = FALSE;
	}
	if (_tmp2_) {
		result = self->priv->last_offset;
		return result;
	}
	_tmp5_ = self->priv->trigram_filter;
	if (_tmp5_ != NULL) {
		KkcBloomFilter* _tmp6_;
		KkcLanguageModelEntry _tmp7_;
		_tmp6_ = self->priv->trigram_filter;
		_tmp7_ = *entry;
		_tmp4_ = !kkc_bloom_filter_contains (_tmp6_, (guint32) _tmp7_.id, (guint32) c);
	} else {
		_tmp4_ = FALSE;
	}
	if (_tmp4_) {
		result = (glong) -1;
		return result;
	}
	_tmp8_ = g_new0 (guint8, 8);
	buffer = _tmp8_;
	buffer_length1 = 8;
	_buffer_size_ = buffer_length1;
	_tmp9_ = buffer;
	_tmp9__length1 = buffer_length1;
	p = _tmp9_;
	_tmp10_ = *entry;
	value = (guint32) _tmp10_.id;
	_tmp11_ = p;
	memcpy (_tmp11_, &value, (gsize) sizeof (guint32));
	_tmp12_ = p;
	p = _tmp12_ + 4;
	pvalue = (guint32) c;
	_tmp13_ = p;
	memcpy (_tmp13_, &pvalue, (gsize) sizeof (guint32));
	record_size = 10;
	_tmp14_ = self->priv->trigram_index;
	_tmp15_ = kkc_index_file_get_contents (_tmp14_);
	_tmp16_ = self->priv->trigram_index;
	_tmp17_ = buffer;
	_tmp17__length1 = buffer_length1;
	offset = kkc_language_model_utils_bsearch_ngram (_tmp15_, (glong) 0, ((glong) kkc_index_file_get_length (_tmp16_)) / record_size, (glong) record_size, _tmp17_, (gint) _tmp17__length1);
	_tmp18_ = *entry;
	self->priv->last_value = (guint32) _tmp18_.id;
	self->priv->last_pvalue = (guint32) c;
	self->priv->last_offset = offset;
	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;
	KkcLanguageModelEntry _tmp0_;
	KkcLanguageModelEntry _tmp1_;
	KkcLanguageModelEntry _tmp2_;
	gboolean result;
	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;
	result = kkc_sorted_trigram_language_model_trigram_offset (self, &_tmp0_, &_tmp1_, &_tmp2_) >= ((glong) 0);
	return result;
}

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

static gboolean
kkc_sorted_trigram_language_model_real_parse (KkcLanguageModel* base,
                                              GError** error)
{
	KkcSortedTrigramLanguageModel * self;
	gchar* prefix = NULL;
	KkcLanguageModelMetadata* _tmp1_;
	KkcLanguageModelMetadata* _tmp2_;
	const gchar* _tmp3_;
	const gchar* _tmp4_;
	gchar* _tmp5_;
	gchar* _tmp6_;
	gchar* _tmp7_;
	gchar* _tmp8_;
	gchar* trigram_filter_filename = NULL;
	const gchar* _tmp25_;
	gchar* _tmp26_;
	GError* _inner_error0_ = NULL;
	gboolean result;
	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_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp0_ = FALSE;
		g_propagate_error (error, _inner_error0_);
		return _tmp0_;
	}
	_tmp1_ = kkc_language_model_get_metadata ((KkcLanguageModel*) self);
	_tmp2_ = _tmp1_;
	_tmp3_ = kkc_metadata_file_get_filename ((KkcMetadataFile*) _tmp2_);
	_tmp4_ = _tmp3_;
	_tmp5_ = g_path_get_dirname (_tmp4_);
	_tmp6_ = _tmp5_;
	_tmp7_ = g_build_filename (_tmp6_, "data", NULL);
	_tmp8_ = _tmp7_;
	_g_free0 (_tmp6_);
	prefix = _tmp8_;
	if (kkc_use_mapped_index_file) {
		KkcMappedIndexFile* _tmp9_ = NULL;
		const gchar* _tmp10_;
		gchar* _tmp11_;
		gchar* _tmp12_;
		KkcMappedIndexFile* _tmp13_;
		KkcMappedIndexFile* _tmp14_;
		KkcMappedIndexFile* _tmp16_;
		_tmp10_ = prefix;
		_tmp11_ = g_strconcat (_tmp10_, ".3gram", NULL);
		_tmp12_ = _tmp11_;
		_tmp13_ = kkc_mapped_index_file_new (_tmp12_, &_inner_error0_);
		_tmp14_ = _tmp13_;
		_g_free0 (_tmp12_);
		_tmp9_ = _tmp14_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			gboolean _tmp15_ = FALSE;
			g_propagate_error (error, _inner_error0_);
			_g_free0 (prefix);
			return _tmp15_;
		}
		_tmp16_ = _tmp9_;
		_tmp9_ = NULL;
		_g_object_unref0 (self->priv->trigram_index);
		self->priv->trigram_index = (KkcIndexFile*) _tmp16_;
		_g_object_unref0 (_tmp9_);
	} else {
		KkcLoadedIndexFile* _tmp17_ = NULL;
		const gchar* _tmp18_;
		gchar* _tmp19_;
		gchar* _tmp20_;
		KkcLoadedIndexFile* _tmp21_;
		KkcLoadedIndexFile* _tmp22_;
		KkcLoadedIndexFile* _tmp24_;
		_tmp18_ = prefix;
		_tmp19_ = g_strconcat (_tmp18_, ".3gram", NULL);
		_tmp20_ = _tmp19_;
		_tmp21_ = kkc_loaded_index_file_new (_tmp20_, &_inner_error0_);
		_tmp22_ = _tmp21_;
		_g_free0 (_tmp20_);
		_tmp17_ = _tmp22_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			gboolean _tmp23_ = FALSE;
			g_propagate_error (error, _inner_error0_);
			_g_free0 (prefix);
			return _tmp23_;
		}
		_tmp24_ = _tmp17_;
		_tmp17_ = NULL;
		_g_object_unref0 (self->priv->trigram_index);
		self->priv->trigram_index = (KkcIndexFile*) _tmp24_;
		_g_object_unref0 (_tmp17_);
	}
	_tmp25_ = prefix;
	_tmp26_ = g_strconcat (_tmp25_, ".3gram.filter", NULL);
	trigram_filter_filename = _tmp26_;
	{
		KkcBloomFilter* _tmp27_ = NULL;
		const gchar* _tmp28_;
		KkcBloomFilter* _tmp29_;
		KkcBloomFilter* _tmp30_;
		_tmp28_ = trigram_filter_filename;
		_tmp29_ = kkc_bloom_filter_new (_tmp28_, &_inner_error0_);
		_tmp27_ = _tmp29_;
		if (G_UNLIKELY (_inner_error0_ != NULL)) {
			goto __catch0_g_error;
		}
		_tmp30_ = _tmp27_;
		_tmp27_ = NULL;
		_g_object_unref0 (self->priv->trigram_filter);
		self->priv->trigram_filter = _tmp30_;
		_g_object_unref0 (_tmp27_);
	}
	goto __finally0;
	__catch0_g_error:
	{
		GError* e = NULL;
		const gchar* _tmp31_;
		GError* _tmp32_;
		const gchar* _tmp33_;
		e = _inner_error0_;
		_inner_error0_ = NULL;
		_tmp31_ = trigram_filter_filename;
		_tmp32_ = e;
		_tmp33_ = _tmp32_->message;
		g_warning ("sorted-trigram-language-model.vala:102: can't load %s: %s", _tmp31_, _tmp33_);
		_g_error_free0 (e);
	}
	__finally0:
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		gboolean _tmp34_ = FALSE;
		g_propagate_error (error, _inner_error0_);
		_g_free0 (trigram_filter_filename);
		_g_free0 (prefix);
		return _tmp34_;
	}
	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;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (metadata != NULL, NULL);
	self = (KkcSortedTrigramLanguageModel*) kkc_sorted_bigram_language_model_construct (object_type, metadata, &_inner_error0_);
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_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,
                                              gpointer klass_data)
{
	kkc_sorted_trigram_language_model_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KkcSortedTrigramLanguageModel_private_offset);
	((KkcLanguageModelClass *) klass)->parse = (gboolean (*) (KkcLanguageModel*, GError**)) 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,
                                                                             gpointer iface_data)
{
	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,
                                                 gpointer klass)
{
	self->priv = kkc_sorted_trigram_language_model_get_instance_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);
}

static GType
kkc_sorted_trigram_language_model_get_type_once (void)
{
	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);
	KkcSortedTrigramLanguageModel_private_offset = g_type_add_instance_private (kkc_sorted_trigram_language_model_type_id, sizeof (KkcSortedTrigramLanguageModelPrivate));
	return kkc_sorted_trigram_language_model_type_id;
}

GType
kkc_sorted_trigram_language_model_get_type (void)
{
	static volatile gsize kkc_sorted_trigram_language_model_type_id__once = 0;
	if (g_once_init_enter (&kkc_sorted_trigram_language_model_type_id__once)) {
		GType kkc_sorted_trigram_language_model_type_id;
		kkc_sorted_trigram_language_model_type_id = kkc_sorted_trigram_language_model_get_type_once ();
		g_once_init_leave (&kkc_sorted_trigram_language_model_type_id__once, kkc_sorted_trigram_language_model_type_id);
	}
	return kkc_sorted_trigram_language_model_type_id__once;
}

