MemManager.cpp 3.9 KB
Newer Older
1
#include <faiss/AutoTune.h>
2
#include <iostream>
X
Xu Peng 已提交
3 4
#include <sstream>
#include <thread>
5

6 7
#include <wrapper/Index.h>

X
Xu Peng 已提交
8 9
#include "MemManager.h"
#include "Meta.h"
10 11


X
Xu Peng 已提交
12 13 14
namespace zilliz {
namespace vecwise {
namespace engine {
15

X
Xu Peng 已提交
16 17 18 19 20
MemVectors::MemVectors(const std::shared_ptr<meta::Meta>& meta_ptr,
        const meta::GroupFileSchema& schema, const Options& options)
  : pMeta_(meta_ptr),
    options_(options),
    schema_(schema),
21
    _pIdGenerator(new SimpleIDGenerator()),
X
Xu Peng 已提交
22
    pIndex_(faiss::index_factory(schema_.dimension, "IDMap,Flat")) {
23 24
}

25
void MemVectors::add(size_t n_, const float* vectors_, IDNumbers& vector_ids_) {
X
Xu Peng 已提交
26
    _pIdGenerator->getNextIDNumbers(n_, vector_ids_);
27
    pIndex_->add_with_ids(n_, vectors_, &vector_ids_[0]);
X
Xu Peng 已提交
28 29 30
    for(auto i=0 ; i<n_; i++) {
        vector_ids_.push_back(i);
    }
31 32 33
}

size_t MemVectors::total() const {
34
    return pIndex_->ntotal;
35 36 37
}

size_t MemVectors::approximate_size() const {
X
Xu Peng 已提交
38
    return total() * schema_.dimension;
39 40
}

41
Status MemVectors::serialize(std::string& group_id) {
X
Xu Peng 已提交
42 43
    /* std::stringstream ss; */
    /* ss << "/tmp/test/" << _pIdGenerator->getNextIDNumber(); */
44 45
    /* faiss::write_index(pIndex_, ss.str().c_str()); */
    /* std::cout << pIndex_->ntotal << std::endl; */
X
Xu Peng 已提交
46
    /* std::cout << _file_location << std::endl; */
47
    /* faiss::write_index(pIndex_, _file_location.c_str()); */
X
Xu Peng 已提交
48 49 50 51 52 53 54
    group_id = schema_.group_id;
    auto rows = approximate_size();
    write_index(pIndex_, schema_.location.c_str());
    schema_.rows = rows;
    schema_.file_type = (rows >= options_.index_trigger_size) ?
        meta::GroupFileSchema::TO_INDEX : meta::GroupFileSchema::RAW;
    pMeta_->update_group_file(schema_);
55
    return Status::OK();
56 57 58 59 60 61 62
}

MemVectors::~MemVectors() {
    if (_pIdGenerator != nullptr) {
        delete _pIdGenerator;
        _pIdGenerator = nullptr;
    }
63 64 65
    if (pIndex_ != nullptr) {
        delete pIndex_;
        pIndex_ = nullptr;
66 67 68 69 70 71 72
    }
}

/*
 * MemManager
 */

X
Xu Peng 已提交
73 74 75 76
VectorsPtr MemManager::get_mem_by_group(const std::string& group_id) {
    auto memIt = _memMap.find(group_id);
    if (memIt != _memMap.end()) {
        return memIt->second;
77
    }
78

79
    meta::GroupFileSchema group_file;
X
Xu Peng 已提交
80 81
    group_file.group_id = group_id;
    auto status = _pMeta->add_group_file(group_file);
82 83 84
    if (!status.ok()) {
        return nullptr;
    }
X
Xu Peng 已提交
85

X
Xu Peng 已提交
86
    _memMap[group_id] = std::shared_ptr<MemVectors>(new MemVectors(_pMeta, group_file, options_));
X
Xu Peng 已提交
87
    return _memMap[group_id];
88 89 90 91 92 93
}

Status MemManager::add_vectors(const std::string& group_id_,
        size_t n_,
        const float* vectors_,
        IDNumbers& vector_ids_) {
94
    std::unique_lock<std::mutex> lock(_mutex);
95
    return add_vectors_no_lock(group_id_, n_, vectors_, vector_ids_);
96 97
}

X
Xu Peng 已提交
98
Status MemManager::add_vectors_no_lock(const std::string& group_id,
99
        size_t n,
100
        const float* vectors,
X
Xu Peng 已提交
101
        IDNumbers& vector_ids) {
X
Xu Peng 已提交
102
    std::shared_ptr<MemVectors> mem = get_mem_by_group(group_id);
103
    if (mem == nullptr) {
X
Xu Peng 已提交
104
        return Status::NotFound("Group " + group_id + " not found!");
105
    }
X
Xu Peng 已提交
106 107 108
    mem->add(n, vectors, vector_ids);

    return Status::OK();
109 110
}

X
Xu Peng 已提交
111
Status MemManager::mark_memory_as_immutable() {
112
    std::unique_lock<std::mutex> lock(_mutex);
X
Xu Peng 已提交
113 114 115
    for (auto& kv: _memMap) {
        _immMems.push_back(kv.second);
    }
X
Xu Peng 已提交
116

X
Xu Peng 已提交
117
    _memMap.clear();
118
    return Status::OK();
X
Xu Peng 已提交
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
}

/* bool MemManager::need_serialize(double interval) { */
/*     if (_immMems.size() > 0) { */
/*         return false; */
/*     } */

/*     auto diff = std::difftime(std::time(nullptr), _last_compact_time); */
/*     if (diff >= interval) { */
/*         return true; */
/*     } */

/*     return false; */
/* } */

134
Status MemManager::serialize(std::vector<std::string>& group_ids) {
X
Xu Peng 已提交
135
    mark_memory_as_immutable();
136 137
    std::string group_id;
    group_ids.clear();
X
Xu Peng 已提交
138
    for (auto& mem : _immMems) {
139 140
        mem->serialize(group_id);
        group_ids.push_back(group_id);
X
Xu Peng 已提交
141 142
    }
    _immMems.clear();
143
    return Status::OK();
X
Xu Peng 已提交
144 145
}

146

X
Xu Peng 已提交
147 148 149
} // namespace engine
} // namespace vecwise
} // namespace zilliz