GCC Code Coverage Report


Directory: src/
File: src/types/vec32.h
Date: 2026-09-30 11:11:31
Exec Total Coverage
Lines: 34 34 100.0%
Functions: 7 7 100.0%
Branches: 8 20 40.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2026 Tiger Data, Inc.
3 * Licensed under the PostgreSQL License. See LICENSE for details.
4 *
5 * vec32.h - Vector type compatible with pgvector
6 *
7 * The struct layout is identical to pgvector's Vector type, enabling
8 * zero-copy interoperability when running inside PostgreSQL.
9 */
10
11 #ifndef VEC32_H
12 #define VEC32_H
13
14 #include <stdint.h>
15 #include <string.h>
16
17 #include "core/types.h"
18
19 #define VEC32_MAX_DIM 16000
20
21 /*
22 * Vec32: Binary-compatible with pgvector's Vector type.
23 *
24 * The struct layout is identical in both standalone and PostgreSQL modes.
25 * In standalone mode, vl_len_ stores the total size (not used as varlena).
26 * In PostgreSQL mode, vl_len_ is managed by SET_VARSIZE/VARSIZE macros.
27 */
28 typedef struct Vec32
29 {
30 int32_t vl_len_; /* varlena header / size in standalone mode */
31 int16_t dim; /* number of dimensions */
32 int16_t unused; /* reserved for future use, always zero */
33 float x[]; /* flexible array member */
34 } Vec32;
35
36 #define VEC32_SIZE(dim) (offsetof(Vec32, x) + sizeof(float) * (dim))
37 #define VEC32_DIM(v) ((v)->dim)
38 #define VEC32_DATA(v) ((v)->x)
39
40 /* Convert to Vec32Ref for internal operations */
41 static inline Vec32Ref
42 136540 Vec32ToRef(const Vec32 *v)
43 {
44 136540 return (Vec32Ref){.data = v->x, .dim = (Dimension)v->dim};
45 }
46
47 /* Convert to VectorMut for mutable operations */
48 static inline VectorMut
49 Vec32ToMut(Vec32 *v)
50 {
51 return (VectorMut){.data = v->x, .dim = (Dimension)v->dim};
52 }
53
54 /* Allocation and lifecycle */
55 Vec32 *vec32_create(Dimension dim);
56 Vec32 *vec32_copy(const Vec32 *src);
57 void vec32_free(Vec32 *v);
58
59 /* Initialization */
60 void vec32_set(Vec32 *v, const float *values);
61 void vec32_zero(Vec32 *v);
62 void vec32_fill(Vec32 *v, float value);
63
64 /* Operations */
65 float vec32_dot(const Vec32 *a, const Vec32 *b);
66 float vec32_norm(const Vec32 *v);
67 void vec32_normalize(Vec32 *v);
68
69 /* ----------------------------------------------------------------
70 * Inline vtable for compile-time specialization
71 *
72 * These inline functions + static const vtable enable the
73 * compiler to inline through vtable function pointers when the
74 * pointer target is known at compile time. Used by k-means and
75 * other hot loops that dispatch once at the entry point.
76 * ---------------------------------------------------------------- */
77
78 VS_VTABLE_INLINE float
79 359024 vs_f32_dot_product(const void *vec, const float *centroid, Dimension dim)
80 {
81 359024 const float *v = (const float *)vec;
82 359024 float sum = 0.0f;
83
2/8
✓ Branch 0 taken 2890057 times.
✓ Branch 1 taken 359024 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
3249081 for (Dimension d = 0; d < dim; d++)
84 2890057 sum += v[d] * centroid[d];
85
0/6
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
359024 return sum;
86 }
87
88 VS_VTABLE_INLINE float
89 8002156 vs_f32_l2_squared(const void *vec, const float *centroid, Dimension dim)
90 {
91 8002156 const float *v = (const float *)vec;
92 8002156 float sum = 0.0f;
93
2/2
✓ Branch 0 taken 579590697 times.
✓ Branch 1 taken 8002156 times.
587592853 for (Dimension d = 0; d < dim; d++)
94 {
95 579590697 float diff = v[d] - centroid[d];
96 579590697 sum += diff * diff;
97 }
98 8002156 return sum;
99 }
100
101 VS_VTABLE_INLINE float
102 778198 vs_f32_norm_sq(const void *vec, Dimension dim)
103 {
104 778198 const float *v = (const float *)vec;
105 778198 float sum = 0.0f;
106
2/2
✓ Branch 0 taken 48007104 times.
✓ Branch 1 taken 778198 times.
48785302 for (Dimension d = 0; d < dim; d++)
107 48007104 sum += v[d] * v[d];
108 778198 return sum;
109 }
110
111 VS_VTABLE_INLINE void
112 22800 vs_f32_sum_to_float(const void *vec, float *accum, Dimension dim)
113 {
114 22800 const float *v = (const float *)vec;
115
2/2
✓ Branch 0 taken 136960 times.
✓ Branch 1 taken 22800 times.
159760 for (Dimension d = 0; d < dim; d++)
116 136960 accum[d] += v[d];
117 22800 }
118
119 VS_VTABLE_INLINE void
120 16777 vs_f32_to_float_one(const void *src, float *dst, Dimension dim)
121 {
122 16777 memcpy(dst, src, (size_t)dim * sizeof(float));
123 16777 }
124
125 VS_VTABLE_INLINE const float *
126 780431 vs_f32_to_float_block(
127 const void *src, float *dst, uint32_t count, Dimension dim)
128 {
129 780389 (void)dst;
130 780389 (void)count;
131 780389 (void)dim;
132 780431 return (const float *)src;
133 }
134
135 static const Vec32TypeOps vs_f32_type_ops = {
136 .name = "float32",
137 .element_size = sizeof(float),
138 .dot_product = vs_f32_dot_product,
139 .l2_squared = vs_f32_l2_squared,
140 .norm_sq = vs_f32_norm_sq,
141 .sum_to_float = vs_f32_sum_to_float,
142 .to_float_one = vs_f32_to_float_one,
143 .to_float_block = vs_f32_to_float_block,
144 };
145
146 #endif /* VEC32_H */
147