/* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst' * with miniflow_destroy(). */ void miniflow_init(struct miniflow *dst, const struct flow *src) { const uint32_t *src_u32 = (const uint32_t *) src; unsigned int ofs; unsigned int i; int n; /* Initialize dst->map, counting the number of nonzero elements. */ n = 0; memset(dst->map, 0, sizeof dst->map); for (i = 0; i < FLOW_U32S; i++) { if (src_u32[i]) { dst->map[i / 32] |= 1u << (i % 32); n++; } } /* Initialize dst->values. */ dst->values = miniflow_alloc_values(dst, n); ofs = 0; for (i = 0; i < MINI_N_MAPS; i++) { uint32_t map; for (map = dst->map[i]; map; map = zero_rightmost_1bit(map)) { dst->values[ofs++] = src_u32[raw_ctz(map) + i * 32]; } } }
/* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst' * with miniflow_destroy(). */ void miniflow_clone(struct miniflow *dst, const struct miniflow *src) { int n = miniflow_n_values(src); memcpy(dst->map, src->map, sizeof dst->map); dst->values = miniflow_alloc_values(dst, n); memcpy(dst->values, src->values, n * sizeof *dst->values); }
/* Completes an initialization of 'dst' as a miniflow copy of 'src' begun by * the caller. The caller must have already initialized 'dst->map' properly * to indicate the nonzero uint32_t elements of 'src'. 'n' must be the number * of 1-bits in 'dst->map'. * * This function initializes 'dst->values' (either inline if possible or with * malloc() otherwise) and copies the nonzero uint32_t elements of 'src' into * it. */ static void miniflow_init__(struct miniflow *dst, const struct flow *src, int n) { const uint32_t *src_u32 = (const uint32_t *) src; unsigned int ofs; int i; dst->values = miniflow_alloc_values(dst, n); ofs = 0; for (i = 0; i < MINI_N_MAPS; i++) { uint32_t map; for (map = dst->map[i]; map; map = zero_rightmost_1bit(map)) { dst->values[ofs++] = src_u32[raw_ctz(map) + i * 32]; } } }