system: Linux mars.sprixweb.com 3.10.0-1160.119.1.el7.x86_64 #1 SMP Tue Jun 4 14:43:51 UTC 2024 x86_64
cmd: 

Direktori : /lib64/cbpolicyd-2.1/awitpt/
Upload File :
Current File : //lib64/cbpolicyd-2.1/awitpt/cache.pm

# Caching engine
# Copyright (C) 2009-2011, AllWorldIT
# Copyright (C) 2008, LinuxRulz
# Copyright (C) 2007 Nigel Kukard  <nkukard@lbsd.net>
#
# 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 2 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, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.


package awitpt::cache;

use strict;
use warnings;


require Exporter;
our (@ISA,@EXPORT,@EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT = qw(
	cacheStoreKeyPair
	cacheStoreComplexKeyPair
	cacheGetKeyPair
	cacheGetComplexKeyPair
);
@EXPORT_OK = qw(
	getCacheHits
	getCacheMisses
);

use Cache::FastMmap;
use Storable;

# Cache stuff
my $cache_type = "FastMmap";
my $cache;


# Our current error message
my $error = "";

## @internal
# @fn setError($err)
# This function is used to set the last error for this class
#
# @param err Error message
sub setError
{
	my $err = shift;
	my ($package,$filename,$line) = caller;
	my (undef,undef,undef,$subroutine) = caller(1);

	# Set error
	$error = "$subroutine($line): $err";
}


## @internal
# @fn Error
# Return current error message
#
# @return Last error message
sub Error
{
	my $err = $error;

	# Reset error
	$error = "";

	# Return error
	return $err;
}





## @fn Init($server)
# Initialize cache
#
# @param server Server object
# @param params Parameters for the cache
# @li cache_file Filename of the cache file
# @li cache_file_user Owner of the cache file
# @li cache_file_group Group of the cache file
sub Init
{
	my ($server,$params) = @_;
	my $ch;


	# We going to pass these options to new()
	my %opt = (
		'page_size' => 2048,
		'num_pages' => 1000,
		'expire_time' => 300,
		'raw_values' => 1,
		'unlink_on_exit' => 1,
	);

	# Check if we have the optional $params
	if (defined($params)) {
		# If we have a special cache file, use it and init it too
		if (defined($params->{'cache_file'})) {
			$opt{'share_file'} = $params->{'cache_file'};
			$opt{'init_file'} = 1;
		}
	}

	# Create Cache
	$ch = Cache::FastMmap->new(%opt);

	# Check if we have the optional $params
	if (defined($params)) {
		# If we have an explicit owner set, use it
		if (defined($params->{'cache_file_user'})) {
			# Check all is ok...
			my ($chown_user,$chown_group);
			if (!($chown_user = getpwnam($params->{'cache_file_user'}))) {
				setError("User '$chown_user' appears to be invalid: $?");
				return(-1);
			}
			if (!($chown_group = getgrnam($params->{'cache_file_group'}))) {
				setError("Group '$chown_group' appears to be invalid: $?");
				return(-1);
			}
			# Go in and chown it
			if (!chown($chown_user,$chown_group,$opt{'share_file'})) {
				setError("Failed to chown cache file '".$opt{'share_file'}."': $!");
				return(-1);
			}
		}
	}

	# Stats
	$ch->set('Cache/Stats/Hit',0);
	$ch->set('Cache/Stats/Miss',0);

	# Set server vars
	$server->{'cache_engine'}{'handle'} = $ch;
};


## @fn Destroy()
# Destroy cache
#
# @param server Server object
sub Destroy
{
};


## @fn connect($server)
# Connect server with the cache
#
# @param server Server object
sub connect
{
	my $server = shift;

	$cache = $server->{'cache_engine'}{'handle'};
}


## @fn disconnect()
# Disconnect cache from server
#
# @param server Server object
sub disconnect
{
}


## @fn cacheStoreKeyPair($cacheName,$key,$value)
# Store keypair in cache
#
# @param cacheName Cache name to use
# @param key Item key
# @param value Item value
sub cacheStoreKeyPair
{
	my ($cacheName,$key,$value) = @_;


	if (!defined($cacheName)) {
		setError("Cache name not defined in store");
		return -1;
	}

	if ($cacheName eq "") {
		setError("Cache name not set in store");
		return -1;
	}

	if (!defined($key)) {
		setError("Key not defined for cache '$cacheName' store");
		return -1;
	}

	if (!defined($value)) {
		setError("Value not defined for cache '$cacheName' key '$key' store");
		return -1;
	}

	# If we're not caching just return
	return 0 if ($cache_type eq 'none');

	# Store
	$cache->set("$cacheName/$key",$value);

	return 0;
}


## @fn cacheGetKeyPair($cacheName,$key)
# Get value from cache
#
# @param cacheName Cache name to use
# @param key Item key
sub cacheGetKeyPair
{
	my ($cacheName,$key) = @_;


	if (!defined($cacheName)) {
		setError("Cache name not defined in get");
		return (-1);
	}

	if ($cacheName eq "") {
		setError("Cache name not set in get");
		return (-1);
	}

	if (!defined($key)) {
		setError("Key not defined for cache '$cacheName' get");
		return (-1);
	}

	# If we're not caching just return
	if ($cache_type eq 'none') {
		return (0,undef);
	}

	# Check and count
	my $res = $cache->get("$cacheName/$key");
	if ($res) {
		$cache->get_and_set('Cache/Stats/Hit',sub { return ++$_[1]; });
	} else {
		$cache->get_and_set('Cache/Stats/Miss',sub { return ++$_[1]; });
	}

	return (0,$res);
}


## @fn cacheStoreComplexKeyPair($cacheName,$key,$value)
# Store a complex keypair in cache, this would be an object and
# not a number or text
#
# @param cacheName Cache name to use
# @param key Item key
# @param value Item value
sub cacheStoreComplexKeyPair
{
	my ($cacheName,$key,$value) = @_;


	my $rawValue = Storable::freeze($value);
	if (!defined($rawValue)) {
		setError("Unable to freeze cache value in '$cacheName'");
		return -1;
	}

	return cacheStoreKeyPair($cacheName,$key,$rawValue);
}



## @fn cacheGetComplexKeyPair($cacheName,$key)
# Get value from cache
#
# @param cacheName Cache name to use
# @param key Item key
sub cacheGetComplexKeyPair
{
	my ($cacheName,$key) = @_;


	my ($res,$rawValue) = cacheGetKeyPair($cacheName,$key);
	# Thaw out item, if there is no error and we are defined
	if (!$res && defined($rawValue)) {
		$rawValue = Storable::thaw($rawValue);
	}

	return ($res,$rawValue);
}



## @fn getCacheHits
# Return cache hits
#
# @return Cache hits
sub getCacheHits
{
	my $res;


	# Get counter
	$res = defined($cache->get('Cache/Stats/Hit')) ? $cache->get('Cache/Stats/Hit') : 0;

	return $res;
}


## @fn getCacheMisses
# Return cache misses
#
# @return Cache misses
sub getCacheMisses
{
	my $res;


	# Get counter
	$res = defined($cache->get('Cache/Stats/Miss')) ? $cache->get('Cache/Stats/Miss') : 0;

	return $res;
}


1;
# vim: ts=4