| 950 | } |
| 951 | |
| 952 | void FindSpans(uint64_t trace_id, std::deque<RpczSpan>* out) { |
| 953 | out->clear(); |
| 954 | butil::intrusive_ptr<SpanDB> db; |
| 955 | if (GetSpanDB(&db) != 0) { |
| 956 | return; |
| 957 | } |
| 958 | leveldb::Iterator* it = db->id_db->NewIterator(leveldb::ReadOptions()); |
| 959 | uint32_t key_data[4]; |
| 960 | ToBigEndian(trace_id, key_data); |
| 961 | ToBigEndian(0, key_data + 2); |
| 962 | leveldb::Slice key((char*)key_data, sizeof(key_data)); |
| 963 | for (it->Seek(key); it->Valid(); it->Next()) { |
| 964 | if (it->key().size() != sizeof(key_data)) { |
| 965 | LOG(ERROR) << "Invalid key size: " << it->key().size(); |
| 966 | break; |
| 967 | } |
| 968 | const uint64_t stored_trace_id = |
| 969 | ToLittleEndian((const uint32_t*)it->key().data()); |
| 970 | if (trace_id != stored_trace_id) { |
| 971 | break; |
| 972 | } |
| 973 | RpczSpan span; |
| 974 | if (span.ParseFromArray(it->value().data(), it->value().size())) { |
| 975 | out->push_back(span); |
| 976 | } else { |
| 977 | LOG(ERROR) << "Fail to parse from value"; |
| 978 | } |
| 979 | } |
| 980 | delete it; |
| 981 | } |
| 982 | |
| 983 | void ListSpans(int64_t starting_realtime, size_t max_scan, |
| 984 | std::deque<BriefSpan>* out, SpanFilter* filter) { |
no test coverage detected