| 194 | } |
| 195 | |
| 196 | func GetPath(startRoomId int, endRoomId ...int) ([]pathStep, error) { |
| 197 | |
| 198 | start := time.Now() |
| 199 | defer func() { |
| 200 | util.TrackTime(`mapper.GetPath()`, time.Since(start).Seconds()) |
| 201 | }() |
| 202 | |
| 203 | if len(endRoomId) == 0 { |
| 204 | return []pathStep{}, fmt.Errorf("%d => %d (endRoom not found): %w", startRoomId, endRoomId, ErrPathNotFound) |
| 205 | } |
| 206 | |
| 207 | startRoom := rooms.LoadRoom(startRoomId) |
| 208 | if startRoom == nil { |
| 209 | return []pathStep{}, fmt.Errorf("%d => %d (startRoom not found): %w", startRoomId, endRoomId, ErrPathNotFound) |
| 210 | } |
| 211 | |
| 212 | m := GetMapper(startRoom.RoomId) |
| 213 | if m == nil { |
| 214 | return []pathStep{}, fmt.Errorf("%d => %d (mapper not fond): %w", startRoomId, endRoomId, ErrPathNotFound) |
| 215 | } |
| 216 | |
| 217 | cacheKey := pathCacheKey{} |
| 218 | rNow := startRoomId |
| 219 | finalPath := []pathStep{} |
| 220 | for _, roomId := range endRoomId { |
| 221 | |
| 222 | if rNow == roomId { // Avoid repeating id's |
| 223 | continue |
| 224 | } |
| 225 | |
| 226 | cacheKey.startRoomId = rNow |
| 227 | cacheKey.endRoomId = roomId |
| 228 | |
| 229 | if pCache, ok := pathCache.Get(cacheKey); ok { |
| 230 | pathCacheHits.Add(1) |
| 231 | |
| 232 | if pCache.err != nil { |
| 233 | return pCache.steps, fmt.Errorf("%d => %d: %w", rNow, roomId, pCache.err) |
| 234 | } |
| 235 | |
| 236 | finalPath = append(finalPath, pCache.steps...) |
| 237 | rNow = roomId |
| 238 | continue |
| 239 | } |
| 240 | |
| 241 | pathCacheMisses.Add(1) |
| 242 | |
| 243 | if !m.HasRoom(roomId) { |
| 244 | err := fmt.Errorf("%d => %d (room not in mapper): %w", rNow, roomId, ErrPathNotFound) |
| 245 | pathCache.Add(cacheKey, pathCacheValue{steps: nil, err: err}) |
| 246 | return []pathStep{}, err |
| 247 | } |
| 248 | |
| 249 | p, err := m.findPath(rNow, roomId) |
| 250 | if err != nil { |
| 251 | pathCache.Add(cacheKey, pathCacheValue{steps: p, err: err}) |
| 252 | return []pathStep{}, fmt.Errorf("%d => %d: %w", rNow, roomId, ErrPathNotFound) |
| 253 | } |