XCache is a fast, stable PHP opcode cacher that has been proven and is now running on production servers under high load. https://xcache.lighttpd.net/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

149 lines
4.0 KiB

  1. #ifndef XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
  2. #define XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B
  3. #if _MSC_VER > 1000
  4. #pragma once
  5. #endif /* _MSC_VER > 1000 */
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include <assert.h>
  9. typedef struct {
  10. void *data_;
  11. size_t size_;
  12. size_t capacity_;
  13. size_t data_size_;
  14. int persistent_;
  15. } xc_vector_t;
  16. #define xc_vector_initializer(type, persistent) { \
  17. NULL, \
  18. 0, \
  19. 0, \
  20. \
  21. sizeof(type), \
  22. persistent, \
  23. }
  24. #define xc_vector_init_ex(type, vector, data, size, persistent) do { \
  25. (vector)->data_ = data; \
  26. (vector)->size_ = (vector)->capacity_ = size; \
  27. (vector)->data_size_ = sizeof(type); \
  28. (vector)->persistent_ = persistent; \
  29. } while (0)
  30. #define xc_vector_init(type, vector) xc_vector_init_ex(type, vector, NULL, 0, 0)
  31. #define xc_vector_init_persistent(type, vector) xc_vector_init_ex(type, vector, NULL, 0, 1)
  32. static inline void xc_vector_destroy_impl(xc_vector_t *vector TSRMLS_DC)
  33. {
  34. vector->size_ = 0;
  35. if (vector->data_) {
  36. pefree(vector->data_, vector->persistent_);
  37. vector->data_ = NULL;
  38. }
  39. vector->capacity_ = 0;
  40. vector->data_size_ = 0;
  41. }
  42. #define xc_vector_destroy(vector) xc_vector_destroy_impl(vector TSRMLS_CC)
  43. #define xc_vector_clear(vector) do { (vector)->size_ = 0; } while (0)
  44. #define xc_vector_size(vector) ((vector)->size_)
  45. #define xc_vector_initialized(vector) ((vector)->data_size_ != 0)
  46. #define xc_vector_element_ptr_(vector, index) ( \
  47. (void *) ( \
  48. ((char *) (vector)->data_) + (index) * (vector)->data_size_ \
  49. ) \
  50. )
  51. static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
  52. {
  53. assert(vector->data_size_ = data_size);
  54. return vector;
  55. }
  56. #define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data_)
  57. static void xc_vector_reserve_impl(xc_vector_t *vector, size_t capacity TSRMLS_DC)
  58. {
  59. assert(capacity);
  60. if (!vector->capacity_) {
  61. vector->capacity_ = 8;
  62. }
  63. while (vector->capacity_ <= capacity) {
  64. vector->capacity_ <<= 1;
  65. }
  66. vector->data_ = perealloc(vector->data_, vector->data_size_ * vector->capacity_, vector->persistent_);
  67. }
  68. #define xc_vector_reserve(vector, capacity) xc_vector_reserve_impl(vector, capacity TSRMLS_CC)
  69. static void xc_vector_resize_impl(xc_vector_t *vector, size_t size TSRMLS_DC)
  70. {
  71. assert(size);
  72. xc_vector_reserve(vector, size);
  73. vector->size_ = size;
  74. }
  75. #define xc_vector_resize(vector, size) xc_vector_resize_impl(vector, size TSRMLS_CC)
  76. static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
  77. {
  78. if (vector->size_ == vector->capacity_) {
  79. if (vector->capacity_) {
  80. vector->capacity_ <<= 1;
  81. }
  82. else {
  83. vector->capacity_ = 8;
  84. }
  85. vector->data_ = perealloc(vector->data_, vector->data_size_ * vector->capacity_, vector->persistent_);
  86. }
  87. }
  88. #define xc_vector_push_back(vector, value_ptr) do { \
  89. xc_vector_check_reserve_(vector TSRMLS_CC); \
  90. memcpy(xc_vector_element_ptr_(vector, (vector)->size_++), value_ptr, (vector)->data_size_); \
  91. } while (0)
  92. static inline void *xc_vector_detach_impl(xc_vector_t *vector)
  93. {
  94. void *data = vector->data_;
  95. vector->data_ = NULL;
  96. vector->capacity_ = 0;
  97. vector->size_ = 0;
  98. return data;
  99. }
  100. #define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
  101. static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
  102. {
  103. assert(vector);
  104. assert(vector->data_size_ == data_size);
  105. assert(vector->capacity_ > 0);
  106. return vector;
  107. }
  108. #define xc_vector_pop_back(type, vector) xc_vector_data(type, \
  109. xc_vector_pop_back_check_(vector, sizeof(type)) \
  110. )[--(vector)->size_]
  111. static inline void xc_vector_reverse(xc_vector_t *vector)
  112. {
  113. char *left, *right;
  114. void *tmp;
  115. assert(vector);
  116. assert(vector->data_size_);
  117. tmp = alloca(vector->data_size_);
  118. for (left = vector->data_, right = xc_vector_element_ptr_(vector, vector->size_ - 1); left < right; left += vector->data_size_, right -= vector->data_size_) {
  119. memcpy(tmp, left, vector->data_size_);
  120. memcpy(left, right, vector->data_size_);
  121. memcpy(right, tmp, vector->data_size_);
  122. }
  123. }
  124. #endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */