| 19 | namespace vsag::eval { |
| 20 | |
| 21 | void |
| 22 | parse_sparse_vectors(const char* src_data, |
| 23 | size_t data_size, |
| 24 | std::vector<SparseVector>& parsed_vectors, |
| 25 | int64_t& max_len) { |
| 26 | // parse the sparse vectors with ordered keys |
| 27 | const char* ptr = src_data; |
| 28 | const char* end = src_data + data_size; |
| 29 | while (ptr < end) { |
| 30 | SparseVector vec; |
| 31 | |
| 32 | if (ptr + sizeof(uint32_t) > end) |
| 33 | break; |
| 34 | memcpy(&vec.len_, ptr, sizeof(uint32_t)); |
| 35 | ptr += sizeof(uint32_t); |
| 36 | |
| 37 | if (vec.len_ == 0) { |
| 38 | parsed_vectors.push_back(vec); |
| 39 | continue; |
| 40 | } |
| 41 | max_len = std::max(max_len, static_cast<int64_t>(vec.len_)); |
| 42 | |
| 43 | const size_t keys_size = vec.len_ * sizeof(uint32_t); |
| 44 | const size_t vals_size = vec.len_ * sizeof(float); |
| 45 | |
| 46 | if (ptr + keys_size + vals_size > end) |
| 47 | break; |
| 48 | |
| 49 | vec.ids_ = new uint32_t[vec.len_]; |
| 50 | vec.vals_ = new float[vec.len_]; |
| 51 | |
| 52 | memcpy(vec.ids_, ptr, keys_size); |
| 53 | ptr += keys_size; |
| 54 | |
| 55 | memcpy(vec.vals_, ptr, vals_size); |
| 56 | ptr += vals_size; |
| 57 | |
| 58 | std::vector<uint32_t> indices(vec.len_); |
| 59 | for (uint32_t i = 0; i < vec.len_; ++i) indices[i] = i; |
| 60 | |
| 61 | std::sort(indices.begin(), indices.end(), [&](uint32_t a, uint32_t b) { |
| 62 | return vec.ids_[a] < vec.ids_[b]; |
| 63 | }); |
| 64 | |
| 65 | auto* sorted_ids = new uint32_t[vec.len_]; |
| 66 | auto* sorted_vals = new float[vec.len_]; |
| 67 | |
| 68 | for (uint32_t i = 0; i < vec.len_; ++i) { |
| 69 | sorted_ids[i] = vec.ids_[indices[i]]; |
| 70 | sorted_vals[i] = vec.vals_[indices[i]]; |
| 71 | } |
| 72 | |
| 73 | delete[] vec.ids_; |
| 74 | delete[] vec.vals_; |
| 75 | vec.ids_ = sorted_ids; |
| 76 | vec.vals_ = sorted_vals; |
| 77 | |
| 78 | parsed_vectors.push_back(vec); |