/* bloom-filter.c generated by valac 0.56.19, the Vala compiler
 * generated from bloom-filter.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 <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include "libkkc/libkkc.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_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;
typedef struct _KkcBloomFilterPrivate KkcBloomFilterPrivate;
enum  {
	KKC_BLOOM_FILTER_0_PROPERTY,
	KKC_BLOOM_FILTER_NUM_PROPERTIES
};
static GParamSpec* kkc_bloom_filter_properties[KKC_BLOOM_FILTER_NUM_PROPERTIES];
#define _g_mapped_file_unref0(var) ((var == NULL) ? NULL : (var = (g_mapped_file_unref (var), NULL)))
#define _g_object_unref0(var) ((var == NULL) ? NULL : (var = (g_object_unref (var), NULL)))
#define _vala_assert(expr, msg) if G_LIKELY (expr) ; else g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);
#define _vala_return_if_fail(expr, msg) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return; }
#define _vala_return_val_if_fail(expr, msg, val) if G_LIKELY (expr) ; else { g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC, msg); return val; }
#define _vala_warn_if_fail(expr, msg) if G_LIKELY (expr) ; else g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, msg);

struct _KkcBloomFilter {
	GObject parent_instance;
	KkcBloomFilterPrivate * priv;
};

struct _KkcBloomFilterClass {
	GObjectClass parent_class;
};

struct _KkcBloomFilterPrivate {
	GMappedFile* mmap;
};

static gint KkcBloomFilter_private_offset;
static gpointer kkc_bloom_filter_parent_class = NULL;

VALA_EXTERN guint32 kkc_murmur_hash3_32 (guint32 b0,
                             guint32 b1,
                             guint32 seed);
VALA_EXTERN GType kkc_bloom_filter_get_type (void) G_GNUC_CONST ;
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 gboolean kkc_bloom_filter_is_bit_set (KkcBloomFilter* self,
                                      guint32 index);
VALA_EXTERN gboolean kkc_bloom_filter_contains (KkcBloomFilter* self,
                                    guint32 b0,
                                    guint32 b1);
static void kkc_bloom_filter_finalize (GObject * obj);
static GType kkc_bloom_filter_get_type_once (void);

guint32
kkc_murmur_hash3_32 (guint32 b0,
                     guint32 b1,
                     guint32 seed)
{
	guint32 h1 = 0U;
	static const guint32 c1 = (guint32) 0xcc9e2d51U;
	static const guint32 c2 = (guint32) 0x1b873593U;
	guint32 result;
	h1 = seed;
	b0 = b0 * c1;
	b0 = (b0 << 15) | (b0 >> (32 - 15));
	b0 = b0 * c2;
	h1 ^= b0;
	h1 = (h1 << 13) | (h1 >> (32 - 13));
	h1 = (h1 * 5) + 0xe6546b64U;
	b1 = b1 * c1;
	b1 = (b1 << 15) | (b1 >> (32 - 15));
	b1 = b1 * c2;
	h1 ^= b1;
	h1 = (h1 << 13) | (h1 >> (32 - 13));
	h1 = (h1 * 5) + 0xe6546b64U;
	h1 ^= (guint32) 8;
	h1 ^= h1 >> 16;
	h1 *= (guint32) 0x85ebca6bU;
	h1 ^= h1 >> 13;
	h1 *= (guint32) 0xc2b2ae35U;
	h1 ^= h1 >> 16;
	result = h1;
	return result;
}

static inline gpointer
kkc_bloom_filter_get_instance_private (KkcBloomFilter* self)
{
	return G_STRUCT_MEMBER_P (self, KkcBloomFilter_private_offset);
}

KkcBloomFilter*
kkc_bloom_filter_construct (GType object_type,
                            const gchar* filename,
                            GError** error)
{
	KkcBloomFilter * self = NULL;
	GMappedFile* _tmp0_ = NULL;
	GMappedFile* _tmp1_;
	GMappedFile* _tmp2_;
	GError* _inner_error0_ = NULL;
	g_return_val_if_fail (filename != NULL, NULL);
	self = (KkcBloomFilter*) g_object_new (object_type, NULL);
	_tmp1_ = g_mapped_file_new (filename, FALSE, &_inner_error0_);
	_tmp0_ = _tmp1_;
	if (G_UNLIKELY (_inner_error0_ != NULL)) {
		g_propagate_error (error, _inner_error0_);
		_g_object_unref0 (self);
		return NULL;
	}
	_tmp2_ = _tmp0_;
	_tmp0_ = NULL;
	_g_mapped_file_unref0 (self->priv->mmap);
	self->priv->mmap = _tmp2_;
	_g_mapped_file_unref0 (_tmp0_);
	return self;
}

KkcBloomFilter*
kkc_bloom_filter_new (const gchar* filename,
                      GError** error)
{
	return kkc_bloom_filter_construct (KKC_TYPE_BLOOM_FILTER, filename, error);
}

static gboolean
kkc_bloom_filter_is_bit_set (KkcBloomFilter* self,
                             guint32 index)
{
	GMappedFile* _tmp0_;
	guint8* p = NULL;
	GMappedFile* _tmp1_;
	gchar* _tmp2_;
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	_tmp0_ = self->priv->mmap;
	_vala_assert (((gsize) (index / 8)) < g_mapped_file_get_length (_tmp0_), "index / 8 < mmap.get_length ()");
	_tmp1_ = self->priv->mmap;
	_tmp2_ = g_mapped_file_get_contents (_tmp1_);
	p = ((guint8*) _tmp2_) + (index / 8);
	result = ((gint) ((*p) & (1 << (index % 8)))) != 0;
	return result;
}

gboolean
kkc_bloom_filter_contains (KkcBloomFilter* self,
                           guint32 b0,
                           guint32 b1)
{
	gboolean result;
	g_return_val_if_fail (self != NULL, FALSE);
	{
		gint k = 0;
		k = 0;
		{
			gboolean _tmp0_ = FALSE;
			_tmp0_ = TRUE;
			while (TRUE) {
				guint32 h = 0U;
				guint32 i = 0U;
				GMappedFile* _tmp2_;
				if (!_tmp0_) {
					gint _tmp1_;
					_tmp1_ = k;
					k = _tmp1_ + 1;
				}
				_tmp0_ = FALSE;
				if (!(k < 4)) {
					break;
				}
				h = kkc_murmur_hash3_32 (b0, b1, (guint32) k);
				_tmp2_ = self->priv->mmap;
				i = (guint32) (h * ((g_mapped_file_get_length (_tmp2_) * 8) / ((gdouble) 0xFFFFFFFFLL)));
				if (!kkc_bloom_filter_is_bit_set (self, i)) {
					result = FALSE;
					return result;
				}
			}
		}
	}
	result = TRUE;
	return result;
}

static void
kkc_bloom_filter_class_init (KkcBloomFilterClass * klass,
                             gpointer klass_data)
{
	kkc_bloom_filter_parent_class = g_type_class_peek_parent (klass);
	g_type_class_adjust_private_offset (klass, &KkcBloomFilter_private_offset);
	G_OBJECT_CLASS (klass)->finalize = kkc_bloom_filter_finalize;
}

static void
kkc_bloom_filter_instance_init (KkcBloomFilter * self,
                                gpointer klass)
{
	self->priv = kkc_bloom_filter_get_instance_private (self);
}

static void
kkc_bloom_filter_finalize (GObject * obj)
{
	KkcBloomFilter * self;
	self = G_TYPE_CHECK_INSTANCE_CAST (obj, KKC_TYPE_BLOOM_FILTER, KkcBloomFilter);
	_g_mapped_file_unref0 (self->priv->mmap);
	G_OBJECT_CLASS (kkc_bloom_filter_parent_class)->finalize (obj);
}

static GType
kkc_bloom_filter_get_type_once (void)
{
	static const GTypeInfo g_define_type_info = { sizeof (KkcBloomFilterClass), (GBaseInitFunc) NULL, (GBaseFinalizeFunc) NULL, (GClassInitFunc) kkc_bloom_filter_class_init, (GClassFinalizeFunc) NULL, NULL, sizeof (KkcBloomFilter), 0, (GInstanceInitFunc) kkc_bloom_filter_instance_init, NULL };
	GType kkc_bloom_filter_type_id;
	kkc_bloom_filter_type_id = g_type_register_static (G_TYPE_OBJECT, "KkcBloomFilter", &g_define_type_info, 0);
	KkcBloomFilter_private_offset = g_type_add_instance_private (kkc_bloom_filter_type_id, sizeof (KkcBloomFilterPrivate));
	return kkc_bloom_filter_type_id;
}

GType
kkc_bloom_filter_get_type (void)
{
	static volatile gsize kkc_bloom_filter_type_id__once = 0;
	if (g_once_init_enter (&kkc_bloom_filter_type_id__once)) {
		GType kkc_bloom_filter_type_id;
		kkc_bloom_filter_type_id = kkc_bloom_filter_get_type_once ();
		g_once_init_leave (&kkc_bloom_filter_type_id__once, kkc_bloom_filter_type_id);
	}
	return kkc_bloom_filter_type_id__once;
}

