test_class.declarator: distanceCalculator
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private DistanceCalculator distanceCalculator;
test_class.type: DistanceCalculator
test_class.var_name: distanceCalculator
test_class.declarator: distanceRepository
test_class.modifier: @Mock
      private
test_class.original_string: @Mock
      private DistanceRepository distanceRepository;
test_class.type: DistanceRepository
test_class.var_name: distanceRepository
test_class.declarator: distanceMatrix
test_class.modifier: @InjectMocks
      private
test_class.original_string: @InjectMocks
      private DistanceMatrixImpl distanceMatrix;
test_class.type: DistanceMatrixImpl
test_class.var_name: distanceMatrix
test_class.file: optaweb-vehicle-routing-backend/src/test/java/org/optaweb/vehiclerouting/service/distance/DistanceMatrixImplTest.java
test_class.identifier: DistanceMatrixImplTest
test_case.body: @Test
      void should_call_router_and_persist_distances_when_repo_is_empty() {
          Location l1 = location(100, -1);
          Location l2 = location(111, 20);
          long dist12 = 12;
          long dist21 = 21;
          when(distanceRepository.getDistance(any(), any())).thenReturn(-1L);
          when(distanceCalculator.travelTimeMillis(l1.coordinates(), l2.coordinates())).thenReturn(dist12);
          when(distanceCalculator.travelTimeMillis(l2.coordinates(), l1.coordinates())).thenReturn(dist21);
  
          // no calculation for the first location
          distanceMatrix.addLocation(l1);
          verifyNoInteractions(distanceCalculator);
          verifyNoInteractions(distanceRepository);
  
          distanceMatrix.addLocation(l2);
  
          // getting distances from the repository (unsuccessful)
          verify(distanceRepository).getDistance(l2, l1);
          verify(distanceRepository).getDistance(l1, l2);
  
          // distances are calculated and persisted
          verify(distanceRepository).saveDistance(l2, l1, dist21);
          verify(distanceRepository).saveDistance(l1, l2, dist12);
      }
