示例#1
0
文件: yac.c 项目: anakin/yac
static int yac_add_impl(char *prefix, uint prefix_len, char *key, uint len, zval *value, int ttl, int add TSRMLS_DC) /* {{{ */ {
	int ret = 0, flag = Z_TYPE_P(value);
	char *msg, buf[YAC_STORAGE_MAX_KEY_LEN];

	if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes",
				prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
		return ret;
	}

	if (prefix_len) {
		len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
		key = (char *)buf;
	}

	switch (Z_TYPE_P(value)) {
		case IS_NULL:
			ret = yac_storage_update(key, len, (char *)&flag, sizeof(int), flag, add, ttl);
			break;
		case IS_BOOL:
		case IS_LONG:
			ret = yac_storage_update(key, len, (char *)&Z_LVAL_P(value), sizeof(long), flag, add, ttl);
			break;
		case IS_DOUBLE:
			ret = yac_storage_update(key, len, (char *)&Z_DVAL_P(value), sizeof(double), flag, add, ttl);
			break;
		case IS_STRING:
		case IS_CONSTANT:
			{
				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 TSRMLS_CC, E_WARNING, "Value is too long(%d 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 TSRMLS_CC, E_WARNING, "Compression failed");
						efree(compressed);
						return ret;
					}

					if (compressed_len > YAC_G(compress_threshold) || compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d 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, len, compressed, compressed_len, flag, ttl, add);
					efree(compressed);
				} else {
					ret = yac_storage_update(key, len, Z_STRVAL_P(value), Z_STRLEN_P(value), flag, ttl, add);
				}
			}
			break;
		case IS_ARRAY:
		case IS_CONSTANT_ARRAY:
		case IS_OBJECT:
			{
				smart_str buf = {0};
				if (yac_serializer_php_pack(value, &buf, &msg TSRMLS_CC)) {
					if (buf.len > YAC_G(compress_threshold) || buf.len > YAC_STORAGE_MAX_ENTRY_LEN) {
						int compressed_len;
						char *compressed;

						if (buf.len > YAC_ENTRY_MAX_ORIG_LEN) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
							return ret;
						}

						compressed = emalloc(buf.len * 1.05);
						compressed_len = fastlz_compress(buf.c, buf.len, compressed);
						if (!compressed_len || compressed_len > buf.len) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed");
							efree(compressed);
							return ret;
						}

						if (compressed_len > YAC_G(compress_threshold) || compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
							efree(compressed);
							return ret;
						}

						flag |= YAC_ENTRY_COMPRESSED;
						flag |= (buf.len << YAC_ENTRY_ORIG_LEN_SHIT);
						ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add);
						efree(compressed);
					} else {
						ret = yac_storage_update(key, len, buf.c, buf.len, flag, ttl, add);
					}
					smart_str_free(&buf);
				} else {
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serialization failed");
					smart_str_free(&buf);
				}
			}
			break;
		case IS_RESOURCE:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type 'IS_RESOURCE' cannot be stored");
			break;
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported valued type to be stored '%d'", flag);
			break;
	}

	return ret;
}
示例#2
0
文件: yac.c 项目: Neeke/yac
static int yac_add_impl(zend_string *prefix, zend_string *key, zval *value, int ttl, int add) /* {{{ */ {
	int ret = 0, flag = Z_TYPE_P(value);
	char *msg;
	time_t tv;
	zend_string *prefix_key;

	if ((ZSTR_LEN(key) + prefix->len) > YAC_STORAGE_MAX_KEY_LEN) {
		php_error_docref(NULL, E_WARNING, "Key%s can not be longer than %d bytes",
				prefix->len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
		return ret;
	}

	if (prefix->len) {
		prefix_key = strpprintf(YAC_STORAGE_MAX_KEY_LEN, "%s%s", ZSTR_VAL(prefix), ZSTR_VAL(key));
		key = prefix_key;
	}

	tv = time(NULL);
	switch (Z_TYPE_P(value)) {
		case IS_NULL:
		case IS_TRUE:
		case IS_FALSE:
			ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), (char *)&flag, sizeof(int), flag, ttl, add, tv);
			break;
		case IS_LONG:
			ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), (char *)&Z_LVAL_P(value), sizeof(long), flag, ttl, add, tv);
			break;
		case IS_DOUBLE:
			ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), (char *)&Z_DVAL_P(value), sizeof(double), flag, ttl, add, tv);
			break;
		case IS_STRING:
		case IS_CONSTANT:
			{
				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(%d bytes) to be stored", Z_STRLEN_P(value));
						if (prefix->len) {
							zend_string_release(prefix_key);
						}
						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);
						if (prefix->len) {
							zend_string_release(prefix_key);
						}
						return ret;
					}

					if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
						php_error_docref(NULL, E_WARNING, "Value is too long(%d bytes) to be stored", Z_STRLEN_P(value));
						efree(compressed);
						if (prefix->len) {
							zend_string_release(prefix_key);
						}
						return ret;
					}

					flag |= YAC_ENTRY_COMPRESSED;
					flag |= (Z_STRLEN_P(value) << YAC_ENTRY_ORIG_LEN_SHIT);
					ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), compressed, compressed_len, flag, ttl, add, tv);
					efree(compressed);
				} else {
					ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), 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 ENABLE_MSGPACK
				if (yac_serializer_msgpack_pack(value, &buf, &msg))
