comparison OrthancServer/ServerIndex.cpp @ 3027:fd587cf51a89 db-changes

cont
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 18 Dec 2018 12:50:27 +0100
parents 039a9d262d64
children ea653ec47f31
comparison
equal deleted inserted replaced
3025:039a9d262d64 3027:fd587cf51a89
297 return publicId_; 297 return publicId_;
298 } 298 }
299 }; 299 };
300 300
301 301
302 class ServerIndex::MainDicomTagsRegistry : public boost::noncopyable
303 {
304 private:
305 class TagInfo
306 {
307 private:
308 ResourceType level_;
309 DicomTagType type_;
310
311 public:
312 TagInfo()
313 {
314 }
315
316 TagInfo(ResourceType level,
317 DicomTagType type) :
318 level_(level),
319 type_(type)
320 {
321 }
322
323 ResourceType GetLevel() const
324 {
325 return level_;
326 }
327
328 DicomTagType GetType() const
329 {
330 return type_;
331 }
332 };
333
334 typedef std::map<DicomTag, TagInfo> Registry;
335
336
337 Registry registry_;
338
339 void LoadTags(ResourceType level)
340 {
341 const DicomTag* tags = NULL;
342 size_t size;
343
344 ServerToolbox::LoadIdentifiers(tags, size, level);
345
346 for (size_t i = 0; i < size; i++)
347 {
348 if (registry_.find(tags[i]) == registry_.end())
349 {
350 registry_[tags[i]] = TagInfo(level, DicomTagType_Identifier);
351 }
352 else
353 {
354 // These patient-level tags are copied in the study level
355 assert(level == ResourceType_Study &&
356 (tags[i] == DICOM_TAG_PATIENT_ID ||
357 tags[i] == DICOM_TAG_PATIENT_NAME ||
358 tags[i] == DICOM_TAG_PATIENT_BIRTH_DATE));
359 }
360 }
361
362 DicomMap::LoadMainDicomTags(tags, size, level);
363
364 for (size_t i = 0; i < size; i++)
365 {
366 if (registry_.find(tags[i]) == registry_.end())
367 {
368 registry_[tags[i]] = TagInfo(level, DicomTagType_Main);
369 }
370 }
371 }
372
373 public:
374 MainDicomTagsRegistry()
375 {
376 LoadTags(ResourceType_Patient);
377 LoadTags(ResourceType_Study);
378 LoadTags(ResourceType_Series);
379 LoadTags(ResourceType_Instance);
380 }
381
382 void LookupTag(ResourceType& level,
383 DicomTagType& type,
384 const DicomTag& tag) const
385 {
386 Registry::const_iterator it = registry_.find(tag);
387
388 if (it == registry_.end())
389 {
390 // Default values
391 level = ResourceType_Instance;
392 type = DicomTagType_Generic;
393 }
394 else
395 {
396 level = it->second.GetLevel();
397 type = it->second.GetType();
398 }
399 }
400 };
401
402
302 bool ServerIndex::DeleteResource(Json::Value& target, 403 bool ServerIndex::DeleteResource(Json::Value& target,
303 const std::string& uuid, 404 const std::string& uuid,
304 ResourceType expectedType) 405 ResourceType expectedType)
305 { 406 {
306 boost::mutex::scoped_lock lock(mutex_); 407 boost::mutex::scoped_lock lock(mutex_);
539 unsigned int threadSleep) : 640 unsigned int threadSleep) :
540 done_(false), 641 done_(false),
541 db_(db), 642 db_(db),
542 maximumStorageSize_(0), 643 maximumStorageSize_(0),
543 maximumPatients_(0), 644 maximumPatients_(0),
544 overwrite_(false) 645 overwrite_(false),
646 mainDicomTagsRegistry_(new MainDicomTagsRegistry)
545 { 647 {
546 listener_.reset(new Listener(context)); 648 listener_.reset(new Listener(context));
547 db_.SetListener(*listener_); 649 db_.SetListener(*listener_);
548 650
549 // Initial recycling if the parameters have changed since the last 651 // Initial recycling if the parameters have changed since the last
2452 LOG(ERROR) << "EXCEPTION [" << e.What() << "]"; 2554 LOG(ERROR) << "EXCEPTION [" << e.What() << "]";
2453 } 2555 }
2454 } 2556 }
2455 2557
2456 2558
2559 void ServerIndex::NormalizeLookup(DatabaseLookup& target,
2560 const DatabaseLookup& source,
2561 ResourceType queryLevel) const
2562 {
2563 assert(mainDicomTagsRegistry_.get() != NULL);
2564
2565 for (size_t i = 0; i < source.GetConstraintsCount(); i++)
2566 {
2567 const DicomTagConstraint& constraint = source.GetConstraint(i);
2568
2569 ResourceType tagLevel;
2570 DicomTagType tagType;
2571 mainDicomTagsRegistry_->LookupTag(tagLevel, tagType, constraint.GetTag());
2572
2573 if (IsResourceLevelAboveOrEqual(tagLevel, queryLevel) &&
2574 (tagType == DicomTagType_Identifier ||
2575 tagType == DicomTagType_Main))
2576 {
2577 if (tagType == DicomTagType_Identifier)
2578 {
2579 if (constraint.GetConstraintType() == ConstraintType_List)
2580 {
2581 if (!constraint.GetValues().empty())
2582 {
2583 std::auto_ptr<DicomTagConstraint> normalized(
2584 new DicomTagConstraint(constraint.GetTag(),
2585 ConstraintType_List, true,
2586 constraint.IsMandatory()));
2587
2588 normalized->SetTagType(tagType);
2589
2590 for (std::set<std::string>::const_iterator
2591 value = constraint.GetValues().begin();
2592 value != constraint.GetValues().end(); ++value)
2593 {
2594 normalized->AddValue(ServerToolbox::NormalizeIdentifier(*value));
2595 }
2596
2597 target.AddConstraint(normalized.release());
2598 }
2599 }
2600 else
2601 {
2602 std::string value = ServerToolbox::NormalizeIdentifier(constraint.GetValue());
2603
2604 std::auto_ptr<DicomTagConstraint> normalized(
2605 new DicomTagConstraint(constraint.GetTag(),
2606 constraint.GetConstraintType(),
2607 value, true,
2608 constraint.IsMandatory()));
2609
2610 normalized->SetTagType(tagType);
2611 target.AddConstraint(normalized.release());
2612 }
2613 }
2614 else if (tagType == DicomTagType_Main)
2615 {
2616 std::auto_ptr<DicomTagConstraint> clone(constraint.Clone());
2617 clone->SetTagType(tagType);
2618 target.AddConstraint(clone.release());
2619 }
2620 else if (tagType == DicomTagType_Generic)
2621 {
2622 // This tag is not indexed in the database, skip it
2623 }
2624 else
2625 {
2626 throw OrthancException(ErrorCode_InternalError);
2627 }
2628 }
2629 }
2630 }
2631
2632
2457 void ServerIndex::ApplyLookupPatients(std::vector<std::string>& patientsId, 2633 void ServerIndex::ApplyLookupPatients(std::vector<std::string>& patientsId,
2458 std::vector<std::string>& instancesId, 2634 std::vector<std::string>& instancesId,
2459 const DatabaseLookup& lookup, 2635 const DatabaseLookup& lookup,
2460 size_t limit) 2636 size_t limit)
2461 { 2637 {
2462 boost::mutex::scoped_lock lock(mutex_); 2638 DatabaseLookup normalized;
2463 2639 NormalizeLookup(normalized, lookup, ResourceType_Patient);
2464 db_.ApplyLookupPatients(patientsId, lookup, limit); 2640
2465 db_.FindOneChildInstance(instancesId, patientsId, ResourceType_Patient); 2641 {
2642 boost::mutex::scoped_lock lock(mutex_);
2643 db_.ApplyLookupPatients(patientsId, instancesId, normalized, limit);
2644 }
2466 } 2645 }
2467 2646
2468 2647
2469 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId, 2648 void ServerIndex::ApplyLookupResources(std::vector<std::string>& resourcesId,
2470 std::vector<std::string>& instancesId, 2649 std::vector<std::string>& instancesId,
2471 const DatabaseLookup& lookup, 2650 const DatabaseLookup& lookup,
2472 ResourceType queryLevel, 2651 ResourceType queryLevel,
2473 size_t limit) 2652 size_t limit)
2474 { 2653 {
2475 boost::mutex::scoped_lock lock(mutex_); 2654 DatabaseLookup normalized;
2476 2655 NormalizeLookup(normalized, lookup, queryLevel);
2477 db_.ApplyLookupResources(resourcesId, lookup, queryLevel, limit); 2656
2478 db_.FindOneChildInstance(instancesId, resourcesId, queryLevel); 2657 {
2658 boost::mutex::scoped_lock lock(mutex_);
2659 db_.ApplyLookupResources(resourcesId, instancesId, normalized, queryLevel, limit);
2660 }
2479 } 2661 }
2480 } 2662 }