test_case.class_method_signature: DistanceMatrixImplTest.should_call_router_and_persist_distances_when_repo_is_empty()
test_case.full_signature: @Test void should_call_router_and_persist_distances_when_repo_is_empty()
test_case.identifier: should_call_router_and_persist_distances_when_repo_is_empty
test_case.invocations: location location thenReturn when getDistance any any thenReturn when travelTimeMillis coordinates coordinates thenReturn when travelTimeMillis coordinates coordinates addLocation verifyNoInteractions verifyNoInteractions addLocation getDistance verify getDistance verify saveDistance verify saveDistance verify
test_case.modifiers: @Test
test_case.parameters: ()
test_case.return: void
test_case.signature: void should_call_router_and_persist_distances_when_repo_is_empty()
focal_class.declarator: distanceCalculator
focal_class.modifier: private final
focal_class.original_string: private final DistanceCalculator distanceCalculator;
focal_class.type: DistanceCalculator
focal_class.var_name: distanceCalculator
focal_class.declarator: distanceRepository
focal_class.modifier: private final
focal_class.original_string: private final DistanceRepository distanceRepository;
focal_class.type: DistanceRepository
focal_class.var_name: distanceRepository
focal_class.declarator: matrix = new HashMap<>()
focal_class.modifier: private final
focal_class.original_string: private final Map<Location, Map<Long, Distance>> matrix = new HashMap<>();
focal_class.type: Map<Location, Map<Long, Distance>>
focal_class.var_name: matrix
focal_class.file: optaweb-vehicle-routing-backend/src/main/java/org/optaweb/vehiclerouting/service/distance/DistanceMatrixImpl.java
focal_class.identifier: DistanceMatrixImpl
focal_class.interfaces: implements DistanceMatrix
focal_class.class_method_signature: DistanceMatrixImpl.DistanceMatrixImpl(DistanceCalculator distanceCalculator, DistanceRepository distanceRepository)
focal_class.full_signature: @Autowired  DistanceMatrixImpl(DistanceCalculator distanceCalculator, DistanceRepository distanceRepository)
focal_class.identifier: DistanceMatrixImpl
focal_class.modifiers: @Autowired
focal_class.parameters: (DistanceCalculator distanceCalculator, DistanceRepository distanceRepository)
focal_class.signature:  DistanceMatrixImpl(DistanceCalculator distanceCalculator, DistanceRepository distanceRepository)
focal_class.class_method_signature: DistanceMatrixImpl.addLocation(Location newLocation)
focal_class.full_signature: @Override public DistanceMatrixRow addLocation(Location newLocation)
focal_class.identifier: addLocation
focal_class.modifiers: @Override public
focal_class.parameters: (Location newLocation)
focal_class.return: DistanceMatrixRow
focal_class.signature: DistanceMatrixRow addLocation(Location newLocation)
focal_class.class_method_signature: DistanceMatrixImpl.calculateOrRestoreDistance(Location from, Location to)
focal_class.full_signature: private Distance calculateOrRestoreDistance(Location from, Location to)
focal_class.identifier: calculateOrRestoreDistance
focal_class.modifiers: private
focal_class.parameters: (Location from, Location to)
focal_class.return: Distance
focal_class.signature: Distance calculateOrRestoreDistance(Location from, Location to)
focal_class.class_method_signature: DistanceMatrixImpl.removeLocation(Location location)
focal_class.full_signature: @Override public void removeLocation(Location location)
focal_class.identifier: removeLocation
focal_class.modifiers: @Override public
focal_class.parameters: (Location location)
focal_class.return: void
focal_class.signature: void removeLocation(Location location)
focal_class.class_method_signature: DistanceMatrixImpl.clear()
focal_class.full_signature: @Override public void clear()
focal_class.identifier: clear
focal_class.modifiers: @Override public
focal_class.parameters: ()
focal_class.return: void
focal_class.signature: void clear()
focal_class.class_method_signature: DistanceMatrixImpl.dimension()
focal_class.full_signature: public int dimension()
focal_class.identifier: dimension
focal_class.modifiers: public
focal_class.parameters: ()
focal_class.return: int
focal_class.signature: int dimension()
focal_method.body: @Override
      public DistanceMatrixRow addLocation(Location newLocation) {
          // Matrix == distance rows.
          // We're adding a whole new row with distances from the new location to existing ones.
          // We're also creating a new column by "appending" a new cell to each existing row.
          // This new column contains distances from each existing location to the new one.
  
          // The map must be thread-safe because:
          // - we're updating it from the parallel stream below
          // - it is accessed from solver thread!
          Map<Long, Distance> distancesToOthers = new ConcurrentHashMap<>(); // the new row
  
          // distance to self is 0
          distancesToOthers.put(newLocation.id(), Distance.ZERO);
  
          // For all entries (rows) in the matrix:
          matrix.entrySet().stream().parallel().forEach(distanceRow -> {
              // Entry key is the existing (other) location.
              Location other = distanceRow.getKey();
              // Entry value is the data (cells) in the row (distances from the entry key location to any other).
              Map<Long, Distance> distancesFromOther = distanceRow.getValue();
              // Add a new cell to the row with the distance from the entry key location to the new location
              // (results in a new column at the end of the loop).
              distancesFromOther.put(newLocation.id(), calculateOrRestoreDistance(other, newLocation));
              // Add a cell to the new distance's row.
              distancesToOthers.put(other.id(), calculateOrRestoreDistance(newLocation, other));
          });
  
          matrix.put(newLocation, distancesToOthers);
  
          return locationId -> {
              if (!distancesToOthers.containsKey(locationId)) {
                  throw new IllegalArgumentException(
                          "Distance from " + newLocation
                                  + " to " + locationId
                                  + " hasn't been recorded.\n"
                                  + "We only know distances to " + distancesToOthers.keySet());
              }
              return distancesToOthers.get(locationId);
          };
      }
focal_method.class_method_signature: DistanceMatrixImpl.addLocation(Location newLocation)
focal_method.full_signature: @Override public DistanceMatrixRow addLocation(Location newLocation)
focal_method.identifier: addLocation
focal_method.invocations: put id forEach parallel stream entrySet getKey getValue put id calculateOrRestoreDistance put id calculateOrRestoreDistance put containsKey keySet get
focal_method.modifiers: @Override public
focal_method.parameters: (Location newLocation)
focal_method.return: DistanceMatrixRow
focal_method.signature: DistanceMatrixRow addLocation(Location newLocation)