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.

125 lines
3.1 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. size_t size;
  11. void *data;
  12. size_t capacity;
  13. size_t data_size;
  14. int persistent;
  15. } xc_vector_t;
  16. #define xc_vector_initializer(type, persistent_) { \
  17. 0, \
  18. NULL, \
  19. \
  20. 0, \
  21. sizeof(type), \
  22. persistent_, \
  23. }
  24. #define xc_vector_init(type, vector, persistent_) do { \
  25. (vector)->size = 0; \
  26. (vector)->data = NULL; \
  27. \
  28. (vector)->capacity = 0; \
  29. (vector)->data_size = sizeof(type); \
  30. (vector)->persistent = persistent_; \
  31. } while (0)
  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_size(vector) ((vector)->size)
  44. #define xc_vector_initialized(vector) ((vector)->data_size != 0)
  45. #define xc_vector_element_ptr_(vector, index) ( \
  46. (void *) ( \
  47. ((char *) (vector)->data) + (index) * (vector)->data_size \
  48. ) \
  49. )
  50. static inline xc_vector_t *xc_vector_check_type_(xc_vector_t *vector, size_t data_size)
  51. {
  52. assert(vector->data_size = data_size);
  53. return vector;
  54. }
  55. #define xc_vector_data(type, vector) ((type *) xc_vector_check_type_(vector, sizeof(type))->data)
  56. static inline void xc_vector_check_reserve_(xc_vector_t *vector TSRMLS_DC)
  57. {
  58. if (vector->size == vector->capacity) {
  59. if (vector->capacity) {
  60. vector->capacity <<= 1;
  61. vector->data = perealloc(vector->data, vector->data_size * vector->capacity, vector->persistent);
  62. }
  63. else {
  64. vector->capacity = 8;
  65. vector->data = pemalloc(vector->data_size * vector->capacity, vector->persistent);
  66. }
  67. }
  68. }
  69. #define xc_vector_push_back(vector, value_ptr) do { \
  70. xc_vector_check_reserve_(vector TSRMLS_CC); \
  71. memcpy(xc_vector_element_ptr_(vector, (vector)->size++), value_ptr, (vector)->data_size); \
  72. } while (0)
  73. static inline void *xc_vector_detach_impl(xc_vector_t *vector)
  74. {
  75. void *data = vector->data;
  76. vector->data = NULL;
  77. vector->capacity = 0;
  78. vector->size = 0;
  79. return data;
  80. }
  81. #define xc_vector_detach(type, vector) ((type *) xc_vector_detach_impl(xc_vector_check_type_(vector, sizeof(type))))
  82. static inline xc_vector_t *xc_vector_pop_back_check_(xc_vector_t *vector, size_t data_size)
  83. {
  84. assert(vector);
  85. assert(vector->data_size == data_size);
  86. assert(vector->capacity > 0);
  87. return vector;
  88. }
  89. #define xc_vector_pop_back(type, vector) xc_vector_data(type, \
  90. xc_vector_pop_back_check_(vector, sizeof(type)) \
  91. )[--(vector)->size]
  92. static inline void xc_vector_reverse(xc_vector_t *vector)
  93. {
  94. char *left, *right;
  95. void *tmp;
  96. assert(vector);
  97. tmp = alloca(vector->data_size);
  98. for (left = vector->data, right = xc_vector_element_ptr_(vector, vector->size - 1); left < right; left += vector->data_size, right -= vector->data_size) {
  99. memcpy(tmp, left, vector->data_size);
  100. memcpy(left, right, vector->data_size);
  101. memcpy(right, tmp, vector->data_size);
  102. }
  103. }
  104. #endif /* XC_VECTOR_H_0957AC4E1A44E838C7B8DBECFF9C4B3B */