#else

				if (yac_serializer_php_pack(value, &buf, &msg))
#endif
				{
					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");
							if (prefix->len) {
								zend_string_release(prefix_key);
							}
							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);
							if (prefix->len) {
								zend_string_release(prefix_key);
							}
							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);
							if (prefix->len) {
								zend_string_release(prefix_key);
							}
							return ret;
						}

						flag |= YAC_ENTRY_COMPRESSED;
						flag |= (buf.s->len << YAC_ENTRY_ORIG_LEN_SHIT);
						ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), compressed, compressed_len, flag, ttl, add, tv);
						efree(compressed);
					} else {
						ret = yac_storage_update(ZSTR_VAL(key), ZSTR_LEN(key), 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;
	}

	if (prefix->len) {
		zend_string_release(prefix_key);
	}

	return ret;
}
示例#3
0
static int yac_add_impl(char *prefix, uint prefix_len, char*key, uint len, zval *value, int ttl, int add TSRMLS_DC){
	int ret = 0, flag = z_type_p(value);
	char *msg, buf[YAC_STORAGE_MAX_KEY_LEN];

	if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN){
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "key%s can not be longer than %d bytes", 
				prefix_len?"(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
		return ret;
	}

	if (prefix_len) {
		len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
		key = (char *)buf;
	}

	switch(z_type_p(value)) {
		case is_null:
			ret = yac_storage_update(key, len, (char *)&flag, sizeof(int), flag, add, ttl);
			break;
		case is_bool:
		case is_long:
			ret = yac_storage_update(key, len, (char *)&z_lval_p(value), sizeof(long), flag, add, ttl);
			break;
		case is_double:
			ret = yac_storage_update(key, len, (char *)&z_dval_p(value), sizeof(double), flag, add, ttl);
			break;
		case is_string:
		case is_constant:
			{
				if(z_strlen_p(value) > yac_g(compress_threshold) || z_strlen_p(value) > yac_storage_max_entry_len) {
					int compresssed_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 TSRMLS_CC, E_WARNING, "Value is too long(%d 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 TSRMLS_CC, E_WARNING, "Compression failed");
						efree(compressed);
						return ret;
					}

					if (compressed_len > yac_g(compress_threshold) || compressed_len > yac_storage_max_entry_len) {
						php_error_docref(null TSRMLS_CC, E_WARNING, "Value is too long(%d bytes) to be stored", z_strlen_p(value));
						efree(compressed);
						return ret;
					}

					flag |= yac_entry_compressed;
					flag |= (z_strlen_p(value) << yac_entry_orgi_len_shit);
					ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add);

					efree(compressed);
				} else {
					ret = yac_storage_update(key, len, z_strval_p(value), z_strlen_p(value), flag, ttl, add);
				}
			}
			break;
		case is_array:
		case is_constant_array:
		case is_object:
			{
				smart_str buf = {0};
				if (yac_serializer_php_pack(value, &buf, &msg TSRMLS_CC)) {
					if(buf.len > yac_g(compress_threshold) || buf.len > yac_storage_max_entry_len) {
						int compressed_len;
						char *compressed;

						if (buf.len > yac_entry_max_orig_len) {
							php_error_docref(null TSRMLS_CC, E_WARNING, "Value is too big to be stored");
							return ret;
						}

						compressed = emalloc(buf.len * 1.05);
						compressed_len = fastlz_compress(buf.c, buf.len, compressed);
						if (!compressed_len || compressed_len > buf.len) {
							php_error_docref(null TSRMLS_CC, E_WARNING, "Compression failed");
							efree(compressed);
							return re;
						}

						if (compressed_len > yac_g(compress_threshold) || compressed_len > yac_storage_max_entry_len) {
							php_error_docref(null tsrmls_cc, E_WARNING, "Value is too big to be stored");
							efree(compressed);
							return ret;
						}

						flag |= yac_entry_compressed;
						flag |= (buf.len << yac_entry_orig_len_shit);
						ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add);
						efree(compressed);
					} else {
						ret = yac_storage_update(key, len, buf.c, buf.len, flag, ttl, add);
					}
					smart_str_free(&buf);
				} else {
					php_error_docref(null tsrmls_cc, E_WARNING, "Serialization failed");
					smart_str_free(&buf);
				}
			}
			break;
		case is_resource:
			php_error_docref(null tsrmls_cc, E_WARNING, "Type 'is_resource' cannot be stored");
			break;
		default:
			php_error_docref(null tsrmls_cc, E_WARNING, "Unsupported valued type to be stored '%d', flag");
			break;
	}

	return ret;
}
示例#4
0
文件: yac.c 项目: PainAndLove/yac
static int yac_add_impl(char *prefix, uint prefix_len, char *key, uint len, zval *value, int ttl, int add TSRMLS_DC) /* {{{ */ {
	int ret = 0, flag = Z_TYPE_P(value);
	char *msg, buf[YAC_STORAGE_MAX_KEY_LEN];
	time_t tv;

	if ((len + prefix_len) > YAC_STORAGE_MAX_KEY_LEN) {
		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Key%s can not be longer than %d bytes",
				prefix_len? "(include prefix)" : "", YAC_STORAGE_MAX_KEY_LEN);
		return ret;
	}

	if (prefix_len) {
		len = snprintf(buf, sizeof(buf), "%s%s", prefix, key);
		key = (char *)buf;
	}

	
	tv = time(NULL);
	switch (Z_TYPE_P(value)) {
		case IS_NULL:
			ret = yac_storage_update(key, len, (char *)&flag, sizeof(int), flag, ttl, add, tv);
			break;
		case IS_BOOL:
		case IS_LONG:
			ret = yac_storage_update(key, len, (char *)&Z_LVAL_P(value), sizeof(long), flag, ttl, add, tv);
			break;
		case IS_DOUBLE:
			ret = yac_storage_update(key, len, (char *)&Z_DVAL_P(value), sizeof(double), flag, ttl, add, tv);
			break;
		case IS_STRING:
		case IS_CONSTANT:
			{
				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 TSRMLS_CC, E_WARNING, "Value is too long(%d 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 TSRMLS_CC, E_WARNING, "Compression failed");
						efree(compressed);
						return ret;
					}

					if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
						php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too long(%d 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, len, compressed, compressed_len, flag, ttl, add, tv);
					efree(compressed);
				} else {
					ret = yac_storage_update(key, len, Z_STRVAL_P(value), Z_STRLEN_P(value), flag, ttl, add, tv);
				}
			}
			break;
		case IS_ARRAY:
		case IS_CONSTANT_ARRAY:
		case IS_OBJECT:
			{
				smart_str buf = {0};
#if ENABLE_MSGPACK
				if (yac_serializer_msgpack_pack(value, &buf, &msg TSRMLS_CC)) {
#else

				if (yac_serializer_php_pack(value, &buf, &msg TSRMLS_CC)) {
#endif
					if (buf.len > YAC_G(compress_threshold) || buf.len > YAC_STORAGE_MAX_ENTRY_LEN) {
						int compressed_len;
						char *compressed;

						if (buf.len > YAC_ENTRY_MAX_ORIG_LEN) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
							return ret;
						}

						compressed = emalloc(buf.len * 1.05);
						compressed_len = fastlz_compress(buf.c, buf.len, compressed);
						if (!compressed_len || compressed_len > buf.len) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Compression failed");
							efree(compressed);
							return ret;
						}

						if (compressed_len > YAC_STORAGE_MAX_ENTRY_LEN) {
							php_error_docref(NULL TSRMLS_CC, E_WARNING, "Value is too big to be stored");
							efree(compressed);
							return ret;
						}

						flag |= YAC_ENTRY_COMPRESSED;
						flag |= (buf.len << YAC_ENTRY_ORIG_LEN_SHIT);
						ret = yac_storage_update(key, len, compressed, compressed_len, flag, ttl, add, tv);
						efree(compressed);
					} else {
						ret = yac_storage_update(key, len, buf.c, buf.len, flag, ttl, add, tv);
					}
					smart_str_free(&buf);
				} else {
					php_error_docref(NULL TSRMLS_CC, E_WARNING, "Serialization failed");
					smart_str_free(&buf);
				}
			}
			break;
		case IS_RESOURCE:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type 'IS_RESOURCE' cannot be stored");
			break;
		default:
			php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unsupported valued type to be stored '%d'", flag);
			break;
	}

	return ret;
}
/* }}} */

static int yac_add_multi_impl(char *prefix, uint prefix_len, zval *kvs, int ttl, int add TSRMLS_DC) /* {{{ */ {
	HashTable *ht = Z_ARRVAL_P(kvs);

	for (zend_hash_internal_pointer_reset(ht);
			zend_hash_has_more_elements(ht) == SUCCESS;
			zend_hash_move_forward(ht)) {
		char *key;
		ulong idx;
		zval **value;
		uint len, should_free = 0;

		if (zend_hash_get_current_data(ht, (void **)&value) == FAILURE) {
			continue;
		}

		switch (zend_hash_get_current_key_ex(ht, &key, &len, &idx, 0, NULL)) {
			case HASH_KEY_IS_LONG:
				len = spprintf(&key, 0, "%lu", idx) + 1;
				should_free = 1;
			case HASH_KEY_IS_STRING:
				if (yac_add_impl(prefix, prefix_len, key, len - 1, *value, ttl, add TSRMLS_CC)) {
					if (should_free) {
						efree(key);
					}
					continue;
				} else {
					if (should_free) {
						efree(key);
					}
					return 0;
				}
			default:
				continue;
		}
	}

	return 1;
}