bool scan_manager_t::find_source_names(const std::string& file_hash, source_names_t& source_names) const { if (file_hash.size() == 0) { std::cerr << "Error: find_source_names called with empty file_hash\n"; return false; } // read source_id uint64_t source_id; bool has_id = lmdb_source_id_manager->find(file_hash, source_id); if (has_id == false) { // no source ID for this file_hash source_names.clear(); return false; } else { // source return lmdb_source_name_manager->find(source_id, source_names); } }
/** * Find source names, false on no source ID. */ bool find(const uint64_t source_id, source_names_t& names) const { // get context hashdb::lmdb_context_t context(env, false, true); context.open(); // set key uint8_t key_start[10]; uint8_t* key_p = key_start; key_p = lmdb_helper::encode_uint64_t(source_id, key_p); const size_t key_size = key_p - key_start; context.key.mv_size = key_size; context.key.mv_data = key_start; context.data.mv_size = 0; context.data.mv_data = NULL; // set the cursor to this key int rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_SET_KEY); #ifdef DEBUG_LMDB_SOURCE_NAME_MANAGER_HPP print_mdb_val("source_name_manager find start at key", context.key); #endif // note if source ID was found bool source_id_found = (rc == 0); // read name pairs while data available and key matches names.clear(); while (rc == 0 && context.key.mv_size == key_size && memcmp(context.key.mv_data, key_start, key_size) == 0) { #ifdef DEBUG_LMDB_SOURCE_NAME_MANAGER_HPP print_mdb_val("source_name_manager find key", context.key); print_mdb_val("source_name_manager find data", context.data); #endif // read repository_name, filename pair into names const uint8_t* p = static_cast<uint8_t*>(context.data.mv_data); const uint8_t* const p_stop = p + context.data.mv_size; uint64_t repository_name_size; const uint8_t* const rn_p = lmdb_helper::decode_uint64_t( p, repository_name_size); p = rn_p + repository_name_size; uint64_t filename_size; const uint8_t* const fn_p = lmdb_helper::decode_uint64_t( p, filename_size); p = fn_p + filename_size; names.insert(source_name_t( std::string(reinterpret_cast<const char*>(rn_p), repository_name_size), std::string(reinterpret_cast<const char*>(fn_p), filename_size))); // validate that the decoding was properly consumed if (p != p_stop) { std::cerr << "data decode error in LMDB source name store\n"; assert(0); } // next rc = mdb_cursor_get(context.cursor, &context.key, &context.data, MDB_NEXT); } // make sure rc is valid if (rc == 0 || rc == MDB_NOTFOUND) { // good, LMDB worked correctly context.close(); return source_id_found; } else { // invalid rc std::cerr << "LMDB error: " << mdb_strerror(rc) << "\n"; assert(0); return false; // for mingw } }