package.xml 0000664 0001750 0001750 00000026300 14157324055 014272 0 ustar huixinchen huixinchen
yac
pecl.php.net
lockless user data cache
yac is a fast, lock-free, shared memory user data cache for PHP. it can be used to replace APC or local memcached.
Xinchen Hui
laruence
laruence@php.net
yes
2021-12-18
2.3.1
2.3.1
stable
stable
PHP
- PHP8.1 Supports
7.0.0
1.4.0
yac
2021-12-18
2.3.1
2.3.1
stable
stable
PHP License
- PHP8.1 Supports
2021-01-06
2.3.0
2.3.0
stable
stable
PHP License
- PHP8 Supported
2020-03-31
2.2.1
2.2.1
stable
stable
PHP License
- Refactor key manipulation, avoding memory allocation
- Refactor Yac::__set/__get by using native objects_handler
2020-03-31
2.2.0
2.2.0
stable
stable
PHP License
- Added json serializer
- Added igbinary serializer
- change yac.serilalizer to string, "php", "json" etc
2020-03-27
2.1.2
2.1.2
stable
stable
PHP License
- Fixed compiler warning of redefinition of macros
- Fixed crc32c only pick the first byte
- Also use crc32_u32 in 64 bits
2020-03-25
2.1.1
2.1.1
stable
stable
PHP License
- Fixed Build in 32bits
2020-03-25
2.1.0
2.1.0
stable
stable
PHP License
- Implemnented CAS based lock-free protection
- Use SSE4.2 _mm_crc32 instead of normal crc32 to make speedup
- Some optimization to avoding memory usage
2020-03-19
2.0.4
2.0.4
beta
beta
PHP License
- Fixed PHP-7.4 windows build
2020-01-06
2.0.3
2.0.3
beta
beta
PHP License
- Fixed PHP-7.4 Compatiblity
2017-07-27
2.0.2
2.0.2
beta
beta
PHP License
- Fixed PHP-7.2 Compatiblity
2016-07-02
2.0.1
2.0.1
beta
beta
PHP License
- Fixed issue #63 (include smart_str.h)
2015-10-27
2.0.0
2.0.0
beta
beta
PHP License
- Release yac for PHP7
2014-10-22
0.9.2
0.9.2
beta
beta
PHP License
- Add --with-system-fastlz option
2014-07-25
0.9.1
0.9.1
beta
beta
PHP License
- Try to fix windows build
2014-07-24
0.9.0
0.9.0
beta
beta
PHP License
- first release
yac-2.3.1/storage/allocator/allocators/createfilemapping.c 0000664 0001750 0001750 00000022676 14157324055 025016 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Xinchen Hui |
| Dmitry Stogov |
| Wei Dai |
+----------------------------------------------------------------------+
*/
#include "php.h"
#include "php_yac.h"
#include "storage/yac_storage.h"
#include "storage/allocator/yac_allocator.h"
#include
#include
#include
#define ACCEL_FILEMAP_NAME "Yac.SharedMemoryArea"
#define ACCEL_FILEMAP_BASE "Yac.MemoryBase"
#define MAX_MAP_RETRIES 25
static HANDLE memfile = NULL;
static void *mapping_base;
typedef struct {
yac_shared_segment common;
unsigned long size;
} yac_shared_segment_create_file;
#ifdef USE_FILE_MAPPING
static char *create_name_with_username(char *name) /* {{{ */ {
static char newname[MAXPATHLEN + UNLEN + 4];
char uname[UNLEN + 1];
DWORD unsize = UNLEN;
GetUserName(uname, &unsize);
snprintf(newname, sizeof(newname) - 1, "%s@%s", name, uname);
return newname;
}
/* }}} */
static char *get_mmap_base_file(void) /* {{{ */ {
static char windir[MAXPATHLEN+UNLEN + 3 + sizeof("\\\\@")];
char uname[UNLEN + 1];
DWORD unsize = UNLEN;
int l;
GetTempPath(MAXPATHLEN, windir);
GetUserName(uname, &unsize);
l = strlen(windir);
snprintf(windir + l, sizeof(windir) - l - 1, "\\%s@%s", ACCEL_FILEMAP_BASE, uname);
return windir;
}
/* }}} */
static int yac_shared_alloc_reattach(size_t requested_size, char **error_in) /* {{{ */ {
void *wanted_mapping_base;
char *mmap_base_file = get_mmap_base_file();
FILE *fp = fopen(mmap_base_file, "r");
MEMORY_BASIC_INFORMATION info;
if (!fp) {
*error_in="fopen";
return ALLOC_FAILURE;
}
if (!fscanf(fp, "%p", &wanted_mapping_base)) {
*error_in="read mapping base";
fclose(fp);
return ALLOC_FAILURE;
}
fclose(fp);
/* Check if the requested address space is free */
if (VirtualQuery(wanted_mapping_base, &info, sizeof(info)) == 0) {
*error_in="VirtualQuery";
return ALLOC_FAILURE;
}
if (info.State != MEM_FREE) {
*error_in="info.State";
return ALLOC_FAILURE;
}
if (info.RegionSize < requested_size) {
*error_in="info.RegionSize";
return ALLOC_FAILURE;
}
mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, wanted_mapping_base);
if (mapping_base == NULL) {
return ALLOC_FAIL_MAPPING;
}
return SUCCESSFULLY_REATTACHED;
}
/* }}} */
static int create_segments(unsigned long k_size, unsigned long v_size, yac_shared_segment_create_file **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
int ret;
unsigned long allocate_size, occupied_size = 0;
unsigned int i, segment_size, segments_num = 1024, is_reattach = 0;
int map_retries = 0;
yac_shared_segment_create_file first_segment;
void *default_mapping_base_set[] = {0, 0};
/* TODO:
improve fixed addresses on x64. It still makes no sense to do it as Windows addresses are virtual per se and can or should be randomized anyway
through Address Space Layout Radomization (ASLR). We can still let the OS do its job and be sure that each process gets the same address if
desired. Not done yet, @zend refused but did not remember the exact reason, pls add info here if one of you know why :)
*/
#if defined(_WIN64)
void *vista_mapping_base_set[] = { (void *) 0x0000100000000000, (void *) 0x0000200000000000, (void *) 0x0000300000000000, (void *) 0x0000700000000000, 0 };
#else
void *vista_mapping_base_set[] = { (void *) 0x20000000, (void *) 0x21000000, (void *) 0x30000000, (void *) 0x31000000, (void *) 0x50000000, 0 };
#endif
void **wanted_mapping_base = default_mapping_base_set;
k_size = YAC_SMM_ALIGNED_SIZE(k_size);
v_size = YAC_SMM_ALIGNED_SIZE(v_size);
while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
segments_num >>= 1;
}
segment_size = v_size / segments_num;
++segments_num;
allocate_size = k_size + v_size;
/* Mapping retries: When Apache2 restarts, the parent process startup routine
can be called before the child process is killed. In this case, the map will fail
and we have to sleep some time (until the child releases the mapping object) and retry.*/
do {
memfile = OpenFileMapping(FILE_MAP_WRITE, 0, create_name_with_username(ACCEL_FILEMAP_NAME));
if (memfile == NULL) {
break;
}
ret = yac_shared_alloc_reattach((size_t)k_size, error_in);
if (ret == ALLOC_FAIL_MAPPING) {
/* Mapping failed, wait for mapping object to get freed and retry */
CloseHandle(memfile);
memfile = NULL;
Sleep(1000 * (map_retries + 1));
} else if (ret == SUCCESSFULLY_REATTACHED) {
is_reattach = 1;
break;
} else {
return ret;
}
} while (++map_retries < MAX_MAP_RETRIES);
if (map_retries == MAX_MAP_RETRIES) {
*error_in = "OpenFileMapping";
return 0;
}
*shared_segments_p = (yac_shared_segment_create_file *)calloc(1, segments_num * sizeof(yac_shared_segment_create_file));
if(!*shared_segments_p) {
*error_in = "calloc";
return 0;
}
*shared_segments_count = segments_num;
/* Starting from windows Vista, heap randomization occurs which might cause our mapping base to
be taken (fail to map). So under Vista, we try to map into a hard coded predefined addresses
in high memory. */
if (!YAC_G(mmap_base) || !*YAC_G(mmap_base)) {
do {
OSVERSIONINFOEX osvi;
SYSTEM_INFO si;
ZeroMemory(&si, sizeof(SYSTEM_INFO));
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if (! GetVersionEx ((OSVERSIONINFO *) &osvi)) {
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (!GetVersionEx((OSVERSIONINFO *)&osvi)) {
break;
}
}
GetSystemInfo(&si);
/* Are we running Vista ? */
if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT && osvi.dwMajorVersion == 6) {
wanted_mapping_base = vista_mapping_base_set;
}
} while (0);
} else {
char *s = YAC_G(mmap_base);
/* skip leading 0x, %p assumes hexdeciaml format anyway */
if (*s == '0' && *(s + 1) == 'x') {
s += 2;
}
if (sscanf(s, "%p", &default_mapping_base_set[0]) != 1) {
*error_in = "mapping";
return 0;
}
}
if (is_reattach == 0) {
memfile = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, allocate_size, create_name_with_username(ACCEL_FILEMAP_NAME));
if (memfile == NULL) {
*error_in = "CreateFileMapping";
return 0;
}
do {
first_segment.common.p = mapping_base = MapViewOfFileEx(memfile, FILE_MAP_ALL_ACCESS, 0, 0, 0, *wanted_mapping_base);
if (wanted_mapping_base == NULL) {
break;
}
*wanted_mapping_base++;
} while (!mapping_base);
}
if(mapping_base == NULL) {
*error_in = "MapViewOfFileEx";
return 0;
} else {
char *mmap_base_file = get_mmap_base_file();
FILE *fp = fopen(mmap_base_file, "w");
if (!fp) {
*error_in = "get_mmap_base_file";
return 0;
}
fprintf(fp, "%p", mapping_base);
fclose(fp);
}
first_segment.common.p = mapping_base;
first_segment.size = allocate_size;
first_segment.common.size = k_size;
first_segment.common.pos = 0;
(*shared_segments_p)[0] = first_segment;
occupied_size = k_size;
for (i = 1; i < segments_num; i++) {
(*shared_segments_p)[i].size = 0;
(*shared_segments_p)[i].common.pos = 0;
(*shared_segments_p)[i].common.p = (void *)((char *)first_segment.common.p + occupied_size);
if ((allocate_size - occupied_size) >= YAC_SMM_ALIGNED_SIZE(segment_size)) {
(*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
occupied_size += YAC_SMM_ALIGNED_SIZE(segment_size);
} else {
(*shared_segments_p)[i].common.size = (allocate_size - occupied_size);
break;
}
}
return 1;
}
/* }}} */
static int detach_segment(yac_shared_segment *shared_segment) /* {{{ */ {
if (!shared_segment->size && mapping_base) {
UnmapViewOfFile(mapping_base);
CloseHandle(memfile);
}
return 0;
}
/* }}} */
static unsigned long segment_type_size(void) /* {{{ */ {
return sizeof(yac_shared_segment_create_file);
}
/* }}} */
yac_shared_memory_handlers yac_alloc_create_file_handlers = /* {{{ */ {
(create_segments_t)create_segments,
detach_segment,
segment_type_size
};
/* }}} */
#endif /* USE_CREATE_FILE */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/allocator/allocators/mmap.c 0000664 0001750 0001750 00000007552 14157324055 022265 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Xinchen Hui |
+----------------------------------------------------------------------+
*/
#include "storage/yac_storage.h"
#include "storage/allocator/yac_allocator.h"
#ifdef USE_MMAP
#include
#include
#include
#include
#include
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
# define MAP_ANONYMOUS MAP_ANON
#endif
#ifndef MAP_FAILED
#define MAP_FAILED (void *)-1
#endif
typedef struct {
yac_shared_segment common;
unsigned long size;
} yac_shared_segment_mmap;
static int create_segments(unsigned long k_size, unsigned long v_size, yac_shared_segment_mmap **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
unsigned long allocate_size, occupied_size = 0;
unsigned int i, segment_size, segments_num = 1024;
yac_shared_segment_mmap first_segment;
k_size = YAC_SMM_ALIGNED_SIZE(k_size);
v_size = YAC_SMM_ALIGNED_SIZE(v_size);
while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
segments_num >>= 1;
}
segment_size = v_size / segments_num;
++segments_num;
allocate_size = k_size + v_size;
first_segment.common.p = mmap(0, allocate_size, PROT_READ | PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, -1, 0);
if (first_segment.common.p == MAP_FAILED) {
*error_in = "mmap";
return 0;
}
first_segment.size = allocate_size;
first_segment.common.size = k_size;
first_segment.common.pos = 0;
*shared_segments_p = (yac_shared_segment_mmap *)calloc(1, segments_num * sizeof(yac_shared_segment_mmap));
if (!*shared_segments_p) {
munmap(first_segment.common.p, first_segment.size);
*error_in = "calloc";
return 0;
} else {
*shared_segments_p[0] = first_segment;
}
*shared_segments_count = segments_num;
occupied_size = k_size;
for (i = 1; i < segments_num; i++) {
(*shared_segments_p)[i].size = 0;
(*shared_segments_p)[i].common.pos = 0;
(*shared_segments_p)[i].common.p = first_segment.common.p + occupied_size;
if ((allocate_size - occupied_size) >= YAC_SMM_ALIGNED_SIZE(segment_size)) {
(*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
occupied_size += YAC_SMM_ALIGNED_SIZE(segment_size);
} else {
(*shared_segments_p)[i].common.size = (allocate_size - occupied_size);
break;
}
}
return 1;
}
/* }}} */
static int detach_segment(yac_shared_segment *shared_segment) /* {{{ */ {
if (shared_segment->size) {
munmap(shared_segment->p, shared_segment->size);
}
return 0;
}
/* }}} */
static unsigned long segment_type_size(void) /* {{{ */ {
return sizeof(yac_shared_segment_mmap);
}
/* }}} */
yac_shared_memory_handlers yac_alloc_mmap_handlers = /* {{{ */ {
(create_segments_t)create_segments,
detach_segment,
segment_type_size
};
/* }}} */
#endif /* USE_MMAP */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/allocator/allocators/shm.c 0000664 0001750 0001750 00000014154 14157324055 022116 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Xinchen Hui |
+----------------------------------------------------------------------+
*/
#include "storage/yac_storage.h"
#include "storage/allocator/yac_allocator.h"
#ifdef USE_SHM
#if defined(__FreeBSD__)
# include
#endif
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
typedef struct {
yac_shared_segment common;
int shm_id;
} yac_shared_segment_shm;
static int create_segments(size_t k_size, size_t v_size, yac_shared_segment_shm **shared_segments_p, int *shared_segments_count, char **error_in) /* {{{ */ {
struct shmid_ds sds;
int shm_id, shmget_flags;
yac_shared_segment_shm *shared_segments, first_segment;
unsigned int i, j, allocate_size, allocated_num, segments_num, segment_size;
shmget_flags = IPC_CREAT|SHM_R|SHM_W|IPC_EXCL;
segments_num = 1024;
while ((v_size / segments_num) < YAC_SMM_SEGMENT_MIN_SIZE) {
segments_num >>= 1;
}
segment_size = v_size / segments_num;
allocate_size = YAC_SMM_SEGMENT_MAX_SIZE;
while ((shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags)) < 0) {
allocate_size >>= 1;
}
if (shm_id < 0) {
/* this should never happen */
*error_in = "shmget";
return 0;
}
if (allocate_size < YAC_SMM_SEGMENT_MIN_SIZE) {
/* this should never happen */
*error_in = "shmget";
return 0;
}
if (k_size <= allocate_size) {
first_segment.shm_id = shm_id;
first_segment.common.pos = 0;
first_segment.common.size = allocate_size;
first_segment.common.p = shmat(shm_id, NULL, 0);
shmctl(shm_id, IPC_RMID, &sds);
if (first_segment.common.p == (void *)-1) {
*error_in = "shmat";
return 0;
}
} else {
shmctl(shm_id, IPC_RMID, &sds);
*error_in = "shmget";
return 0;
}
allocated_num = (v_size % allocate_size)? (v_size / allocate_size) + 1 : (v_size / allocate_size);
shared_segments = (yac_shared_segment_shm *)calloc(1, (allocated_num) * sizeof(yac_shared_segment_shm));
if (!shared_segments) {
*error_in = "calloc";
return 0;
}
for (i = 0; i < allocated_num; i ++) {
shm_id = shmget(IPC_PRIVATE, allocate_size, shmget_flags);
if (shm_id == -1) {
*error_in = "shmget";
for (j = 0; j < i; j++) {
shmdt(shared_segments[j].common.p);
}
free(shared_segments);
return 0;
}
shared_segments[i].shm_id = shm_id;
shared_segments[i].common.pos = 0;
shared_segments[i].common.size = allocate_size;
shared_segments[i].common.p = shmat(shm_id, NULL, 0);
shmctl(shm_id, IPC_RMID, &sds);
if (shared_segments[i].common.p == (void *)-1) {
*error_in = "shmat";
for (j = 0; j < i; j++) {
shmdt(shared_segments[j].common.p);
}
free(shared_segments);
return 0;
}
}
++segments_num;
*shared_segments_p = (yac_shared_segment_shm *)calloc(1, segments_num * sizeof(yac_shared_segment_shm));
if (!*shared_segments_p) {
free(shared_segments);
*error_in = "calloc";
return 0;
} else {
*shared_segments_p[0] = first_segment;
}
*shared_segments_count = segments_num;
j = 0;
for (i = 1; i < segments_num; i++) {
if (shared_segments[j].common.pos == 0) {
(*shared_segments_p)[i].shm_id = shared_segments[j].shm_id;
}
if ((shared_segments[j].common.size - shared_segments[j].common.pos) >= (2 * YAC_SMM_ALIGNED_SIZE(segment_size))) {
(*shared_segments_p)[i].common.pos = 0;
(*shared_segments_p)[i].common.size = YAC_SMM_ALIGNED_SIZE(segment_size);
(*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
shared_segments[j].common.pos += YAC_SMM_ALIGNED_SIZE(segment_size);
} else {
(*shared_segments_p)[i].common.pos = 0;
(*shared_segments_p)[i].common.size = shared_segments[j].common.size - shared_segments[j].common.pos;
(*shared_segments_p)[i].common.p = shared_segments[j].common.p + YAC_SMM_ALIGNED_SIZE(shared_segments[j].common.pos);
j++;
}
}
free(shared_segments);
return 1;
}
/* }}} */
static int detach_segment(yac_shared_segment_shm *shared_segment) /* {{{ */ {
if (shared_segment->shm_id) {
shmdt(shared_segment->common.p);
}
return 1;
}
/* }}} */
static size_t segment_type_size(void) /* {{{ */ {
return sizeof(yac_shared_segment_shm);
}
/* }}} */
yac_shared_memory_handlers yac_alloc_shm_handlers = /* {{{ */ {
(create_segments_t)create_segments,
(detach_segment_t)detach_segment,
segment_type_size
};
/* }}} */
#endif /* USE_SHM */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/allocator/yac_allocator.h 0000664 0001750 0001750 00000007546 14157324055 022014 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Xinchen Hui |
+----------------------------------------------------------------------+
*/
#ifndef YAC_ALLOCATOR_H
#define YAC_ALLOCATOR_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#define YAC_SMM_ALIGNMENT 8
#define YAC_SMM_ALIGNMENT_LOG2 3
#define YAC_SMM_ALIGNMENT_MASK ~(YAC_SMM_ALIGNMENT - 1)
#define YAC_SMM_BLOCK_HEADER_SIZE YAC_SMM_ALIGNED_SIZE(sizeof(yac_shared_block_header))
#define YAC_SMM_MAIN_SEG_SIZE (4*1024*1024)
#define YAC_SMM_SEGMENT_MAX_SIZE (32*1024*1024)
#define YAC_SMM_SEGMENT_MIN_SIZE (4*1024*1024)
#define YAC_SMM_MIN_BLOCK_SIZE 128
#define YAC_SMM_ALIGNED_SIZE(x) (((x) + YAC_SMM_ALIGNMENT - 1) & YAC_SMM_ALIGNMENT_MASK)
#define YAC_SMM_TRUE_SIZE(x) ((x < YAC_SMM_MIN_BLOCK_SIZE)? (YAC_SMM_MIN_BLOCK_SIZE) : (YAC_SMM_ALIGNED_SIZE(x)))
#ifdef PHP_WIN32
# define USE_FILE_MAPPING 1
# define inline __inline
#elif defined(HAVE_SHM_MMAP_ANON)
# define USE_MMAP 1
#elif defined(HAVE_SHM_IPC)
# define USE_SHM 1
#else
#error(no builtin shared memory supported)
#endif
#define ALLOC_FAILURE 0
#define ALLOC_SUCCESS 1
#define FAILED_REATTACHED 2
#define SUCCESSFULLY_REATTACHED 4
#define ALLOC_FAIL_MAPPING 8
typedef int (*create_segments_t)(unsigned long k_size, unsigned long v_size, yac_shared_segment **shared_segments, int *shared_segment_count, char **error_in);
typedef int (*detach_segment_t)(yac_shared_segment *shared_segment);
typedef struct {
create_segments_t create_segments;
detach_segment_t detach_segment;
unsigned long (*segment_type_size)(void);
} yac_shared_memory_handlers;
typedef struct {
const char *name;
yac_shared_memory_handlers *handler;
} yac_shared_memory_handler_entry;
int yac_allocator_startup(unsigned long first_seg_size, unsigned long size, char **err);
void yac_allocator_shutdown(void);
unsigned long yac_allocator_real_size(unsigned long size);
void *yac_allocator_raw_alloc(unsigned long real_size, int seg);
int yac_allocator_free(void *p);
static inline void * yac_allocator_alloc(unsigned long size, int seg) {
unsigned long real_size = yac_allocator_real_size(size);
if (!real_size) {
return (void *)0;
}
return yac_allocator_raw_alloc(real_size, seg);
}
#if defined(USE_MMAP)
extern yac_shared_memory_handlers yac_alloc_mmap_handlers;
#define yac_shared_memory_handler yac_alloc_mmap_handlers
#define YAC_SHARED_MEMORY_HANDLER_NAME "mmap"
#elif defined(USE_SHM)
extern yac_shared_memory_handlers yac_alloc_shm_handlers;
#define yac_shared_memory_handler yac_alloc_shm_handlers
#define YAC_SHARED_MEMORY_HANDLER_NAME "shm"
#elif defined(USE_FILE_MAPPING)
extern yac_shared_memory_handlers yac_alloc_create_file_handlers;
#define yac_shared_memory_handler yac_alloc_create_file_handlers
#define YAC_SHARED_MEMORY_HANDLER_NAME "file_mapping"
#endif
#endif /* YAC_ALLOCATOR_H */
yac-2.3.1/storage/allocator/yac_allocator.c 0000664 0001750 0001750 00000013444 14157324055 022001 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Authors: Xinchen Hui |
+----------------------------------------------------------------------+
*/
#include
#include
#include
#include "php.h"
#include "storage/yac_storage.h"
#include "yac_allocator.h"
int yac_allocator_startup(unsigned long k_size, unsigned long size, char **msg) /* {{{ */ {
char *p;
yac_shared_segment *segments = NULL;
int i, segments_num, segments_array_size, segment_size;
const yac_shared_memory_handlers *he;
if ((he = &yac_shared_memory_handler)) {
int ret = he->create_segments(k_size, size, &segments, &segments_num, msg);
if (!ret) {
if (segments) {
int i;
for (i = 0; i < segments_num; i++) {
if (segments[i].p && segments[i].p != (void *)-1) {
he->detach_segment(&segments[i]);
}
}
free(segments);
}
return 0;
}
} else {
return 0;
}
segment_size = he->segment_type_size();
segments_array_size = (segments_num - 1) * segment_size;
yac_storage = segments[0].p;
memcpy(&YAC_SG(first_seg), (char *)(&segments[0]), segment_size);
YAC_SG(segments_num) = segments_num - 1;
YAC_SG(segments_num_mask) = YAC_SG(segments_num) - 1;
YAC_SG(segments) = (yac_shared_segment **)((char *)yac_storage + YAC_SMM_ALIGNED_SIZE(sizeof(yac_storage_globals) + segment_size - sizeof(yac_shared_segment)));
p = (char *)YAC_SG(segments) + (sizeof(void *) * YAC_SG(segments_num));
memcpy(p, (char *)segments + segment_size, segments_array_size);
for (i = 0; i < YAC_SG(segments_num); i++) {
YAC_SG(segments)[i] = (yac_shared_segment *)p;
p += segment_size;
}
YAC_SG(slots) = (yac_kv_key *)((char *)YAC_SG(segments)
+ (YAC_SG(segments_num) * sizeof(void *)) + YAC_SMM_ALIGNED_SIZE(segments_array_size));
free(segments);
return 1;
}
/* }}} */
void yac_allocator_shutdown(void) /* {{{ */ {
yac_shared_segment **segments;
const yac_shared_memory_handlers *he;
segments = YAC_SG(segments);
if (segments) {
if ((he = &yac_shared_memory_handler)) {
int i = 0;
for (i = 0; i < YAC_SG(segments_num); i++) {
he->detach_segment(segments[i]);
}
he->detach_segment(&YAC_SG(first_seg));
}
}
}
/* }}} */
static inline void *yac_allocator_alloc_algo2(unsigned long size, int hash) /* {{{ */ {
yac_shared_segment *segment;
unsigned int seg_size, retry, pos, current;
current = hash & YAC_SG(segments_num_mask);
/* do we really need lock here? it depends the real life exam */
retry = 3;
do_retry:
segment = YAC_SG(segments)[current];
seg_size = segment->size;
pos = segment->pos;
if ((seg_size - pos) >= size) {
do_alloc:
pos += size;
segment->pos = pos;
if (segment->pos == pos) {
return (void *)((char *)segment->p + (pos - size));
} else if (retry--) {
goto do_retry;
}
return NULL;
} else {
int i, max;
max = (YAC_SG(segments_num) > 4)? 4 : YAC_SG(segments_num);
for (i = 1; i < max; i++) {
segment = YAC_SG(segments)[(current + i) & YAC_SG(segments_num_mask)];
seg_size = segment->size;
pos = segment->pos;
if ((seg_size - pos) >= size) {
current = (current + i) & YAC_SG(segments_num_mask);
goto do_alloc;
}
}
segment->pos = 0;
pos = 0;
++YAC_SG(recycles);
goto do_alloc;
}
}
/* }}} */
#if 0
static inline void *yac_allocator_alloc_algo1(unsigned long size) /* {{{ */ {
int i, j, picked_seg, atime;
picked_seg = (YAC_SG(current_seg) + 1) & YAC_SG(segments_num_mask);
atime = YAC_SG(segments)[picked_seg]->atime;
for (i = 0; i < 10; i++) {
j = (picked_seg + 1) & YAC_SG(segments_num_mask);
if (YAC_SG(segments)[j]->atime < atime) {
picked_seg = j;
atime = YAC_SG(segments)[j]->atime;
}
}
YAC_SG(current_seg) = picked_seg;
YAC_SG(segments)[picked_seg]->pos = 0;
return yac_allocator_alloc_algo2(size);
}
/* }}} */
#endif
unsigned long yac_allocator_real_size(unsigned long size) /* {{{ */ {
unsigned long real_size = YAC_SMM_TRUE_SIZE(size);
if (real_size > YAC_SG(segments)[0]->size) {
return 0;
}
return real_size;
}
/* }}} */
void * yac_allocator_raw_alloc(unsigned long real_size, int hash) /* {{{ */ {
return yac_allocator_alloc_algo2(real_size, hash);
/*
if (YAC_SG(exhausted)) {
return yac_allocator_alloc_algo1(real_size);
} else {
void *p;
if ((p = yac_allocator_alloc_algo2(real_size))) {
return p;
}
return yac_allocator_alloc_algo1(real_size);
}
*/
}
/* }}} */
#if 0
void yac_allocator_touch(void *p, unsigned long atime) /* {{{ */ {
yac_shared_block_header h = *(yac_shared_block_header *)(p - sizeof(yac_shared_block_header));
if (h.seg >= YAC_SG(segments_num)) {
return;
}
YAC_SG(segments)[h.seg]->atime = atime;
}
/* }}} */
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/yac_storage.h 0000664 0001750 0001750 00000010132 14157324055 017501 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef YAC_STORAGE_H
#define YAC_STORAGE_H
#define YAC_STORAGE_MAX_ENTRY_LEN (1 << 20)
#define YAC_STORAGE_MAX_KEY_LEN (48)
#define YAC_STORAGE_FACTOR (1.25)
#define YAC_KEY_KLEN_MASK (255)
#define YAC_KEY_VLEN_BITS (8)
#define YAC_KEY_KLEN(k) ((k).len & YAC_KEY_KLEN_MASK)
#define YAC_KEY_VLEN(k) ((k).len >> YAC_KEY_VLEN_BITS)
#define YAC_KEY_SET_LEN(k, kl, vl) ((k).len = (vl << YAC_KEY_VLEN_BITS) | (kl & YAC_KEY_KLEN_MASK))
#define YAC_FULL_CRC_THRESHOLD 256
#define USER_ALLOC emalloc
#define USER_FREE efree
typedef struct {
unsigned long atime;
unsigned int len;
char data[1];
} yac_kv_val;
typedef struct {
unsigned long h;
unsigned int crc;
unsigned int ttl;
unsigned int len;
unsigned int flag;
unsigned int size;
unsigned int mutex;
yac_kv_val *val;
unsigned char key[YAC_STORAGE_MAX_KEY_LEN];
} yac_kv_key;
typedef struct _yac_item_list {
unsigned int index;
unsigned long h;
unsigned long crc;
unsigned int ttl;
unsigned int k_len;
unsigned int v_len;
unsigned int flag;
unsigned int size;
unsigned char key[YAC_STORAGE_MAX_KEY_LEN];
struct _yac_item_list *next;
} yac_item_list;
typedef struct {
volatile unsigned int pos;
unsigned int size;
void *p;
} yac_shared_segment;
typedef struct {
unsigned long k_msize;
unsigned long v_msize;
unsigned int segments_num;
unsigned int segment_size;
unsigned int slots_num;
unsigned int slots_size;
unsigned int miss;
unsigned int fails;
unsigned int kicks;
unsigned int recycles;
unsigned long hits;
} yac_storage_info;
typedef struct {
yac_kv_key *slots;
unsigned int slots_mask;
unsigned int slots_num;
unsigned int slots_size;
unsigned int miss;
unsigned int fails;
unsigned int kicks;
unsigned int recycles;
unsigned long hits;
yac_shared_segment **segments;
unsigned int segments_num;
unsigned int segments_num_mask;
yac_shared_segment first_seg;
} yac_storage_globals;
extern yac_storage_globals *yac_storage;
#define YAC_SG(element) (yac_storage->element)
int yac_storage_startup(unsigned long first_size, unsigned long size, char **err);
void yac_storage_shutdown(void);
int yac_storage_find(const char *key, unsigned int len, char **data, unsigned int *size, unsigned int *flag, int *cas, unsigned long tv);
int yac_storage_update(const char *key, unsigned int len, char *data, unsigned int size, unsigned int falg, int ttl, int add, unsigned long tv);
int yac_storage_delete(const char *key, unsigned int len, int ttl, unsigned long tv);
void yac_storage_flush(void);
const char * yac_storage_shared_memory_name(void);
yac_storage_info * yac_storage_get_info(void);
void yac_storage_free_info(yac_storage_info *info);
yac_item_list * yac_storage_dump(unsigned int limit);
void yac_storage_free_list(yac_item_list *list);
#define yac_storage_exists(ht, key, len) yac_storage_find(ht, key, len, NULL)
#endif /* YAC_STORAGE_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/yac_storage.c 0000664 0001750 0001750 00000051567 14157324055 017515 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#if HAVE_SSE_CRC32
#include "Zend/zend_cpuinfo.h"
#include
static uint32_t crc32c_sse42(const char *dagta, unsigned int size);
#endif
#include "yac_atomic.h"
#include "yac_storage.h"
#include "allocator/yac_allocator.h"
yac_storage_globals *yac_storage;
static uint32_t (*yac_crc)(const char *data, unsigned int size);
static uint32_t crc32(const char *dagta, unsigned int size);
static inline unsigned int yac_storage_align_size(unsigned int size) /* {{{ */ {
int bits = 0;
while ((size = size >> 1)) {
++bits;
}
return (1 << bits);
}
/* }}} */
int yac_storage_startup(unsigned long fsize, unsigned long size, char **msg) /* {{{ */ {
unsigned long real_size;
if (!yac_allocator_startup(fsize, size, msg)) {
return 0;
}
#if HAVE_SSE_CRC32
if (zend_cpu_supports_sse42()) {
yac_crc = crc32c_sse42;
} else
#endif
{
yac_crc = crc32;
}
size = YAC_SG(first_seg).size - ((char *)YAC_SG(slots) - (char *)yac_storage);
real_size = yac_storage_align_size(size / sizeof(yac_kv_key));
if (!((size / sizeof(yac_kv_key)) & ~(real_size << 1))) {
real_size <<= 1;
}
YAC_SG(slots_size) = real_size;
YAC_SG(slots_mask) = real_size - 1;
YAC_SG(slots_num) = 0;
YAC_SG(fails) = 0;
YAC_SG(hits) = 0;
YAC_SG(miss) = 0;
YAC_SG(kicks) = 0;
memset((char *)YAC_SG(slots), 0, sizeof(yac_kv_key) * real_size);
return 1;
}
/* }}} */
void yac_storage_shutdown(void) /* {{{ */ {
yac_allocator_shutdown();
}
/* }}} */
/* {{{ MurmurHash2 (Austin Appleby)
*/
static inline uint64_t yac_inline_hash_func1(const char *data, unsigned int len) {
unsigned int h, k;
h = 0 ^ len;
while (len >= 4) {
k = data[0];
k |= data[1] << 8;
k |= data[2] << 16;
k |= data[3] << 24;
k *= 0x5bd1e995;
k ^= k >> 24;
k *= 0x5bd1e995;
h *= 0x5bd1e995;
h ^= k;
data += 4;
len -= 4;
}
switch (len) {
case 3:
h ^= data[2] << 16;
case 2:
h ^= data[1] << 8;
case 1:
h ^= data[0];
h *= 0x5bd1e995;
}
h ^= h >> 13;
h *= 0x5bd1e995;
h ^= h >> 15;
return h;
}
/* }}} */
/* {{{ DJBX33A (Daniel J. Bernstein, Times 33 with Addition)
*
* This is Daniel J. Bernstein's popular `times 33' hash function as
* posted by him years ago on comp->lang.c. It basically uses a function
* like ``hash(i) = hash(i-1) * 33 + str[i]''. This is one of the best
* known hash functions for strings. Because it is both computed very
* fast and distributes very well.
*
* The magic of number 33, i.e. why it works better than many other
* constants, prime or not, has never been adequately explained by
* anyone. So I try an explanation: if one experimentally tests all
* multipliers between 1 and 256 (as RSE did now) one detects that even
* numbers are not useable at all. The remaining 128 odd numbers
* (except for the number 1) work more or less all equally well. They
* all distribute in an acceptable way and this way fill a hash table
* with an average percent of approx. 86%.
*
* If one compares the Chi^2 values of the variants, the number 33 not
* even has the best value. But the number 33 and a few other equally
* good numbers like 17, 31, 63, 127 and 129 have nevertheless a great
* advantage to the remaining numbers in the large set of possible
* multipliers: their multiply operation can be replaced by a faster
* operation based on just one shift plus either a single addition
* or subtraction operation. And because a hash function has to both
* distribute good _and_ has to be very fast to compute, those few
* numbers should be preferred and seems to be the reason why Daniel J.
* Bernstein also preferred it.
*
*
* -- Ralf S. Engelschall
*/
static inline uint64_t yac_inline_hash_func2(const char *key, uint32_t len) {
register uint64_t hash = 5381;
/* variant with the hash unrolled eight times */
for (; len >= 8; len -= 8) {
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
hash = ((hash << 5) + hash) + *key++;
}
switch (len) {
case 7: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 6: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 5: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 4: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 3: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 2: hash = ((hash << 5) + hash) + *key++; /* fallthrough... */
case 1: hash = ((hash << 5) + hash) + *key++; break;
case 0: break;
default: break;
}
return hash;
}
/* }}} */
/* {{{ COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or
* code or tables extracted from it, as desired without restriction.
*
* First, the polynomial itself and its table of feedback terms. The
* polynomial is
* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
*
* Note that we take it "backwards" and put the highest-order term in
* the lowest-order bit. The X^32 term is "implied"; the LSB is the
* X^31 term, etc. The X^0 term (usually shown as "+1") results in
* the MSB being 1
*
* Note that the usual hardware shift register implementation, which
* is what we're using (we're merely optimizing it by doing eight-bit
* chunks at a time) shifts bits into the lowest-order term. In our
* implementation, that means shifting towards the right. Why do we
* do it this way? Because the calculated CRC must be transmitted in
* order from highest-order term to lowest-order term. UARTs transmit
* characters in order from LSB to MSB. By storing the CRC this way
* we hand it to the UART in the order low-byte to high-byte; the UART
* sends each low-bit to high-bit; and the result is transmission bit
* by bit from highest- to lowest-order term without requiring any bit
* shuffling on our part. Reception works similarly
*
* The feedback terms table consists of 256, 32-bit entries. Notes
*
* The table can be generated at runtime if desired; code to do so
* is shown later. It might not be obvious, but the feedback
* terms simply represent the results of eight shift/xor opera
* tions for all combinations of data and CRC register values
*
* The values must be right-shifted by eight bits by the "updcrc
* logic; the shift must be unsigned (bring in zeroes). On some
* hardware you could probably optimize the shift in assembler by
* using byte-swap instructions
* polynomial $edb88320
*
*
* CRC32 code derived from work by Gary S. Brown.
*/
static unsigned int crc32_tab[] = {
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
static uint32_t crc32(const char *buf, unsigned int size) {
const char *p;
uint32_t crc = 0 ^ 0xFFFFFFFF;
p = buf;
while (size--) {
crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8);
}
return crc ^ 0xFFFFFFFF;
}
/* }}} */
#if HAVE_SSE_CRC32
static uint32_t crc32c_sse42(const char *buf, unsigned int size) /* {{{ */ {
uint32_t crc = 0 ^ 0xFFFFFFFF;
#if __x86_64__
while (size >= sizeof(uint64_t)) {
crc = _mm_crc32_u64(crc, *(uint64_t*)buf);
buf += sizeof(uint64_t);
size -= sizeof(uint64_t);
}
#endif
while (size >= sizeof(uint32_t)) {
crc = _mm_crc32_u32(crc, *(uint32_t*)buf);
buf += sizeof(uint32_t);
size -= sizeof(uint32_t);
}
if (size >= sizeof(uint16_t)) {
crc = _mm_crc32_u16(crc, *(uint16_t*)buf);
buf += sizeof(uint16_t);
size -= sizeof(uint16_t);
}
if (size) {
crc = _mm_crc32_u8(crc, *buf);
}
return crc ^ 0xFFFFFFFF;
}
/* }}} */
#endif
static inline unsigned int yac_crc32(char *data, unsigned int size) /* {{{ */ {
if (size < YAC_FULL_CRC_THRESHOLD) {
return yac_crc(data, size);
} else {
int i = 0;
char crc_contents[YAC_FULL_CRC_THRESHOLD];
int head = YAC_FULL_CRC_THRESHOLD >> 2;
int tail = YAC_FULL_CRC_THRESHOLD >> 4;
int body = YAC_FULL_CRC_THRESHOLD - head - tail;
char *p = data + head;
char *q = crc_contents + head;
int step = (size - tail - head) / body;
memcpy(crc_contents, data, head);
for (; i < body; i++, q++, p+= step) {
*q = *p;
}
memcpy(q, p, tail);
return yac_crc(crc_contents, YAC_FULL_CRC_THRESHOLD);
}
}
/* }}} */
int yac_storage_find(const char *key, unsigned int len, char **data, unsigned int *size, unsigned int *flag, int *cas, unsigned long tv) /* {{{ */ {
uint64_t h, hash, seed;
yac_kv_key k, *p;
yac_kv_val v;
hash = h = yac_inline_hash_func1(key, len);
p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
++YAC_SG(miss);
return 0;
}
k = *p;
READP(p);
if (k.val) {
char *s;
uint32_t i;
if (k.h == hash && YAC_KEY_KLEN(k) == len) {
v = *(k.val);
if (!memcmp(k.key, key, len)) {
s = USER_ALLOC(YAC_KEY_VLEN(k) + 1);
memcpy(s, (char *)k.val->data, YAC_KEY_VLEN(k));
do_verify:
if (k.len != v.len) {
USER_FREE(s);
++YAC_SG(miss);
return 0;
}
if (k.ttl) {
if (k.ttl <= tv) {
++YAC_SG(miss);
USER_FREE(s);
return 0;
}
}
if (k.crc != yac_crc32(s, YAC_KEY_VLEN(k))) {
USER_FREE(s);
++YAC_SG(miss);
return 0;
}
s[YAC_KEY_VLEN(k)] = '\0';
k.val->atime = tv;
*data = s;
*size = YAC_KEY_VLEN(k);
*flag = k.flag;
++YAC_SG(hits);
return 1;
}
}
seed = yac_inline_hash_func2(key, len);
for (i = 0; i < 3; i++) {
h += seed & YAC_SG(slots_mask);
p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
++YAC_SG(miss);
return 0;
}
k = *p;
READP(p);
if (k.h == hash && YAC_KEY_KLEN(k) == len) {
v = *(k.val);
if (!memcmp(k.key, key, len)) {
s = USER_ALLOC(YAC_KEY_VLEN(k) + 1);
memcpy(s, (char *)k.val->data, YAC_KEY_VLEN(k));
goto do_verify;
}
}
}
}
++YAC_SG(miss);
return 0;
}
/* }}} */
int yac_storage_delete(const char *key, unsigned int len, int ttl, unsigned long tv) /* {{{ */ {
uint64_t hash, h, seed;
yac_kv_key k, *p;
hash = h = yac_inline_hash_func1(key, len);
p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
return 0;
}
k = *p;
READP(p);
if (k.val) {
uint32_t i;
if (k.h == hash && YAC_KEY_KLEN(k) == len) {
if (!memcmp((char *)k.key, key, len)) {
if (ttl == 0) {
p->ttl = 1;
} else {
p->ttl = ttl + tv;
}
return 1;
}
}
seed = yac_inline_hash_func2(key, len);
for (i = 0; i < 3; i++) {
h += seed & YAC_SG(slots_mask);
p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
return 0;
}
k = *p;
READP(p);
if (k.val == NULL) {
return 1;
} else if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
p->ttl = 1;
return 1;
}
}
}
return 0;
}
/* }}} */
int yac_storage_update(const char *key, unsigned int len, char *data, unsigned int size, unsigned int flag, int ttl, int add, unsigned long tv) /* {{{ */ {
uint64_t hash, h;
int idx = 0, is_valid;
yac_kv_key *p, k, *paths[4];
yac_kv_val *val, *s;
unsigned long real_size;
hash = h = yac_inline_hash_func1(key, len);
paths[idx++] = p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
return 0;
}
k = *p;
READP(p);
if (k.val) {
/* Found the exact match */
if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
do_update:
is_valid = 0;
if (k.crc == yac_crc32(k.val->data, YAC_KEY_VLEN(k))) {
is_valid = 1;
}
if (add && (!k.ttl || k.ttl > tv) && is_valid) {
return 0;
}
if (k.size >= size && is_valid) {
s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
memcpy(s->data, data, size);
if (ttl) {
k.ttl = (uint64_t)tv + ttl;
} else {
k.ttl = 0;
}
s->atime = tv;
YAC_KEY_SET_LEN(*s, len, size);
memcpy((char *)k.val, (char *)s, sizeof(yac_kv_val) + size - 1);
k.crc = yac_crc32(s->data, size);
k.flag = flag;
memcpy(k.key, key, len);
YAC_KEY_SET_LEN(k, len, size);
if (!WRITEP(p)) {
USER_FREE(s);
return 0;
}
*p = k;
READP(p);
USER_FREE(s);
return 1;
} else {
uint32_t msize;
real_size = yac_allocator_real_size(sizeof(yac_kv_val) + (size * YAC_STORAGE_FACTOR) - 1);
if (!real_size) {
++YAC_SG(fails);
return 0;
}
msize = sizeof(yac_kv_val) + size - 1;
s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
memcpy(s->data, data, size);
s->atime = tv;
YAC_KEY_SET_LEN(*s, len, size);
val = yac_allocator_raw_alloc(real_size, (int)hash);
if (val) {
memcpy((char *)val, (char *)s, msize);
if (ttl) {
k.ttl = tv + ttl;
} else {
k.ttl = 0;
}
k.crc = yac_crc32(s->data, size);
k.val = val;
k.flag = flag;
k.size = real_size;
memcpy(k.key, key, len);
YAC_KEY_SET_LEN(k, len, size);
if (!WRITEP(p)) {
USER_FREE(s);
return 0;
}
*p = k;
READP(p);
USER_FREE(s);
return 1;
}
++YAC_SG(fails);
USER_FREE(s);
return 0;
}
} else {
uint32_t i;
uint64_t seed, max_atime;
seed = yac_inline_hash_func2(key, len);
for (i = 0; i < 3; i++) {
h += seed & YAC_SG(slots_mask);
paths[idx++] = p = &(YAC_SG(slots)[h & YAC_SG(slots_mask)]);
if (!WRITEP(p)) {
return 0;
}
k = *p;
READP(p);
if (k.val == NULL) {
goto do_add;
} else if (k.h == hash && YAC_KEY_KLEN(k) == len && !memcmp((char *)k.key, key, len)) {
/* Found the exact match */
goto do_update;
}
}
--idx;
max_atime = paths[idx]->val->atime;
for (i = 0; i < idx; i++) {
if ((paths[i]->ttl && paths[i]->ttl <= tv) || paths[i]->len != paths[i]->val->len) {
p = paths[i];
goto do_add;
} else if (paths[i]->val->atime < max_atime) {
max_atime = paths[i]->val->atime;
p = paths[i];
}
}
if (!WRITEP(p)) {
return 0;
}
k = *p;
READP(p);
++YAC_SG(kicks);
k.h = hash;
goto do_update;
}
} else {
do_add:
real_size = yac_allocator_real_size(sizeof(yac_kv_val) + (size * YAC_STORAGE_FACTOR) - 1);
if (!real_size) {
++YAC_SG(fails);
return 0;
}
s = USER_ALLOC(sizeof(yac_kv_val) + size - 1);
memcpy(s->data, data, size);
s->atime = tv;
YAC_KEY_SET_LEN(*s, len, size);
val = yac_allocator_raw_alloc(real_size, (int)hash);
if (val) {
memcpy((char *)val, (char *)s, sizeof(yac_kv_val) + size - 1);
if (p->val == NULL) {
++YAC_SG(slots_num);
}
k.h = hash;
k.val = val;
k.flag = flag;
k.size = real_size;
k.crc = yac_crc32(s->data, size);
memcpy(k.key, key, len);
YAC_KEY_SET_LEN(k, len, size);
if (ttl) {
k.ttl = tv + ttl;
} else {
k.ttl = 0;
}
if (!WRITEP(p)) {
USER_FREE(s);
return 0;
}
*p = k;
READP(p);
USER_FREE(s);
return 1;
}
++YAC_SG(fails);
USER_FREE(s);
}
return 0;
}
/* }}} */
void yac_storage_flush(void) /* {{{ */ {
YAC_SG(slots_num) = 0;
memset((char *)YAC_SG(slots), 0, sizeof(yac_kv_key) * YAC_SG(slots_size));
}
/* }}} */
yac_storage_info * yac_storage_get_info(void) /* {{{ */ {
yac_storage_info *info = USER_ALLOC(sizeof(yac_storage_info));
info->k_msize = (unsigned long)YAC_SG(first_seg).size;
info->v_msize = (unsigned long)YAC_SG(segments)[0]->size * (unsigned long)YAC_SG(segments_num);
info->segment_size = YAC_SG(segments)[0]->size;
info->segments_num = YAC_SG(segments_num);
info->hits = YAC_SG(hits);
info->miss = YAC_SG(miss);
info->fails = YAC_SG(fails);
info->kicks = YAC_SG(kicks);
info->recycles = YAC_SG(recycles);
info->slots_size = YAC_SG(slots_size);
info->slots_num = YAC_SG(slots_num);
return info;
}
/* }}} */
void yac_storage_free_info(yac_storage_info *info) /* {{{ */ {
USER_FREE(info);
}
/* }}} */
yac_item_list * yac_storage_dump(unsigned int limit) /* {{{ */ {
yac_kv_key k;
yac_item_list *item, *list = NULL;
if (YAC_SG(slots_num)) {
unsigned int i = 0, n = 0;
for (; iindex = i;
item->h = k.h;
item->crc = k.crc;
item->ttl = k.ttl;
item->k_len = YAC_KEY_KLEN(k);
item->v_len = YAC_KEY_VLEN(k);
item->flag = k.flag;
item->size = k.size;
memcpy(item->key, k.key, YAC_STORAGE_MAX_KEY_LEN);
item->next = list;
list = item;
++n;
}
}
}
return list;
}
/* }}} */
void yac_storage_free_list(yac_item_list *list) /* {{{ */ {
yac_item_list *l;
while (list) {
l = list;
list = list->next;
USER_FREE(l);
}
}
/* }}} */
const char * yac_storage_shared_memory_name(void) /* {{{ */ {
return YAC_SHARED_MEMORY_HANDLER_NAME;
}
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/storage/yac_atomic.h 0000664 0001750 0001750 00000004635 14157324055 017324 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
| John Neo |
+----------------------------------------------------------------------+
*/
#ifndef YAC_ATOMIC_H
#define YAC_ATOMIC_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if HAVE_BUILTIN_ATOMIC
#define YAC_CAS(lock, old, set) __sync_bool_compare_and_swap(lock, old, set)
#elif ( __amd64__ || __amd64 || __x86_64__ || __i386__ || __i386 )
static inline int __yac_cas(unsigned int *lock, unsigned int old, unsigned int set) {
unsigned char res;
__asm__ volatile ( "lock;" "cmpxchgl %3, %1;" "sete %0;" :
"=a" (res) : "m" (*lock), "a" (old), "r" (set) : "memory");
return res;
}
#define YAC_CAS(lock, old, set) __yac_cas(lock, old, set)
#elif ZEND_WIN32
#define YAC_CAS(lock, old, set) (InterlockedCompareExchange(lock, set, old) == old)
#else
#undef YAC_CAS
#warning No atomic CAS supports
#endif
#ifdef YAC_CAS
#define MUT_READ 0x0
#define MUT_WRITE 0x1
#define CAS_MAX_SPIN 100
static inline int yac_mutex_write(unsigned int *me) {
int retry = 0;
while (!YAC_CAS(me, MUT_READ, MUT_WRITE)) {
if (++retry == CAS_MAX_SPIN) {
return 0;
}
}
return 1;
}
static inline void yac_mutex_read(unsigned int *me) {
*me = MUT_READ;
}
#define WRITEP(P) yac_mutex_write(&(P->mutex))
#define READP(P) yac_mutex_read(&(P->mutex))
#else
#undef YAC_CAS
#define WRITEP(P) (1)
#define READP(P)
#endif
#endif
yac-2.3.1/compressor/fastlz/LICENSE 0000664 0001750 0001750 00000002312 14157324055 020071 0 ustar huixinchen huixinchen FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
yac-2.3.1/compressor/fastlz/README.TXT 0000664 0001750 0001750 00000003507 14157324055 020431 0 ustar huixinchen huixinchen FastLZ - lightning-fast lossless compression library
Author: Ariya Hidayat
Official website: http://fastlz.org
FastLZ is distributed using the MIT license, see file LICENSE
for details.
FastLZ consists of two files: fastlz.h and fastlz.c. Just add these
files to your project in order to use FastLZ. For information on
compression and decompression routines, see fastlz.h.
A simple file compressor called 6pack is included as an example
on how to use FastLZ. The corresponding decompressor is 6unpack.
To compile using GCC:
gcc -o 6pack 6pack.c fastlz.c
gcc -o 6unpack 6unpack.c fastlz.c
To compile using MinGW:
mingw32-gcc -o 6pack 6pack.c fastlz.c
mingw32-gcc -o 6unpack 6unpack.c fastlz.c
To compile using Microsoft Visual C++:
cl 6pack.c fastlz.c
cl 6unpack.c fastlz.c
To compile using Borland C++:
bcc32 6pack.c fastlz.c
bcc32 6unpack.c fastlz.c
To compile using OpenWatcom C/C++:
cl386 6pack.c fastlz.c
cl386 6unpack.c fastlz.c
To compile using Intel C++ compiler for Windows:
icl 6pack.c fastlz.c
icl 6unpack.c fastlz.c
To compile using Intel C++ compiler for Linux:
icc -o 6pack 6pack.c fastlz.c
icc -o 6unpack 6unpack.c fastlz.c
To compile 6pack using LCC-Win32:
lc 6pack.c fastlz.c
lc 6unpack.c fastlz.c
To compile 6pack using Pelles C:
pocc 6pack.c
pocc 6unpack.c
pocc fastlz.c
polink 6pack.obj fastlz.obj
polink 6unpack.obj fastlz.obj
For speed optimization, always use proper compile flags for optimization options.
Typical compiler flags are given below:
* GCC (pre 4.2): -march=pentium -O3 -fomit-frame-pointer -mtune=pentium
* GCC 4.2 or later: -march=pentium -O3 -fomit-frame-pointer -mtune=generic
* Digital Mars C/C++: -o+all -5
* Intel C++ (Windows): /O3 /Qipo
* Intel C++ (Linux): -O2 -march=pentium -mtune=pentium
* Borland C++: -O2 -5
* LCC-Win32: -O
* Pelles C: /O2
yac-2.3.1/compressor/fastlz/fastlz.h 0000664 0001750 0001750 00000006756 14157324055 020560 0 ustar huixinchen huixinchen /*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef FASTLZ_H
#define FASTLZ_H
#define FASTLZ_VERSION 0x000100
#define FASTLZ_VERSION_MAJOR 0
#define FASTLZ_VERSION_MINOR 0
#define FASTLZ_VERSION_REVISION 0
#define FASTLZ_VERSION_STRING "0.1.0"
#if defined (__cplusplus)
extern "C" {
#endif
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
*/
int fastlz_compress(const void* input, int length, void* output);
/**
Decompress a block of compressed data and returns the size of the
decompressed block. If error occurs, e.g. the compressed data is
corrupted or the output buffer is not large enough, then 0 (zero)
will be returned instead.
The input buffer and the output buffer can not overlap.
Decompression is memory safe and guaranteed not to write the output buffer
more than what is specified in maxout.
*/
int fastlz_decompress(const void* input, int length, void* output, int maxout);
/**
Compress a block of data in the input buffer and returns the size of
compressed block. The size of input buffer is specified by length. The
minimum input buffer size is 16.
The output buffer must be at least 5% larger than the input buffer
and can not be smaller than 66 bytes.
If the input is not compressible, the return value might be larger than
length (input buffer size).
The input buffer and the output buffer can not overlap.
Compression level can be specified in parameter level. At the moment,
only level 1 and level 2 are supported.
Level 1 is the fastest compression and generally useful for short data.
Level 2 is slightly slower but it gives better compression ratio.
Note that the compressed data, regardless of the level, can always be
decompressed using the function fastlz_decompress above.
*/
int fastlz_compress_level(int level, const void* input, int length, void* output);
#if defined (__cplusplus)
}
#endif
#endif /* FASTLZ_H */
yac-2.3.1/compressor/fastlz/fastlz.c 0000664 0001750 0001750 00000032520 14157324055 020537 0 ustar huixinchen huixinchen /*
FastLZ - lightning-fast lossless compression library
Copyright (C) 2007 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2006 Ariya Hidayat (ariya@kde.org)
Copyright (C) 2005 Ariya Hidayat (ariya@kde.org)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
/*
* Always check for bound when decompressing.
* Generally it is best to leave it defined.
*/
#define FASTLZ_SAFE
/*
* Give hints to the compiler for branch prediction optimization.
*/
#if defined(__GNUC__) && (__GNUC__ > 2)
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
#else
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
#endif
/*
* Use inlined functions for supported systems.
*/
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
#define FASTLZ_INLINE inline
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
#define FASTLZ_INLINE __inline
#else
#define FASTLZ_INLINE
#endif
/*
* Prevent accessing more than 8-bit at once, except on x86 architectures.
*/
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_STRICT_ALIGN
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) /* GNU C */
#undef FASTLZ_STRICT_ALIGN
#elif defined(_M_IX86) /* Intel, MSVC */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__386)
#undef FASTLZ_STRICT_ALIGN
#elif defined(_X86_) /* MinGW */
#undef FASTLZ_STRICT_ALIGN
#elif defined(__I86__) /* Digital Mars */
#undef FASTLZ_STRICT_ALIGN
#endif
#endif
/*
* FIXME: use preprocessor magic to set this on different platforms!
*/
typedef unsigned char flzuint8;
typedef unsigned short flzuint16;
typedef unsigned int flzuint32;
/* prototypes */
int fastlz_compress(const void* input, int length, void* output);
int fastlz_compress_level(int level, const void* input, int length, void* output);
int fastlz_decompress(const void* input, int length, void* output, int maxout);
#define MAX_COPY 32
#define MAX_LEN 264 /* 256 + 8 */
#define MAX_DISTANCE 8192
#if !defined(FASTLZ_STRICT_ALIGN)
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
#else
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
#endif
#define HASH_LOG 13
#define HASH_SIZE (1<< HASH_LOG)
#define HASH_MASK (HASH_SIZE-1)
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 1
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz1_compress
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
#include "fastlz.c"
#undef FASTLZ_LEVEL
#define FASTLZ_LEVEL 2
#undef MAX_DISTANCE
#define MAX_DISTANCE 8191
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
#undef FASTLZ_COMPRESSOR
#undef FASTLZ_DECOMPRESSOR
#define FASTLZ_COMPRESSOR fastlz2_compress
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
#include "fastlz.c"
int fastlz_compress(const void* input, int length, void* output)
{
/* for short block, choose fastlz1 */
if(length < 65536)
return fastlz1_compress(input, length, output);
/* else... */
return fastlz2_compress(input, length, output);
}
int fastlz_decompress(const void* input, int length, void* output, int maxout)
{
/* magic identifier for compression level */
int level = ((*(const flzuint8*)input) >> 5) + 1;
if(level == 1)
return fastlz1_decompress(input, length, output, maxout);
if(level == 2)
return fastlz2_decompress(input, length, output, maxout);
/* unknown level, trigger error */
return 0;
}
int fastlz_compress_level(int level, const void* input, int length, void* output)
{
if(level == 1)
return fastlz1_compress(input, length, output);
if(level == 2)
return fastlz2_compress(input, length, output);
return 0;
}
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
{
const flzuint8* ip = (const flzuint8*) input;
const flzuint8* ip_bound = ip + length - 2;
const flzuint8* ip_limit = ip + length - 12;
flzuint8* op = (flzuint8*) output;
const flzuint8* htab[HASH_SIZE];
const flzuint8** hslot;
flzuint32 hval;
flzuint32 copy;
/* sanity check */
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
{
if(length)
{
/* create literal copy only */
*op++ = length-1;
ip_bound++;
while(ip <= ip_bound)
*op++ = *ip++;
return length+1;
}
else
return 0;
}
/* initializes hash table */
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
*hslot = ip;
/* we start with literal copy */
copy = 2;
*op++ = MAX_COPY-1;
*op++ = *ip++;
*op++ = *ip++;
/* main loop */
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
{
const flzuint8* ref;
flzuint32 distance;
/* minimum match length */
flzuint32 len = 3;
/* comparison starting-point */
const flzuint8* anchor = ip;
/* check for a run */
#if FASTLZ_LEVEL==2
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
{
distance = 1;
ip += 3;
ref = anchor - 1 + 3;
goto match;
}
#endif
/* find potential match */
HASH_FUNCTION(hval,ip);
hslot = htab + hval;
ref = htab[hval];
/* calculate distance to the match */
distance = anchor - ref;
/* update hash table */
*hslot = anchor;
/* is this a match? check the first 3 bytes */
if(distance==0 ||
#if FASTLZ_LEVEL==1
(distance >= MAX_DISTANCE) ||
#else
(distance >= MAX_FARDISTANCE) ||
#endif
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
goto literal;
#if FASTLZ_LEVEL==2
/* far, needs at least 5-byte match */
if(distance >= MAX_DISTANCE)
{
if(*ip++ != *ref++ || *ip++!= *ref++)
goto literal;
len += 2;
}
match:
#endif
/* last matched byte */
ip = anchor + len;
/* distance is biased */
distance--;
if(!distance)
{
/* zero distance means a run */
flzuint8 x = ip[-1];
while(ip < ip_bound)
if(*ref++ != x) break; else ip++;
}
else
for(;;)
{
/* safe because the outer check against ip limit */
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
if(*ref++ != *ip++) break;
while(ip < ip_bound)
if(*ref++ != *ip++) break;
break;
}
/* if we have copied something, adjust the copy count */
if(copy)
/* copy is biased, '0' means 1 byte copy */
*(op-copy-1) = copy-1;
else
/* back, to overwrite the copy count */
op--;
/* reset literal counter */
copy = 0;
/* length is biased, '1' means a match of 3 bytes */
ip -= 3;
len = ip - anchor;
/* encode the match */
#if FASTLZ_LEVEL==2
if(distance < MAX_DISTANCE)
{
if(len < 7)
{
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
}
else
{
*op++ = (7 << 5) + (distance >> 8);
for(len-=7; len >= 255; len-= 255)
*op++ = 255;
*op++ = len;
*op++ = (distance & 255);
}
}
else
{
/* far away, but not yet in the another galaxy... */
if(len < 7)
{
distance -= MAX_DISTANCE;
*op++ = (len << 5) + 31;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
else
{
distance -= MAX_DISTANCE;
*op++ = (7 << 5) + 31;
for(len-=7; len >= 255; len-= 255)
*op++ = 255;
*op++ = len;
*op++ = 255;
*op++ = distance >> 8;
*op++ = distance & 255;
}
}
#else
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
while(len > MAX_LEN-2)
{
*op++ = (7 << 5) + (distance >> 8);
*op++ = MAX_LEN - 2 - 7 -2;
*op++ = (distance & 255);
len -= MAX_LEN-2;
}
if(len < 7)
{
*op++ = (len << 5) + (distance >> 8);
*op++ = (distance & 255);
}
else
{
*op++ = (7 << 5) + (distance >> 8);
*op++ = len - 7;
*op++ = (distance & 255);
}
#endif
/* update the hash at match boundary */
HASH_FUNCTION(hval,ip);
htab[hval] = ip++;
HASH_FUNCTION(hval,ip);
htab[hval] = ip++;
/* assuming literal copy */
*op++ = MAX_COPY-1;
continue;
literal:
*op++ = *anchor++;
ip = anchor;
copy++;
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
{
copy = 0;
*op++ = MAX_COPY-1;
}
}
/* left-over as literal copy */
ip_bound++;
while(ip <= ip_bound)
{
*op++ = *ip++;
copy++;
if(copy == MAX_COPY)
{
copy = 0;
*op++ = MAX_COPY-1;
}
}
/* if we have copied something, adjust the copy length */
if(copy)
*(op-copy-1) = copy-1;
else
op--;
#if FASTLZ_LEVEL==2
/* marker for fastlz2 */
*(flzuint8*)output |= (1 << 5);
#endif
return op - (flzuint8*)output;
}
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
{
const flzuint8* ip = (const flzuint8*) input;
const flzuint8* ip_limit = ip + length;
flzuint8* op = (flzuint8*) output;
flzuint8* op_limit = op + maxout;
flzuint32 ctrl = (*ip++) & 31;
int loop = 1;
do
{
const flzuint8* ref = op;
flzuint32 len = ctrl >> 5;
flzuint32 ofs = (ctrl & 31) << 8;
if(ctrl >= 32)
{
#if FASTLZ_LEVEL==2
flzuint8 code;
#endif
len--;
ref -= ofs;
if (len == 7-1)
#if FASTLZ_LEVEL==1
len += *ip++;
ref -= *ip++;
#else
do
{
code = *ip++;
len += code;
} while (code==255);
code = *ip++;
ref -= code;
/* match from 16-bit distance */
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
{
ofs = (*ip++) << 8;
ofs += *ip++;
ref = op - ofs - MAX_DISTANCE;
}
#endif
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
return 0;
#endif
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
ctrl = *ip++;
else
loop = 0;
if(ref == op)
{
/* optimize copy for a run */
flzuint8 b = ref[-1];
*op++ = b;
*op++ = b;
*op++ = b;
for(; len; --len)
*op++ = b;
}
else
{
#if !defined(FASTLZ_STRICT_ALIGN)
const flzuint16* p;
flzuint16* q;
#endif
/* copy from reference */
ref--;
*op++ = *ref++;
*op++ = *ref++;
*op++ = *ref++;
#if !defined(FASTLZ_STRICT_ALIGN)
/* copy a byte, so that now it's word aligned */
if(len & 1)
{
*op++ = *ref++;
len--;
}
/* copy 16-bit at once */
q = (flzuint16*) op;
op += len;
p = (const flzuint16*) ref;
for(len>>=1; len > 4; len-=4)
{
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
*q++ = *p++;
}
for(; len; --len)
*q++ = *p++;
#else
for(; len; --len)
*op++ = *ref++;
#endif
}
}
else
{
ctrl++;
#ifdef FASTLZ_SAFE
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
return 0;
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
return 0;
#endif
*op++ = *ip++;
for(--ctrl; ctrl; ctrl--)
*op++ = *ip++;
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
if(loop)
ctrl = *ip++;
}
}
while(FASTLZ_EXPECT_CONDITIONAL(loop));
return op - (flzuint8*)output;
}
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
yac-2.3.1/serializer/yac_serializer.h 0000664 0001750 0001750 00000004260 14157324055 020720 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef YAC_SERIALIZER_H
#define YAC_SERIALIZER_H
typedef int (*yac_serializer_t)(zval*, smart_str*, char**);
typedef zval* (*yac_unserializer_t)(char *, size_t, char**, zval*);
#ifdef YAC_ENABLE_MSGPACK
int yac_serializer_msgpack_pack(zval *pzval, smart_str *buf, char **msg);
zval * yac_serializer_msgpack_unpack(char *content, size_t len, char **msg, zval *rv);
#endif
int yac_serializer_php_pack(zval *pzval, smart_str *buf, char **msg);
zval * yac_serializer_php_unpack(char *content, size_t len, char **msg, zval *rv);
#ifdef YAC_ENABLE_IGBINARY
int yac_serializer_igbinary_pack(zval *pzval, smart_str *buf, char **msg);
zval * yac_serializer_igbinary_unpack(char *content, size_t len, char **msg, zval *rv);
#endif
#ifdef YAC_ENABLE_JSON
int yac_serializer_json_pack(zval *pzval, smart_str *buf, char **msg);
zval * yac_serializer_json_unpack(char *content, size_t len, char **msg, zval *rv);
#endif
#endif /* YAC_SERIALIZER_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/serializer/php.c 0000664 0001750 0001750 00000004327 14157324055 016501 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "php.h"
#include "ext/standard/php_var.h" /* for serialize */
#include "zend_smart_str.h"
#include "yac_serializer.h"
int yac_serializer_php_pack(zval *pzval, smart_str *buf, char **msg) /* {{{ */ {
php_serialize_data_t var_hash;
PHP_VAR_SERIALIZE_INIT(var_hash);
php_var_serialize(buf, pzval, &var_hash);
PHP_VAR_SERIALIZE_DESTROY(var_hash);
return 1;
} /* }}} */
zval * yac_serializer_php_unpack(char *content, size_t len, char **msg, zval *rv) /* {{{ */ {
const unsigned char *p;
php_unserialize_data_t var_hash;
p = (const unsigned char*)content;
ZVAL_FALSE(rv);
PHP_VAR_UNSERIALIZE_INIT(var_hash);
if (!php_var_unserialize(rv, &p, p + len, &var_hash)) {
zval_ptr_dtor(rv);
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
/* spprintf(msg, 0, "unpack error at offset %ld of %ld bytes", (long)((char*)p - content), len); */
return NULL;
}
PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
return rv;
} /* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/serializer/msgpack.c 0000664 0001750 0001750 00000003553 14157324055 017337 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yar - Light, concurrent RPC framework |
+----------------------------------------------------------------------+
| Copyright (c) 2012-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
| Zhenyu Zhang |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef YAC_ENABLE_MSGPACK
#include "php.h"
#include "ext/msgpack/php_msgpack.h"
#include "zend_smart_str.h" /* for smart_str */
#include "yac_serializer.h"
int yac_serializer_msgpack_pack(zval *pzval, smart_str *buf, char **msg) /* {{{ */ {
php_msgpack_serialize(buf, pzval);
return 1;
} /* }}} */
zval * yac_serializer_msgpack_unpack(char *content, size_t len, char **msg, zval *rv) /* {{{ */ {
ZVAL_NULL(rv);
php_msgpack_unserialize(rv, content, len);
return rv;
} /* }}} */
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/serializer/json.c 0000664 0001750 0001750 00000003577 14157324055 016671 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if YAC_ENABLE_JSON
#include "php.h"
#include "ext/json/php_json.h"
#include "zend_smart_str.h" /* for smart_str */
#include "yac_serializer.h"
int yac_serializer_json_pack(zval *pzval, smart_str *buf, char **msg) /* {{{ */ {
#if ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 3))
php_json_encode(buf, pzval);
#else
php_json_encode(buf, pzval, 0); /* options */
#endif
return 1;
} /* }}} */
zval* yac_serializer_json_unpack(char *content, size_t len, char **msg, zval *rv) /* {{{ */ {
ZVAL_NULL(rv);
php_json_decode(rv, content, len, 1, 512);
return rv;
} /* }}} */
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/serializer/igbinary.c 0000664 0001750 0001750 00000003760 14157324055 017516 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
| Remi Collet |
+----------------------------------------------------------------------+
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef YAC_ENABLE_IGBINARY
#include "php.h"
#include "ext/igbinary/igbinary.h"
#include "zend_smart_str.h" /* for smart_str */
#include "yac_serializer.h"
int yac_serializer_igbinary_pack(zval *pzval, smart_str *buf, char **msg) /* {{{ */ {
uint8_t *ret;
size_t ret_len;
if (igbinary_serialize(&ret, &ret_len, pzval) == 0) {
smart_str_appendl(buf, (const char *)ret, ret_len);
efree(ret);
return 1;
}
return 0;
} /* }}} */
zval * yac_serializer_igbinary_unpack(char *content, size_t len, char **msg, zval *rv) /* {{{ */ {
ZVAL_NULL(rv);
igbinary_unserialize((uint8_t *)content, len, rv);
return rv;
} /* }}} */
#endif
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/tests/001.phpt 0000664 0001750 0001750 00000001021 14157324055 015720 0 ustar huixinchen huixinchen --TEST--
Check for yac presence
--SKIPIF--
--FILE--
--EXPECT--
yac extension is available
yac-2.3.1/tests/002.phpt 0000664 0001750 0001750 00000003104 14157324055 015725 0 ustar huixinchen huixinchen --TEST--
Check for yac basic functions
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.serializer=php
--FILE--
set($key, $value));
var_dump($yac->get($key));
$value = NULL;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = TRUE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = FALSE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324.123456;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = new StdClass();;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = fopen("php://input", "r");
var_dump($yac->set($key, $value));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->delete($key));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
bool(true)
string(5) "dummy"
bool(true)
NULL
bool(true)
bool(true)
bool(true)
bool(false)
bool(true)
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
bool(true)
int(9234324)
bool(true)
float(9234324.123456)
bool(true)
object(stdClass)#3 (0) {
}
Warning: Yac::set(): Type 'IS_RESOURCE' cannot be stored in %s002.php on line %d
bool(false)
bool(true)
bool(true)
bool(false)
yac-2.3.1/tests/003.phpt 0000664 0001750 0001750 00000002407 14157324055 015733 0 ustar huixinchen huixinchen --TEST--
Check for yac errors
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value));
var_dump($yac->get($key));
$key = str_repeat("k", YAC_MAX_KEY_LEN);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$key = str_repeat("k", YAC_MAX_KEY_LEN + 1);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$yac = new Yac("dummy");
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
NULL
bool(true)
NULL
Warning: Yac::set(): Key 'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' exceed max key length '48' bytes in %s003.php on line %d
bool(false)
Warning: Yac::get(): Key 'kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' exceed max key length '48' bytes in %s003.php on line %d
bool(false)
Warning: Yac::set(): Key 'dummykkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' exceed max key length '48' bytes in %s003.php on line %d
bool(false)
Warning: Yac::get(): Key 'dummykkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk' exceed max key length '48' bytes in %s003.php on line %d
bool(false)
yac-2.3.1/tests/004.phpt 0000664 0001750 0001750 00000001175 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for yac ttl
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value, 1));
var_dump($yac->get($key));
sleep(1);
var_dump($yac->get($key));
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
var_dump($yac->delete($key, 1));
var_dump($yac->get($key));
sleep(1);
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
string(5) "dummy"
bool(false)
bool(true)
string(5) "dummy"
bool(true)
string(5) "dummy"
bool(false)
yac-2.3.1/tests/005.phpt 0000664 0001750 0001750 00000001453 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for yac non-string key
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value, 1));
var_dump($yac->get($key));
$key = 12345.12345;
var_dump($yac->set($key, $value, 1));
var_dump($yac->get($key));
$key = range(1, 2);
var_dump($yac->set($key, $value, 1));
var_dump($yac->get($key));
$key = new StdClass();
var_dump($yac->set($key, $value, 1));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
string(5) "dummy"
bool(true)
string(5) "dummy"
bool(true)
array(2) {
[1]=>
int(2)
[2]=>
bool(false)
}
%s error:%sObject of class stdClass could not be converted to string in %s005.php%A
yac-2.3.1/tests/006.phpt 0000664 0001750 0001750 00000001123 14157324055 015730 0 ustar huixinchen huixinchen --TEST--
Check for yac multi set/get
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value)) {
var_dump($key, $value);
var_dump("write " . $i);
}
if ($value != ($new = $yac->get($key))) {
var_dump($new);
var_dump("read " . $i);
}
}
var_dump($i);
--EXPECTF--
int(1000)
yac-2.3.1/tests/007.phpt 0000664 0001750 0001750 00000001375 14157324055 015742 0 ustar huixinchen huixinchen --TEST--
Check for yac info
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value)) {
var_dump($key, $value);
var_dump("write " . $i);
}
if ($value != ($new = $yac->get($key))) {
var_dump($new);
var_dump("read " . $i);
}
}
$info = $yac->info();
var_dump($info['slots_used'] <= 1000);
var_dump($info['hits']);
var_dump($info['miss']);
var_dump($info['fails']);
var_dump($info['kicks']);
--EXPECTF--
bool(true)
int(1000)
int(0)
int(0)
int(0)
yac-2.3.1/tests/008.phpt 0000664 0001750 0001750 00000001333 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for yac prefix
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($key, $value);
var_dump($yac->get($key)); //true
var_dump($yac2->get($key)); //false
var_dump($yac2->get("dummy_" . $key)); //true
$yac2->delete($key); //fail
var_dump($yac->get($key)); //true
$yac->delete($key); //okey
var_dump($yac->get($key)); //false
$yac->set($key, $value);
$yac2->delete("dummy_" . $key); //okey
var_dump($yac->get($key)); //false
?>
--EXPECTF--
bool(true)
bool(false)
bool(true)
bool(true)
bool(false)
bool(false)
yac-2.3.1/tests/009.phpt 0000664 0001750 0001750 00000001430 14157324055 015734 0 ustar huixinchen huixinchen --TEST--
Check for yac multi ops
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($values));
$keys = array_keys($values);
$ret = $yac->get($keys);
var_dump(count(array_filter($ret)) == $numbers);
$disable = array_slice($keys, 0, -10);
$yac->delete($disable);
$ret = $yac->get($keys);
var_dump(count(array_filter($ret)) == 10);
?>
--EXPECTF--
bool(true)
bool(true)
bool(true)
yac-2.3.1/tests/010.phpt 0000664 0001750 0001750 00000001206 14157324055 015725 0 ustar huixinchen huixinchen --TEST--
Check for yac::flush
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set($values));
$yac->flush();
var_dump($yac->get($key));
$info = $yac->info();
var_dump($info['slots_used']);
?>
--EXPECTF--
bool(true)
bool(false)
int(0)
yac-2.3.1/tests/011.phpt 0000664 0001750 0001750 00000001430 14157324055 015725 0 ustar huixinchen huixinchen --TEST--
Check for yac::add
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
add($key, $value)); // true
var_dump($yac->add($key, $value)); // false
var_dump($yac->set($key, $value)); // true
var_dump($yac->get($key)); // foo
var_dump($yac->delete($key)); // true
$value = "bar";
var_dump($yac->add($key, $value, 1)); //true
var_dump($yac->add($key, $value, 1)); //false
var_dump($yac->get($key)); //bar
sleep(1);
var_dump($yac->add($key, $value)); //true
?>
--EXPECTF--
bool(true)
bool(false)
bool(true)
string(3) "foo"
bool(true)
bool(true)
bool(false)
string(3) "bar"
bool(true)
yac-2.3.1/tests/012.phpt 0000664 0001750 0001750 00000001266 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for functional apis
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
--EXPECTF--
bool(true)
bool(false)
string(3) "foo"
bool(true)
bool(true)
bool(true)
int(0)
yac-2.3.1/tests/013.phpt 0000664 0001750 0001750 00000000465 14157324055 015736 0 ustar huixinchen huixinchen --TEST--
Check for ttl bug
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
set('test', 1, 1);
sleep(2);
var_dump($yac->get('test'));
?>
--EXPECTF--
bool(false)
yac-2.3.1/tests/014.phpt 0000664 0001750 0001750 00000000647 14157324055 015741 0 ustar huixinchen huixinchen --TEST--
Check for ttl bug
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.compress_threshold=1024
--FILE--
set('test', $value);
echo count($yac->get('test'));
?>
--EXPECTF--
100
yac-2.3.1/tests/015.phpt 0000664 0001750 0001750 00000000677 14157324055 015745 0 ustar huixinchen huixinchen --TEST--
Check for Yac::dump
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.compress_threshold=1024
--FILE--
set("key". $i, "kjslkdfkldasjkf");
}
for ($i = 0; $i<100; $i++) {
$yac->set("key". $i, "kjslkdfkldasjkf");
}
var_dump(count($yac->dump(1000)));
--EXPECTF--
int(100)
yac-2.3.1/tests/016.phpt 0000664 0001750 0001750 00000000576 14157324055 015744 0 ustar huixinchen huixinchen --TEST--
Check for Yac setter/getter
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.compress_threshold=1024
--FILE--
name = "test";
var_dump($yac->name);
var_dump($yac->get("name"));
?>
--EXPECTF--
string(4) "test"
string(4) "test"
yac-2.3.1/tests/017.phpt 0000664 0001750 0001750 00000001524 14157324055 015737 0 ustar huixinchen huixinchen --TEST--
Check for mutiple process
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.compress_threshold=1024
--FILE--
set("parent", "FIN"));
while (!($msg = $yac->get("child")));
echo "MSG From Child:", $msg,"\n";
while(!($yac->set("parent", "BYE")));
pcntl_wait($status);
echo "Parent exiting\n";
} else {
while(!($msg = $yac->get("parent")));
echo "MSG From Parent:" , $msg, "\n";
while(!($yac->set("child", "ACK")));
while(($msg = $yac->get("parent")) != "BYE");
echo "Child exiting\n";
}
?>
--EXPECT--
MSG From Parent:FIN
MSG From Child:ACK
Child exiting
Parent exiting
yac-2.3.1/tests/018.phpt 0000664 0001750 0001750 00000003213 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for yac with json serializer
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.serializer=json
--FILE--
set($key, $value));
var_dump($yac->get($key));
$value = NULL;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = TRUE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = FALSE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324.123456;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = new StdClass();;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = fopen("php://input", "r");
var_dump($yac->set($key, $value));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->delete($key));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
bool(true)
string(5) "dummy"
bool(true)
NULL
bool(true)
bool(true)
bool(true)
bool(false)
bool(true)
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
bool(true)
int(9234324)
bool(true)
float(9234324.123456)
bool(true)
array(0) {
}
Warning: Yac::set(): Type 'IS_RESOURCE' cannot be stored in %s018.php on line %d
bool(false)
bool(true)
bool(true)
bool(false)
yac-2.3.1/tests/019.phpt 0000664 0001750 0001750 00000003251 14157324055 015740 0 ustar huixinchen huixinchen --TEST--
Check for yac with msgpack serializer
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.serializer=msgpack
--FILE--
set($key, $value));
var_dump($yac->get($key));
$value = NULL;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = TRUE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = FALSE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324.123456;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = new StdClass();;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = fopen("php://input", "r");
var_dump($yac->set($key, $value));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->delete($key));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
bool(true)
string(5) "dummy"
bool(true)
NULL
bool(true)
bool(true)
bool(true)
bool(false)
bool(true)
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
bool(true)
int(9234324)
bool(true)
float(9234324.123456)
bool(true)
object(stdClass)#%d (0) {
}
Warning: Yac::set(): Type 'IS_RESOURCE' cannot be stored in %s019.php on line %d
bool(false)
bool(true)
bool(true)
bool(false)
yac-2.3.1/tests/020.phpt 0000664 0001750 0001750 00000003256 14157324055 015735 0 ustar huixinchen huixinchen --TEST--
Check for yac with igbinary serializer
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
yac.serializer=igbinary
--FILE--
set($key, $value));
var_dump($yac->get($key));
$value = NULL;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = TRUE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = FALSE;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = 9234324.123456;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = new StdClass();;
var_dump($yac->set($key, $value));
var_dump($yac->get($key));
$value = fopen("php://input", "r");
var_dump($yac->set($key, $value));
$value = range(1, 5);
var_dump($yac->set($key, $value));
var_dump($yac->delete($key));
var_dump($yac->get($key));
?>
--EXPECTF--
bool(true)
bool(true)
string(5) "dummy"
bool(true)
NULL
bool(true)
bool(true)
bool(true)
bool(false)
bool(true)
array(5) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
[3]=>
int(4)
[4]=>
int(5)
}
bool(true)
int(9234324)
bool(true)
float(9234324.123456)
bool(true)
object(stdClass)#%d (0) {
}
Warning: Yac::set(): Type 'IS_RESOURCE' cannot be stored in %s020.php on line %d
bool(false)
bool(true)
bool(true)
bool(false)
yac-2.3.1/tests/021.phpt 0000664 0001750 0001750 00000001161 14157324055 015727 0 ustar huixinchen huixinchen --TEST--
Check for yac read/write/unset property
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=4M
yac.values_memory_size=32M
--FILE--
value = "value";
/* can not used in writen context */
try {
$yac->foo->bar = "bar";
} catch (Exception $e) {};
var_dump($yac->get("value"));
var_dump($yac->value);
var_dump($yac->get("foo"));
var_dump($yac->foo);
unset($yac->value);
var_dump($yac->get("value"));
var_dump($yac->value);
?>
--EXPECT--
string(5) "value"
string(5) "value"
bool(false)
NULL
bool(false)
NULL
yac-2.3.1/tests/022.phpt 0000664 0001750 0001750 00000000472 14157324055 015734 0 ustar huixinchen huixinchen --TEST--
Check for yac::__construct with yac.enable=0
--SKIPIF--
--INI--
yac.enable=0
--FILE--
getMessage());
}
@var_dump($yac);
?>
--EXPECTF--
string(18) "Yac is not enabled"
NULL
yac-2.3.1/tests/023.phpt 0000664 0001750 0001750 00000000331 14157324055 015727 0 ustar huixinchen huixinchen --TEST--
Check for inherit from Yac
--SKIPIF--
--INI--
yac.enable=0
--FILE--
--EXPECTF--
Fatal error: Class Sub %s final class %s
yac-2.3.1/tests/issue012.phpt 0000664 0001750 0001750 00000000570 14157324055 017003 0 ustar huixinchen huixinchen --TEST--
ISSUE #12 segfault if use mmap&k_size bigger than 4M
--SKIPIF--
--INI--
yac.enable=1
yac.enable_cli=1
yac.keys_memory_size=8M
yac.values_memory_size=128M
--FILE--
set(rand(), strval(rand()), 2);
$i++;
if ($i > 20000) {
break;
}
}
?>
OKEY
--EXPECTF--
OKEY
yac-2.3.1/config.w32 0000664 0001750 0001750 00000002335 14157324055 015174 0 ustar huixinchen huixinchen // $Id$
// vim:ft=javascript
ARG_ENABLE("yac", "enable yac support", "no");
if (PHP_YAC != "no") {
if( CHECK_HEADER_ADD_INCLUDE("fastlz.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\compressor\\fastlz") &&
CHECK_HEADER_ADD_INCLUDE("yac_serializer.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\serializer") &&
CHECK_HEADER_ADD_INCLUDE("yac_storage.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\storage") &&
CHECK_HEADER_ADD_INCLUDE("yac_allocator.h", "CFLAGS_YAC", PHP_YAC + ";" + configure_module_dirname + "\\storage\\allocator")) {
EXTENSION("yac", "yac.c");
ADD_SOURCES(configure_module_dirname + "\\compressor\\fastlz", "fastlz.c", "yac");
ADD_SOURCES(configure_module_dirname + "\\serializer", "php.c", "yac");
ADD_SOURCES(configure_module_dirname + "\\storage", "yac_storage.c", "yac");
ADD_SOURCES(configure_module_dirname + "\\storage\\allocator", "yac_allocator.c", "yac");
ADD_SOURCES(configure_module_dirname + "\\storage\\allocator\\allocators", "createfilemapping.c", "yac");
AC_DEFINE('HAVE_YAC', 1, 'Have yac library');
ADD_FLAG("CFLAGS_YAC", ' /I "' + configure_module_dirname + '" ');
} else {
WARNING("yac not enabled, headers not found");
}
}
yac-2.3.1/LICENSE 0000664 0001750 0001750 00000006222 14157324055 014376 0 ustar huixinchen huixinchen --------------------------------------------------------------------
The PHP License, version 3.01
Copyright (c) 1999 - 2011 The PHP Group. All rights reserved.
--------------------------------------------------------------------
Redistribution and use in source and binary forms, with or without
modification, is permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
3. The name "PHP" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact group@php.net.
4. Products derived from this software may not be called "PHP", nor
may "PHP" appear in their name, without prior written permission
from group@php.net. You may indicate that your software works in
conjunction with PHP by saying "Foo for PHP" instead of calling
it "PHP Foo" or "phpfoo"
5. The PHP Group may publish revised and/or new versions of the
license from time to time. Each version will be given a
distinguishing version number.
Once covered code has been published under a particular version
of the license, you may always continue to use it under the terms
of that version. You may also choose to use such covered code
under the terms of any subsequent version of the license
published by the PHP Group. No one other than the PHP Group has
the right to modify the terms applicable to covered code created
under this License.
6. Redistributions of any form whatsoever must retain the following
acknowledgment:
"This product includes PHP software, freely available from
".
THIS SOFTWARE IS PROVIDED BY THE PHP DEVELOPMENT TEAM ``AS IS'' AND
ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE PHP
DEVELOPMENT TEAM OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------
This software consists of voluntary contributions made by many
individuals on behalf of the PHP Group.
The PHP Group can be contacted via Email at group@php.net.
For more information on the PHP Group and the PHP project,
please see .
PHP includes the Zend Engine, freely available at
.
yac-2.3.1/CREDITS 0000664 0001750 0001750 00000000031 14157324055 014401 0 ustar huixinchen huixinchen yac
Xinchen Hui
Wei Dai
yac-2.3.1/config.m4 0000664 0001750 0001750 00000015024 14157324055 015100 0 ustar huixinchen huixinchen dnl $Id$
dnl config.m4 for extension yac
PHP_ARG_ENABLE(yac, whether to enable yac support,
[ --enable-yac Enable yac support])
PHP_ARG_WITH(system-fastlz, whether to use system FastLZ library,
[ --with-system-fastlz Use system FastLZ library], no, no)
PHP_ARG_ENABLE(json, whether to use igbinary as serializer,
[ --enable-json Use igbinary as serializer], no, no)
PHP_ARG_ENABLE(msgpack, whether to use msgpack as serializer,
[ --enable-msgpack Use Messagepack as serializer], no, no)
PHP_ARG_ENABLE(igbinary, whether to use igbinary as serializer,
[ --enable-igbinary Use igbinary as serializer], no, no)
dnl copied from Zend Optimizer Plus
AC_MSG_CHECKING(for sysvipc shared memory support)
AC_TRY_RUN([
#include
#include
#include
#include
#include
#include
int main() {
pid_t pid;
int status;
int ipc_id;
char *shm;
struct shmid_ds shmbuf;
ipc_id = shmget(IPC_PRIVATE, 4096, (IPC_CREAT | SHM_R | SHM_W));
if (ipc_id == -1) {
return 1;
}
shm = shmat(ipc_id, NULL, 0);
if (shm == (void *)-1) {
shmctl(ipc_id, IPC_RMID, NULL);
return 2;
}
if (shmctl(ipc_id, IPC_STAT, &shmbuf) != 0) {
shmdt(shm);
shmctl(ipc_id, IPC_RMID, NULL);
return 3;
}
shmbuf.shm_perm.uid = getuid();
shmbuf.shm_perm.gid = getgid();
shmbuf.shm_perm.mode = 0600;
if (shmctl(ipc_id, IPC_SET, &shmbuf) != 0) {
shmdt(shm);
shmctl(ipc_id, IPC_RMID, NULL);
return 4;
}
shmctl(ipc_id, IPC_RMID, NULL);
strcpy(shm, "hello");
pid = fork();
if (pid < 0) {
return 5;
} else if (pid == 0) {
strcpy(shm, "bye");
return 6;
}
if (wait(&status) != pid) {
return 7;
}
if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
return 8;
}
if (strcmp(shm, "bye") != 0) {
return 9;
}
return 0;
}
],dnl
AC_DEFINE(HAVE_SHM_IPC, 1, [Define if you have SysV IPC SHM support])
msg=yes,msg=no,msg=no)
AC_MSG_RESULT([$msg])
AC_MSG_CHECKING(for mmap() using MAP_ANON shared memory support)
AC_TRY_RUN([
#include
#include
#include
#include
#include
#ifndef MAP_ANON
# ifdef MAP_ANONYMOUS
# define MAP_ANON MAP_ANONYMOUS
# endif
#endif
#ifndef MAP_FAILED
# define MAP_FAILED ((void*)-1)
#endif
int main() {
pid_t pid;
int status;
char *shm;
shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (shm == MAP_FAILED) {
return 1;
}
strcpy(shm, "hello");
pid = fork();
if (pid < 0) {
return 5;
} else if (pid == 0) {
strcpy(shm, "bye");
return 6;
}
if (wait(&status) != pid) {
return 7;
}
if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
return 8;
}
if (strcmp(shm, "bye") != 0) {
return 9;
}
return 0;
}
],dnl
AC_DEFINE(HAVE_SHM_MMAP_ANON, 1, [Define if you have mmap(MAP_ANON) SHM support])
msg=yes,msg=no,msg=no)
AC_MSG_RESULT([$msg])
AC_MSG_CHECKING(for mmap() using /dev/zero shared memory support)
AC_TRY_RUN([
#include
#include
#include
#include
#include
#include
#include
#ifndef MAP_FAILED
# define MAP_FAILED ((void*)-1)
#endif
int main() {
pid_t pid;
int status;
int fd;
char *shm;
fd = open("/dev/zero", O_RDWR, S_IRUSR | S_IWUSR);
if (fd == -1) {
return 1;
}
shm = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (shm == MAP_FAILED) {
return 2;
}
strcpy(shm, "hello");
pid = fork();
if (pid < 0) {
return 5;
} else if (pid == 0) {
strcpy(shm, "bye");
return 6;
}
if (wait(&status) != pid) {
return 7;
}
if (!WIFEXITED(status) || WEXITSTATUS(status) != 6) {
return 8;
}
if (strcmp(shm, "bye") != 0) {
return 9;
}
return 0;
}
],dnl
AC_DEFINE(HAVE_SHM_MMAP_ZERO, 1, [Define if you have mmap("/dev/zero") SHM support])
msg=yes,msg=no,msg=no)
AC_MSG_RESULT([$msg])
if test "$PHP_MSGPACK" != "no"; then
AC_DEFINE(YAC_ENABLE_MSGPACK, 1, [enable msgpack packager])
ifdef([PHP_ADD_EXTENSION_DEP],
[
PHP_ADD_EXTENSION_DEP(yac, msgpack, true)
])
fi
if test "$PHP_IGBINARY" != "no"; then
AC_DEFINE(YAC_ENABLE_IGBINARY, 1, [enable igbinary packager])
ifdef([PHP_ADD_EXTENSION_DEP],
[
PHP_ADD_EXTENSION_DEP(yac, igbinary, true)
])
fi
if test "$PHP_JSON" != "no"; then
AC_DEFINE(YAC_ENABLE_JSON, 1, [enable json packager])
ifdef([PHP_ADD_EXTENSION_DEP],
[
PHP_ADD_EXTENSION_DEP(yac, json, true)
])
fi
ifdef([PHP_CHECK_CPU_SUPPORTS],
[
if test -x "$PHP_CONFIG"; then
php_vernum=`$PHP_CONFIG --vernum`
if test $php_vernum -ge 70300; then
AC_CHECK_HEADERS([nmmintrin.h])
PHP_CHECK_CPU_SUPPORTS([sse4.2])
dnl Tricky way to remove unintentionally defines
if test -e "confdefs.h"; then
sed -i "/PHP_HAVE_/d" confdefs.h
fi
AC_MSG_CHECKING([for crc32 instruction supports])
if test $have_ext_instructions -eq 1; then
AC_DEFINE([HAVE_SSE_CRC32], 1, [define if you have sse4.2 crc32 instruction support])
CFLAGS="$CFLAGS -msse4.2"
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
fi
fi
fi
], [])
AC_DEFUN([YAC_BUILTIN_ATOMIC],
[
AC_MSG_CHECKING([for __sync_bool_compare_and_swap supports])
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[
int variable = 1;
return (__sync_bool_compare_and_swap(&variable, 1, 2)
&& __sync_add_and_fetch(&variable, 1)) ? 1 : 0;
]])], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_BUILTIN_ATOMIC, 1, [Define to 1 if gcc supports __sync_bool_compare_and_swap() a.o.])
], [
AC_MSG_RESULT([no])
])
])
YAC_BUILTIN_ATOMIC
YAC_FILES="yac.c storage/yac_storage.c storage/allocator/yac_allocator.c storage/allocator/allocators/shm.c storage/allocator/allocators/mmap.c serializer/php.c serializer/msgpack.c serializer/igbinary.c serializer/json.c"
if test "$PHP_SYSTEM_FASTLZ" != "no"; then
AC_CHECK_HEADERS([fastlz.h])
PHP_CHECK_LIBRARY(fastlz, fastlz_compress,
[PHP_ADD_LIBRARY(fastlz, 1, YAC_SHARED_LIBADD)],
[AC_MSG_ERROR(FastLZ library not found)])
else
YAC_FILES="${YAC_FILES} compressor/fastlz/fastlz.c"
fi
if test "$PHP_YAC" != "no"; then
PHP_SUBST(YAC_SHARED_LIBADD)
PHP_NEW_EXTENSION(yac, ${YAC_FILES}, $ext_shared)
PHP_ADD_BUILD_DIR([$ext_builddir/storage])
PHP_ADD_BUILD_DIR([$ext_builddir/storage/allocator])
PHP_ADD_BUILD_DIR([$ext_builddir/storage/allocator/allocators])
PHP_ADD_BUILD_DIR([$ext_builddir/serializer])
PHP_ADD_BUILD_DIR([$ext_builddir/compressor])
PHP_ADD_BUILD_DIR([$ext_builddir/compressor/fastlz])
fi
yac-2.3.1/yac.c 0000664 0001750 0001750 00000071505 14157324055 014317 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include "php.h"
#include "php_ini.h"
#include "SAPI.h"
#include "ext/standard/info.h"
#include "Zend/zend_smart_str.h"
#include "Zend/zend_exceptions.h"
#include "php_yac.h"
#if PHP_MAJOR_VERSION > 7
#include "yac_arginfo.h"
#else
#include "yac_legacy_arginfo.h"
#endif
#include "storage/yac_storage.h"
#include "serializer/yac_serializer.h"
#ifdef HAVE_FASTLZ_H
#include
#else
#include "compressor/fastlz/fastlz.h"
#endif
zend_class_entry *yac_class_ce;
static zend_object_handlers yac_obj_handlers;
typedef struct {
unsigned char prefix[YAC_STORAGE_MAX_KEY_LEN];
uint16_t prefix_len;
zend_object std;
} yac_object;
ZEND_DECLARE_MODULE_GLOBALS(yac);
static yac_serializer_t yac_serializer;
static yac_unserializer_t yac_unserializer;
static PHP_INI_MH(OnChangeKeysMemoryLimit) /* {{{ */ {
if (new_value) {
YAC_G(k_msize) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
}
return SUCCESS;
}
/* }}} */
static PHP_INI_MH(OnChangeValsMemoryLimit) /* {{{ */ {
if (new_value) {
YAC_G(v_msize) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
}
return SUCCESS;
}
/* }}} */
static PHP_INI_MH(OnChangeCompressThreshold) /* {{{ */ {
if (new_value) {
YAC_G(compress_threshold) = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
if (YAC_G(compress_threshold) < YAC_MIN_COMPRESS_THRESHOLD) {
YAC_G(compress_threshold) = YAC_MIN_COMPRESS_THRESHOLD;
}
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_INI
*/
PHP_INI_BEGIN()
STD_PHP_INI_BOOLEAN("yac.enable", "1", PHP_INI_SYSTEM, OnUpdateBool, enable, zend_yac_globals, yac_globals)
STD_PHP_INI_BOOLEAN("yac.debug", "0", PHP_INI_ALL, OnUpdateBool, debug, zend_yac_globals, yac_globals)
STD_PHP_INI_ENTRY("yac.keys_memory_size", "4M", PHP_INI_SYSTEM, OnChangeKeysMemoryLimit, k_msize, zend_yac_globals, yac_globals)
STD_PHP_INI_ENTRY("yac.values_memory_size", "64M", PHP_INI_SYSTEM, OnChangeValsMemoryLimit, v_msize, zend_yac_globals, yac_globals)
STD_PHP_INI_ENTRY("yac.compress_threshold", "-1", PHP_INI_SYSTEM, OnChangeCompressThreshold, compress_threshold, zend_yac_globals, yac_globals)
STD_PHP_INI_ENTRY("yac.enable_cli", "0", PHP_INI_SYSTEM, OnUpdateBool, enable_cli, zend_yac_globals, yac_globals)
STD_PHP_INI_ENTRY("yac.serializer", "php", PHP_INI_SYSTEM, OnUpdateString, serializer, zend_yac_globals, yac_globals)
PHP_INI_END()
/* }}} */
#define Z_YACOBJ_P(zv) (php_yac_fetch_object(Z_OBJ_P(zv)))
static inline yac_object *php_yac_fetch_object(zend_object *obj) /* {{{ */ {
return (yac_object *)((char*)(obj) - XtOffsetOf(yac_object, std));
}
/* }}} */
static const char *yac_assemble_key(yac_object *yac, zend_string *name, size_t *len) /* {{{ */ {
const char *key;
if ((ZSTR_LEN(name) + yac->prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
php_error_docref(NULL, E_WARNING,
"Key '%.*s%s' exceed max key length '%d' bytes",
yac->prefix_len, yac->prefix, ZSTR_VAL(name), YAC_STORAGE_MAX_KEY_LEN);
return NULL;
}
if (yac->prefix_len) {
memcpy(yac->prefix + yac->prefix_len, ZSTR_VAL(name), ZSTR_LEN(name));
key = (const char*)yac->prefix;
*len = yac->prefix_len + ZSTR_LEN(name);
} else {
key = ZSTR_VAL(name);
*len = ZSTR_LEN(name);
}
return key;
}
/* }}} */
static int yac_add_impl(yac_object *yac, zend_string *name, zval *value, int ttl, int add) /* {{{ */ {
int ret = 0, flag = Z_TYPE_P(value);
char *msg;
time_t tv;
const char *key;
size_t key_len;
if ((key = yac_assemble_key(yac, name, &key_len)) == NULL) {
return ret;
}
tv = time(NULL);
switch (Z_TYPE_P(value)) {
case IS_NULL:
case IS_TRUE:
case IS_FALSE:
ret = yac_storage_update(key, key_len, (char *)&flag, sizeof(int), flag, ttl, add, tv);
break;
case IS_LONG:
ret = yac_storage_update(key, key_len, (char *)&Z_LVAL_P(value), sizeof(long), flag, ttl, add, tv);
break;
case IS_DOUBLE:
ret = yac_storage_update(key, key_len, (char *)&Z_DVAL_P(value), sizeof(double), flag, ttl, add, tv);
break;
case IS_STRING:
#ifdef IS_CONSTANT
case IS_CONSTANT:
#endif
{
if (Z_STRLEN_P(value) > YAC_G(compress_threshold) || Z_STRLEN_P(value) > YAC_STORAGE_MAX_ENTRY_LEN) {
int compressed_len;
char *compressed;
/* if longer than this, then we can not stored the length in flag */
if (Z_STRLEN_P(value) > YAC_ENTRY_MAX_ORIG_LEN) {
php_error_docref(NULL, E_WARNING, "Value is too long(%ld bytes) to be stored", Z_STRLEN_P(value));
return ret;
}
compressed = emalloc(Z_STRLEN_P(value) * 1.05);
compressed_len = fastlz_compress(Z_STRVAL_P(value), Z_STRLEN_P(value), compressed);
if (!compressed_len || compressed_len > Z_STRLEN_P(value)) {
php_error_docref(NULL, E_WARNING, "Compression failed");
efree(compressed);
return ret;
}
if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
php_error_docref(NULL, E_WARNING, "Value is too long(%ld bytes) to be stored", Z_STRLEN_P(value));
efree(compressed);
return ret;
}
flag |= YAC_ENTRY_COMPRESSED;
flag |= (Z_STRLEN_P(value) << YAC_ENTRY_ORIG_LEN_SHIT);
ret = yac_storage_update(key, key_len, compressed, compressed_len, flag, ttl, add, tv);
efree(compressed);
} else {
ret = yac_storage_update(key, key_len, Z_STRVAL_P(value), Z_STRLEN_P(value), flag, ttl, add, tv);
}
}
break;
case IS_ARRAY:
#ifdef IS_CONSTANT_ARRAY
case IS_CONSTANT_ARRAY:
#endif
case IS_OBJECT:
{
smart_str buf = {0};
if (yac_serializer(value, &buf, &msg)) {
if (buf.s->len > YAC_G(compress_threshold) || buf.s->len > YAC_STORAGE_MAX_ENTRY_LEN) {
int compressed_len;
char *compressed;
if (buf.s->len > YAC_ENTRY_MAX_ORIG_LEN) {
php_error_docref(NULL, E_WARNING, "Value is too big to be stored");
return ret;
}
compressed = emalloc(buf.s->len * 1.05);
compressed_len = fastlz_compress(ZSTR_VAL(buf.s), ZSTR_LEN(buf.s), compressed);
if (!compressed_len || compressed_len > buf.s->len) {
php_error_docref(NULL, E_WARNING, "Compression failed");
efree(compressed);
return ret;
}
if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
php_error_docref(NULL, E_WARNING, "Value is too big to be stored");
efree(compressed);
return ret;
}
flag |= YAC_ENTRY_COMPRESSED;
flag |= (buf.s->len << YAC_ENTRY_ORIG_LEN_SHIT);
ret = yac_storage_update(key, key_len, compressed, compressed_len, flag, ttl, add, tv);
efree(compressed);
} else {
ret = yac_storage_update(key, key_len, ZSTR_VAL(buf.s), ZSTR_LEN(buf.s), flag, ttl, add, tv);
}
smart_str_free(&buf);
} else {
php_error_docref(NULL, E_WARNING, "Serialization failed");
smart_str_free(&buf);
}
}
break;
case IS_RESOURCE:
php_error_docref(NULL, E_WARNING, "Type 'IS_RESOURCE' cannot be stored");
break;
default:
php_error_docref(NULL, E_WARNING, "Unsupported valued type to be stored '%d'", flag);
break;
}
return ret;
}
/* }}} */
static int yac_add_multi_impl(yac_object *yac, zval *kvs, int ttl, int add) /* {{{ */ {
HashTable *ht = Z_ARRVAL_P(kvs);
zend_string *key;
zend_ulong idx;
zval *value;
ZEND_HASH_FOREACH_KEY_VAL(ht, idx, key, value) {
uint32_t should_free = 0;
if (!key) {
key = strpprintf(0, "%lu", idx);
should_free = 1;
}
if (yac_add_impl(yac, key, value, ttl, add)) {
if (should_free) {
zend_string_release(key);
}
continue;
} else {
if (should_free) {
zend_string_release(key);
}
return 0;
}
} ZEND_HASH_FOREACH_END();
return 1;
}
/* }}} */
static zval* yac_get_impl(yac_object *yac, zend_string *name, uint32_t *cas, zval *rv) /* {{{ */ {
uint32_t flag, size = 0;
char *data, *msg;
time_t tv;
const char *key;
size_t key_len;
if ((key = yac_assemble_key(yac, name, &key_len)) == NULL) {
return NULL;
}
tv = time(NULL);
if (yac_storage_find(key, key_len, &data, &size, &flag, (int *)cas, tv)) {
switch ((flag & YAC_ENTRY_TYPE_MASK)) {
case IS_NULL:
if (size == sizeof(int)) {
ZVAL_NULL(rv);
}
efree(data);
break;
case IS_TRUE:
if (size == sizeof(int)) {
ZVAL_TRUE(rv);
}
efree(data);
break;
case IS_FALSE:
if (size == sizeof(int)) {
ZVAL_FALSE(rv);
}
efree(data);
break;
case IS_LONG:
if (size == sizeof(long)) {
ZVAL_LONG(rv, *(long*)data);
}
efree(data);
break;
case IS_DOUBLE:
if (size == sizeof(double)) {
ZVAL_DOUBLE(rv, *(double*)data);
}
efree(data);
break;
case IS_STRING:
#ifdef IS_CONSTANT
case IS_CONSTANT:
#endif
{
if ((flag & YAC_ENTRY_COMPRESSED)) {
size_t orig_len = ((uint32_t)flag >> YAC_ENTRY_ORIG_LEN_SHIT);
char *origin = emalloc(orig_len + 1);
uint32_t length;
length = fastlz_decompress(data, size, origin, orig_len);
if (!length) {
php_error_docref(NULL, E_WARNING, "Decompression failed");
efree(data);
efree(origin);
return NULL;
}
ZVAL_STRINGL(rv, origin, length);
efree(origin);
efree(data);
} else {
ZVAL_STRINGL(rv, data, size);
efree(data);
}
}
break;
case IS_ARRAY:
#ifdef IS_CONSTANT_ARRAY
case IS_CONSTANT_ARRAY:
#endif
case IS_OBJECT:
{
if ((flag & YAC_ENTRY_COMPRESSED)) {
size_t length, orig_len = ((uint32_t)flag >> YAC_ENTRY_ORIG_LEN_SHIT);
char *origin = emalloc(orig_len + 1);
length = fastlz_decompress(data, size, origin, orig_len);
if (!length) {
php_error_docref(NULL, E_WARNING, "Decompression failed");
efree(data);
efree(origin);
return NULL;
}
efree(data);
data = origin;
size = length;
}
rv = yac_unserializer(data, size, &msg, rv);
efree(data);
}
break;
default:
php_error_docref(NULL, E_WARNING, "Unexpected valued type '%d'", flag);
rv = NULL;
break;
}
} else {
rv = NULL;
}
return rv;
}
/* }}} */
static zval* yac_get_multi_impl(yac_object *yac, zval *keys, zval *cas, zval *rv) /* {{{ */ {
zval *value;
HashTable *ht = Z_ARRVAL_P(keys);
array_init(rv);
ZEND_HASH_FOREACH_VAL(ht, value) {
uint32_t lcas = 0;
zval *v, tmp;
switch (Z_TYPE_P(value)) {
case IS_STRING:
if ((v = yac_get_impl(yac, Z_STR_P(value), &lcas, &tmp))) {
zend_symtable_update(Z_ARRVAL_P(rv), Z_STR_P(value), v);
} else {
ZVAL_FALSE(&tmp);
zend_symtable_update(Z_ARRVAL_P(rv), Z_STR_P(value), &tmp);
}
continue;
default:
{
zend_string *key = zval_get_string(value);
if ((v = yac_get_impl(yac, key, &lcas, &tmp))) {
zend_symtable_update(Z_ARRVAL_P(rv), key, v);
} else {
ZVAL_FALSE(&tmp);
zend_symtable_update(Z_ARRVAL_P(rv), key, &tmp);
}
zend_string_release(key);
}
continue;
}
} ZEND_HASH_FOREACH_END();
return rv;
}
/* }}} */
static int yac_delete_impl(yac_object *yac, zend_string *name, int ttl) /* {{{ */ {
time_t tv = 0;
const char *key;
size_t key_len;
if ((key = yac_assemble_key(yac, name, &key_len)) == NULL) {
return 0;
}
if (ttl) {
tv = (zend_ulong)time(NULL);
}
return yac_storage_delete(key, key_len, ttl, tv);
}
/* }}} */
static int yac_delete_multi_impl(yac_object *yac, zval *keys, int ttl) /* {{{ */ {
HashTable *ht = Z_ARRVAL_P(keys);
int ret = 1;
zval *value;
ZEND_HASH_FOREACH_VAL(ht, value) {
switch (Z_TYPE_P(value)) {
case IS_STRING:
ret = ret & yac_delete_impl(yac, Z_STR_P(value), ttl);
continue;
default:
{
zend_string *key = zval_get_string(value);
ret = ret & yac_delete_impl(yac, key, ttl);
zend_string_release(key);
}
continue;
}
} ZEND_HASH_FOREACH_END();
return ret;
}
/* }}} */
static zend_object *yac_object_new(zend_class_entry *ce) /* {{{ */ {
yac_object *yac = emalloc(sizeof(yac_object) + zend_object_properties_size(ce));
zend_object_std_init(&yac->std, ce);
yac->std.handlers = &yac_obj_handlers;
yac->prefix_len = 0;
return &yac->std;
}
/* }}} */
static void yac_object_free(zend_object *object) /* {{{ */ {
zend_object_std_dtor(object);
}
/* }}} */
static zval* yac_read_property_ptr(void *zobj, void *name, int type, void **cache_slot) /* {{{ */ {
zend_string *member;
#if PHP_VERSION_ID < 80000
member = Z_STR_P((zval*)name);
#else
member = (zend_string*)name;
#endif
zend_throw_exception_ex(NULL, 0, "Retrieval of Yac->%s for modification is unsupported", ZSTR_VAL(member));
return &EG(error_zval);
}
/* }}} */
static zval* yac_read_property(void /* for PHP8 compatibility */ *zobj, void *name, int type, void **cache_slot, zval *rv) /* {{{ */ {
yac_object *yac;
zend_string *member;
if (UNEXPECTED(type == BP_VAR_RW||type == BP_VAR_W)) {
return &EG(error_zval);
}
#if PHP_VERSION_ID < 80000
yac = Z_YACOBJ_P((zval*)zobj);
member = Z_STR_P((zval*)name);
#else
yac = php_yac_fetch_object((zend_object*)zobj);
member = (zend_string*)name;
#endif
if (yac_get_impl(yac, member, NULL, rv)) {
return rv;
}
return &EG(uninitialized_zval);
}
/* }}} */
static YAC_WHANDLER yac_write_property(void *zobj, void *name, zval *value, void **cache_slot) /* {{{ */ {
yac_object *yac;
zend_string *member;
#if PHP_VERSION_ID < 80000
yac = Z_YACOBJ_P((zval*)zobj);
member = Z_STR_P((zval*)name);
#else
yac = php_yac_fetch_object((zend_object*)zobj);
member = (zend_string*)name;
#endif
yac_add_impl(yac, member, value, 0, 0);
Z_TRY_ADDREF_P(value);
YAC_WHANDLER_RET(value);
}
/* }}} */
static void yac_unset_property(void *zobj, void *name, void **cache_slot) /* {{{ */ {
yac_object *yac;
zend_string *member;
#if PHP_VERSION_ID < 80000
yac = Z_YACOBJ_P((zval*)zobj);
member = Z_STR_P((zval*)name);
#else
yac = php_yac_fetch_object((zend_object*)zobj);
member = (zend_string*)name;
#endif
yac_delete_impl(yac, member, 0);
}
/* }}} */
/** {{{ proto public Yac::__construct([string $prefix])
*/
PHP_METHOD(yac, __construct) {
zend_string *prefix = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|S", &prefix) == FAILURE) {
return;
}
if (!YAC_G(enable)) {
zend_throw_exception(NULL, "Yac is not enabled", 0);
}
if (prefix && ZSTR_LEN(prefix)) {
yac_object *yac;
if (ZSTR_LEN(prefix) > YAC_STORAGE_MAX_KEY_LEN) {
zend_throw_exception_ex(NULL, 0,
"Prefix '%s' exceed max key length '%d' bytes", ZSTR_VAL(prefix), YAC_STORAGE_MAX_KEY_LEN);
return;
}
yac = Z_YACOBJ_P(getThis());
yac->prefix_len = ZSTR_LEN(prefix);
memcpy(yac->prefix, ZSTR_VAL(prefix), ZSTR_LEN(prefix));
}
}
/* }}} */
/** {{{ proto public Yac::add(mixed $keys, mixed $value[, int $ttl])
*/
PHP_METHOD(yac, add) {
zend_long ttl = 0;
zval *keys, *value = NULL;
int ret;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &keys) == FAILURE) {
return;
}
break;
case 2:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &keys, &value) == FAILURE) {
return;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
if (Z_TYPE_P(value) == IS_LONG) {
ttl = Z_LVAL_P(value);
value = NULL;
} else {
php_error_docref(NULL, E_WARNING, "ttl parameter must be an integer");
return;
}
}
break;
case 3:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzl", &keys, &value, &ttl) == FAILURE) {
return;
}
break;
default:
WRONG_PARAM_COUNT;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
ret = yac_add_multi_impl(Z_YACOBJ_P(getThis()), keys, ttl, 1);
} else if (Z_TYPE_P(keys) == IS_STRING) {
ret = yac_add_impl(Z_YACOBJ_P(getThis()), Z_STR_P(keys), value, ttl, 1);
} else {
zend_string *key = zval_get_string(keys);
ret = yac_add_impl(Z_YACOBJ_P(getThis()), key, value, ttl, 1);
zend_string_release(key);
}
RETURN_BOOL(ret);
}
/* }}} */
/** {{{ proto public Yac::set(mixed $keys, mixed $value[, int $ttl])
*/
PHP_METHOD(yac, set) {
zend_long ttl = 0;
zval *keys, *value = NULL;
int ret;
switch (ZEND_NUM_ARGS()) {
case 1:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a", &keys) == FAILURE) {
return;
}
break;
case 2:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &keys, &value) == FAILURE) {
return;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
if (Z_TYPE_P(value) == IS_LONG) {
ttl = Z_LVAL_P(value);
value = NULL;
} else {
php_error_docref(NULL, E_WARNING, "ttl parameter must be an integer");
return;
}
}
break;
case 3:
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzl", &keys, &value, &ttl) == FAILURE) {
return;
}
break;
default:
WRONG_PARAM_COUNT;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
ret = yac_add_multi_impl(Z_YACOBJ_P(getThis()), keys, ttl, 0);
} else if (Z_TYPE_P(keys) == IS_STRING) {
ret = yac_add_impl(Z_YACOBJ_P(getThis()), Z_STR_P(keys), value, ttl, 0);
} else {
zend_string *key = zval_get_string(keys);
ret = yac_add_impl(Z_YACOBJ_P(getThis()), key, value, ttl, 0);
zend_string_release(key);
}
RETURN_BOOL(ret);
}
/* }}} */
/** {{{ proto public Yac::get(mixed $keys[, int &$cas])
*/
PHP_METHOD(yac, get) {
uint32_t lcas = 0;
zval *ret, *keys, *cas = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|z", &keys, &cas) == FAILURE) {
return;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
ret = yac_get_multi_impl(Z_YACOBJ_P(getThis()), keys, cas, return_value);
} else if (Z_TYPE_P(keys) == IS_STRING) {
ret = yac_get_impl(Z_YACOBJ_P(getThis()), Z_STR_P(keys), &lcas, return_value);
} else {
zend_string *key = zval_get_string(keys);
ret = yac_get_impl(Z_YACOBJ_P(getThis()), key, &lcas, return_value);
zend_string_release(key);
}
if (ret == NULL) {
RETURN_FALSE;
}
}
/* }}} */
/** {{{ proto public Yac::delete(mixed $key[, int $delay = 0])
*/
PHP_METHOD(yac, delete) {
zend_long time = 0;
zval *keys;
int ret;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|l", &keys, &time) == FAILURE) {
return;
}
if (Z_TYPE_P(keys) == IS_ARRAY) {
ret = yac_delete_multi_impl(Z_YACOBJ_P(getThis()), keys, time);
} else if (Z_TYPE_P(keys) == IS_STRING) {
ret = yac_delete_impl(Z_YACOBJ_P(getThis()), Z_STR_P(keys), time);
} else {
zend_string *key = zval_get_string(keys);
ret = yac_delete_impl(Z_YACOBJ_P(getThis()), key, time);
zend_string_release(key);
}
RETURN_BOOL(ret);
}
/* }}} */
/** {{{ proto public Yac::flush(void)
*/
PHP_METHOD(yac, flush) {
yac_storage_flush();
RETURN_TRUE;
}
/* }}} */
/** {{{ proto public Yac::info(void)
*/
PHP_METHOD(yac, info) {
yac_storage_info *inf;
inf = yac_storage_get_info();
array_init(return_value);
add_assoc_long(return_value, "memory_size", inf->k_msize + inf->v_msize);
add_assoc_long(return_value, "slots_memory_size", inf->k_msize);
add_assoc_long(return_value, "values_memory_size", inf->v_msize);
add_assoc_long(return_value, "segment_size", inf->segment_size);
add_assoc_long(return_value, "segment_num", inf->segments_num);
add_assoc_long(return_value, "miss", inf->miss);
add_assoc_long(return_value, "hits", inf->hits);
add_assoc_long(return_value, "fails", inf->fails);
add_assoc_long(return_value, "kicks", inf->kicks);
add_assoc_long(return_value, "recycles", inf->recycles);
add_assoc_long(return_value, "slots_size", inf->slots_size);
add_assoc_long(return_value, "slots_used", inf->slots_num);
yac_storage_free_info(inf);
return;
}
/* }}} */
/** {{{ proto public Yac::dump(int $limit)
*/
PHP_METHOD(yac, dump) {
long limit = 100;
yac_item_list *list, *l;
array_init(return_value);
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &limit) == FAILURE) {
return;
}
list = l = yac_storage_dump(limit);
for (; l; l = l->next) {
zval item;
array_init(&item);
add_assoc_long(&item, "index", l->index);
add_assoc_long(&item, "hash", l->h);
add_assoc_long(&item, "crc", l->crc);
add_assoc_long(&item, "ttl", l->ttl);
add_assoc_long(&item, "k_len", l->k_len);
add_assoc_long(&item, "v_len", l->v_len);
add_assoc_long(&item, "size", l->size);
add_assoc_string(&item, "key", (char*)l->key);
add_next_index_zval(return_value, &item);
}
yac_storage_free_list(list);
return;
}
/* }}} */
#if 0
only OO-style APIs is supported now
/* {{{{ proto bool yac_add(mixed $keys, mixed $value[, int $ttl])
*/
PHP_FUNCTION(yac_add)
{
PHP_MN(yac_add)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool yac_set(mixed $keys, mixed $value[, int $ttl])
*/
PHP_FUNCTION(yac_set)
{
PHP_MN(yac_set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool yac_get(mixed $keys[, int &$cas])
*/
PHP_FUNCTION(yac_get)
{
PHP_MN(yac_get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool yac_delete(mixed $keys[, int $delay = 0])
*/
PHP_FUNCTION(yac_delete)
{
PHP_MN(yac_delete)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool yac_flush(void)
*/
PHP_FUNCTION(yac_flush)
{
PHP_MN(yac_flush)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ proto bool yac_info(void)
*/
PHP_FUNCTION(yac_info)
{
PHP_MN(yac_info)(INTERNAL_FUNCTION_PARAM_PASSTHRU);
}
/* }}} */
/* {{{ yac_functions[] */
zend_function_entry yac_functions[] = {
PHP_FE(yac_add, arginfo_yac_add)
PHP_FE(yac_set, arginfo_yac_add)
PHP_FE(yac_get, arginfo_yac_get)
PHP_FE(yac_delete, arginfo_yac_delete)
PHP_FE(yac_flush, arginfo_yac_void)
PHP_FE(yac_info, arginfo_yac_void)
{NULL, NULL}
};
/* }}} */
#endif
/** {{{ yac_methods
*/
zend_function_entry yac_methods[] = {
PHP_ME(yac, __construct, arginfo_class_Yac___construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR)
PHP_ME(yac, add, arginfo_class_Yac_add, ZEND_ACC_PUBLIC)
PHP_ME(yac, set, arginfo_class_Yac_set, ZEND_ACC_PUBLIC)
PHP_ME(yac, get, arginfo_class_Yac_get, ZEND_ACC_PUBLIC)
PHP_ME(yac, delete, arginfo_class_Yac_delete, ZEND_ACC_PUBLIC)
PHP_ME(yac, flush, arginfo_class_Yac_flush, ZEND_ACC_PUBLIC)
PHP_ME(yac, info, arginfo_class_Yac_info, ZEND_ACC_PUBLIC)
PHP_ME(yac, dump, arginfo_class_Yac_dump, ZEND_ACC_PUBLIC)
{NULL, NULL, NULL}
};
/* }}} */
/* {{{ PHP_GINIT_FUNCTION
*/
PHP_GINIT_FUNCTION(yac)
{
yac_globals->enable = 1;
yac_globals->k_msize = (4 * 1024 * 1024);
yac_globals->v_msize = (64 * 1024 * 1024);
yac_globals->debug = 0;
yac_globals->compress_threshold = -1;
yac_globals->enable_cli = 0;
#ifdef PHP_WIN32
yac_globals->mmap_base = NULL;
#endif
}
/* }}} */
/* {{{ PHP_MINIT_FUNCTION
*/
PHP_MINIT_FUNCTION(yac)
{
char *msg;
zend_class_entry ce;
REGISTER_INI_ENTRIES();
if (!YAC_G(enable_cli) && !strcmp(sapi_module.name, "cli")) {
YAC_G(enable) = 0;
}
if (YAC_G(enable)) {
if (!yac_storage_startup(YAC_G(k_msize), YAC_G(v_msize), &msg)) {
php_error(E_ERROR, "Shared memory allocator startup failed at '%s': %s", msg, strerror(errno));
return FAILURE;
}
}
REGISTER_STRINGL_CONSTANT("YAC_VERSION", PHP_YAC_VERSION, sizeof(PHP_YAC_VERSION) - 1, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("YAC_MAX_KEY_LEN", YAC_STORAGE_MAX_KEY_LEN, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("YAC_MAX_VALUE_RAW_LEN", YAC_ENTRY_MAX_ORIG_LEN, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("YAC_MAX_RAW_COMPRESSED_LEN", YAC_STORAGE_MAX_ENTRY_LEN, CONST_PERSISTENT | CONST_CS);
REGISTER_LONG_CONSTANT("YAC_SERIALIZER_PHP", YAC_SERIALIZER_PHP, CONST_PERSISTENT | CONST_CS);
#if YAC_ENABLE_MSGPACK
REGISTER_LONG_CONSTANT("YAC_SERIALIZER_MSGPACK", YAC_SERIALIZER_MSGPACK, CONST_PERSISTENT | CONST_CS);
#endif
#if YAC_ENABLE_IGBINARY
REGISTER_LONG_CONSTANT("YAC_SERIALIZER_IGBINARY", YAC_SERIALIZER_IGBINARY, CONST_PERSISTENT | CONST_CS);
#endif
#if YAC_ENABLE_JSON
REGISTER_LONG_CONSTANT("YAC_SERIALIZER_JSON", YAC_SERIALIZER_JSON, CONST_PERSISTENT | CONST_CS);
#endif
#if YAC_ENABLE_MSGPACK
if (strcmp(YAC_G(serializer), "msgpack") == 0) {
yac_serializer = yac_serializer_msgpack_pack;
yac_unserializer = yac_serializer_msgpack_unpack;
REGISTER_LONG_CONSTANT("YAC_SERIALIZER", YAC_SERIALIZER_MSGPACK, CONST_PERSISTENT | CONST_CS);
} else
#endif
#if YAC_ENABLE_IGBINARY
if (strcmp(YAC_G(serializer), "igbinary") == 0) {
yac_serializer = yac_serializer_igbinary_pack;
yac_unserializer = yac_serializer_igbinary_unpack;
REGISTER_LONG_CONSTANT("YAC_SERIALIZER", YAC_SERIALIZER_IGBINARY, CONST_PERSISTENT | CONST_CS);
} else
#endif
#if YAC_ENABLE_JSON
if (strcmp(YAC_G(serializer), "json") == 0) {
yac_serializer = yac_serializer_json_pack;
yac_unserializer = yac_serializer_json_unpack;
REGISTER_LONG_CONSTANT("YAC_SERIALIZER", YAC_SERIALIZER_JSON, CONST_PERSISTENT | CONST_CS);
} else
#endif
{
yac_serializer = yac_serializer_php_pack;
yac_unserializer = yac_serializer_php_unpack;
REGISTER_LONG_CONSTANT("YAC_SERIALIZER", YAC_SERIALIZER_PHP, CONST_PERSISTENT | CONST_CS);
}
INIT_CLASS_ENTRY(ce, "Yac", yac_methods);
yac_class_ce = zend_register_internal_class(&ce);
yac_class_ce->ce_flags |= ZEND_ACC_FINAL;
yac_class_ce->create_object = yac_object_new;
memcpy(&yac_obj_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
yac_obj_handlers.offset = XtOffsetOf(yac_object, std);
yac_obj_handlers.free_obj = yac_object_free;
if (YAC_G(enable)) {
yac_obj_handlers.read_property = (zend_object_read_property_t)yac_read_property;
yac_obj_handlers.write_property = (zend_object_write_property_t)yac_write_property;
yac_obj_handlers.unset_property = (zend_object_unset_property_t)yac_unset_property;
yac_obj_handlers.get_property_ptr_ptr = (zend_object_get_property_ptr_ptr_t)yac_read_property_ptr;
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MSHUTDOWN_FUNCTION
*/
PHP_MSHUTDOWN_FUNCTION(yac)
{
UNREGISTER_INI_ENTRIES();
if (YAC_G(enable)) {
yac_storage_shutdown();
}
return SUCCESS;
}
/* }}} */
/* {{{ PHP_MINFO_FUNCTION
*/
PHP_MINFO_FUNCTION(yac)
{
smart_str names = {0,};
php_info_print_table_start();
php_info_print_table_header(2, "yac support", "enabled");
php_info_print_table_row(2, "Version", PHP_YAC_VERSION);
php_info_print_table_row(2, "Shared Memory", yac_storage_shared_memory_name());
smart_str_appends(&names, "php");
#if YAC_ENABLE_MSGPACK
smart_str_appends(&names, ", msgpack");
#endif
#if YAC_ENABLE_IGBINARY
smart_str_appends(&names, ", igbinary");
#endif
#if YAC_ENABLE_JSON
smart_str_appends(&names, ", json");
#endif
php_info_print_table_row(2, "Serializer", ZSTR_VAL(names.s));
smart_str_free(&names);
php_info_print_table_end();
DISPLAY_INI_ENTRIES();
if (YAC_G(enable)) {
char buf[64];
yac_storage_info *inf;
inf = yac_storage_get_info();
php_info_print_table_start();
php_info_print_table_colspan_header(2, "Cache info");
snprintf(buf, sizeof(buf), "%ld", inf->k_msize + inf->v_msize);
php_info_print_table_row(2, "Total Shared Memory Usage(memory_size)", buf);
snprintf(buf, sizeof(buf), "%ld", inf->k_msize);
php_info_print_table_row(2, "Total Shared Memory Usage for keys(keys_memory_size)", buf);
snprintf(buf, sizeof(buf), "%ld", inf->v_msize);
php_info_print_table_row(2, "Total Shared Memory Usage for values(values_memory_size)", buf);
snprintf(buf, sizeof(buf), "%d", inf->segment_size);
php_info_print_table_row(2, "Size of Shared Memory Segment(segment_size)", buf);
snprintf(buf, sizeof(buf), "%d", inf->segments_num);
php_info_print_table_row(2, "Number of Segments (segment_num)", buf);
snprintf(buf, sizeof(buf), "%d", inf->slots_size);
php_info_print_table_row(2, "Total Slots Number(slots_size)", buf);
snprintf(buf, sizeof(buf), "%d", inf->slots_num);
php_info_print_table_row(2, "Total Used Slots(slots_num)", buf);
php_info_print_table_end();
yac_storage_free_info(inf);
}
}
/* }}} */
#ifdef COMPILE_DL_YAC
ZEND_GET_MODULE(yac)
#endif
static zend_module_dep yac_module_deps[] = {
#if YAC_ENABLE_MSGPACK
ZEND_MOD_REQUIRED("msgpack")
#endif
#if YAC_ENABLE_IGBINARY
ZEND_MOD_REQUIRED("igbinary")
#endif
#if YAC_ENABLE_JSON
ZEND_MOD_REQUIRED("json")
#endif
{NULL, NULL, NULL, 0}
};
/* {{{ yac_module_entry
*/
zend_module_entry yac_module_entry = {
STANDARD_MODULE_HEADER_EX,
NULL,
yac_module_deps,
"yac",
NULL, /* yac_functions, */
PHP_MINIT(yac),
PHP_MSHUTDOWN(yac),
NULL,
NULL,
PHP_MINFO(yac),
PHP_YAC_VERSION,
PHP_MODULE_GLOBALS(yac),
PHP_GINIT(yac),
NULL,
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/php_yac.h 0000664 0001750 0001750 00000005215 14157324055 015166 0 ustar huixinchen huixinchen /*
+----------------------------------------------------------------------+
| Yet Another Cache |
+----------------------------------------------------------------------+
| Copyright (c) 2013-2013 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Xinchen Hui |
+----------------------------------------------------------------------+
*/
/* $Id$ */
#ifndef PHP_YAC_H
#define PHP_YAC_H
extern zend_module_entry yac_module_entry;
#define phpext_yac_ptr &yac_module_entry
#ifdef PHP_WIN32
#define PHP_YAC_API __declspec(dllexport)
#else
#define PHP_YAC_API
#endif
#ifdef ZTS
#include "TSRM.h"
#endif
#define PHP_YAC_VERSION "2.3.1"
#if PHP_VERSION_ID < 70400
#define YAC_WHANDLER void
#define YAC_WHANDLER_RET(zv) return
#else
#define YAC_WHANDLER zval *
#define YAC_WHANDLER_RET(zv) return zv
#endif
#define YAC_CLASS_PROPERTY_PREFIX "_prefix"
#define YAC_ENTRY_COMPRESSED 0x0020
#define YAC_ENTRY_TYPE_MASK 0x1f
#define YAC_ENTRY_ORIG_LEN_SHIT 6
#define YAC_ENTRY_MAX_ORIG_LEN ((1U << ((sizeof(int)*8 - YAC_ENTRY_ORIG_LEN_SHIT))) - 1)
#define YAC_MIN_COMPRESS_THRESHOLD 1024
#define YAC_SERIALIZER_PHP 0
#define YAC_SERIALIZER_JSON 1
#define YAC_SERIALIZER_MSGPACK 2
#define YAC_SERIALIZER_IGBINARY 3
ZEND_BEGIN_MODULE_GLOBALS(yac)
zend_bool enable;
zend_bool debug;
size_t k_msize;
size_t v_msize;
zend_ulong compress_threshold;
zend_bool enable_cli;
char *serializer;
#ifdef PHP_WIN32
char *mmap_base;
#endif
ZEND_END_MODULE_GLOBALS(yac)
PHP_MINIT_FUNCTION(yac);
PHP_MSHUTDOWN_FUNCTION(yac);
PHP_RINIT_FUNCTION(yac);
PHP_RSHUTDOWN_FUNCTION(yac);
PHP_MINFO_FUNCTION(yac);
ZEND_EXTERN_MODULE_GLOBALS(yac);
#define YAC_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(yac, v)
#endif /* PHP_YAC_H */
/*
* Local variables:
* tab-width: 4
* c-basic-offset: 4
* End:
* vim600: noet sw=4 ts=4 fdm=marker
* vim<600: noet sw=4 ts=4
*/
yac-2.3.1/yac_arginfo.h 0000664 0001750 0001750 00000002647 14157324055 016032 0 ustar huixinchen huixinchen /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 0b50242ac2a8f06b2a78418f81c37ac715561053 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, prefix, IS_STRING, 0, "\"\"")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_add, 0, 2, _IS_BOOL, 1)
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO(0, value, IS_MIXED, 0)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, ttl, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_get, 0, 1, _IS_BOOL, 1)
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(1, cas, IS_MIXED, 0, "NULL")
ZEND_END_ARG_INFO()
#define arginfo_class_Yac_set arginfo_class_Yac_add
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_delete, 0, 1, _IS_BOOL, 1)
ZEND_ARG_TYPE_MASK(0, key, MAY_BE_STRING|MAY_BE_ARRAY, NULL)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, delay, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_flush, 0, 0, _IS_BOOL, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_info, 0, 0, IS_ARRAY, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Yac_dump, 0, 0, IS_ARRAY, 1)
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, limit, IS_LONG, 0, "0")
ZEND_END_ARG_INFO()
yac-2.3.1/yac_legacy_arginfo.h 0000664 0001750 0001750 00000001623 14157324055 017347 0 ustar huixinchen huixinchen /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 0b50242ac2a8f06b2a78418f81c37ac715561053 */
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac___construct, 0, 0, 0)
ZEND_ARG_INFO(0, prefix)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac_add, 0, 0, 2)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, value)
ZEND_ARG_INFO(0, ttl)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac_get, 0, 0, 1)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(1, cas)
ZEND_END_ARG_INFO()
#define arginfo_class_Yac_set arginfo_class_Yac_add
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac_delete, 0, 0, 1)
ZEND_ARG_INFO(0, key)
ZEND_ARG_INFO(0, delay)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac_flush, 0, 0, 0)
ZEND_END_ARG_INFO()
#define arginfo_class_Yac_info arginfo_class_Yac_flush
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Yac_dump, 0, 0, 0)
ZEND_ARG_INFO(0, limit)
ZEND_END_ARG_INFO()