Skip to content

Commit

Permalink
fix(app): remove some dangerous reverse()s (#16591)
Browse files Browse the repository at this point in the history
There weer a couple command texts that were doing a `.reverse()` of the
commands array. This is O(N) which is gross and also might be cached
which would cause bugs, so replace it with some uses of findLast() that
definitely weren't inspired by wanting to do some fun typing exercises.

## testing
- [x] tests pass, really
  • Loading branch information
sfoster1 authored Oct 24, 2024
1 parent d454914 commit d907591
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 31 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,25 @@
import type { LabwareLocation, RunTimeCommand } from '@opentrons/shared-data'
import type {
LabwareLocation,
RunTimeCommand,
LoadLabwareRunTimeCommand,
MoveLabwareRunTimeCommand,
} from '@opentrons/shared-data'

const findLastAt = <T, U extends T = T>(
arr: readonly T[],
pred: ((el: T) => boolean) | ((el: T) => el is U)
): [U, number] | [undefined, -1] => {
let arrayLoc = -1
const lastEl = arr.findLast((el: T, idx: number): el is U => {
arrayLoc = idx
return pred(el)
})
if (lastEl === undefined) {
return [undefined, -1]
} else {
return [lastEl, arrayLoc]
}
}

/**
* given a list of commands and a labwareId, calculate the resulting location
Expand All @@ -11,15 +32,22 @@ export function getFinalLabwareLocation(
labwareId: string,
commands: RunTimeCommand[]
): LabwareLocation | null {
for (const c of commands.reverse()) {
if (c.commandType === 'loadLabware' && c.result?.labwareId === labwareId) {
return c.params.location
} else if (
c.commandType === 'moveLabware' &&
c.params.labwareId === labwareId
) {
return c.params.newLocation
}
const [lastMove, lastMoveIndex] = findLastAt(
commands,
(c: RunTimeCommand): c is MoveLabwareRunTimeCommand =>
c.commandType === 'moveLabware' && c.params.labwareId === labwareId
)

const [lastLoad, lastLoadIndex] = findLastAt(
commands,
(c: RunTimeCommand): c is LoadLabwareRunTimeCommand =>
c.commandType === 'loadLabware' && c.result?.labwareId === labwareId
)
if (lastMoveIndex > lastLoadIndex) {
return lastMove?.params?.newLocation ?? null
} else if (lastLoadIndex > lastMoveIndex) {
return lastLoad?.params?.location ?? null
} else {
return null
}
return null
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,42 @@
import { getPipetteNameSpecs } from '@opentrons/shared-data'
import type { PipetteName, RunTimeCommand } from '@opentrons/shared-data'
import type {
PipetteName,
RunTimeCommand,
ConfigureNozzleLayoutRunTimeCommand,
} from '@opentrons/shared-data'

const usedChannelsFromCommand = (
command: ConfigureNozzleLayoutRunTimeCommand | undefined,
defaultChannels: number
): number =>
command?.params?.configurationParams?.style === 'SINGLE'
? 1
: command?.params?.configurationParams?.style === 'COLUMN'
? 8
: defaultChannels

const usedChannelsForPipette = (
pipetteId: string,
commands: RunTimeCommand[],
defaultChannels: number
): number =>
usedChannelsFromCommand(
commands.findLast(
(c: RunTimeCommand): c is ConfigureNozzleLayoutRunTimeCommand =>
c.commandType === 'configureNozzleLayout' &&
c.params?.pipetteId === pipetteId
),
defaultChannels
)

const usedChannels = (
pipetteId: string,
commands: RunTimeCommand[],
pipetteChannels: number
): number =>
pipetteChannels === 96
? usedChannelsForPipette(pipetteId, commands, pipetteChannels)
: pipetteChannels

/**
* @param pipetteName name of pipette being used
Expand All @@ -16,26 +53,10 @@ export function getWellRange(
const pipetteChannels = pipetteName
? getPipetteNameSpecs(pipetteName)?.channels ?? 1
: 1
let usedChannels = pipetteChannels
if (pipetteChannels === 96) {
for (const c of commands.reverse()) {
if (
c.commandType === 'configureNozzleLayout' &&
c.params?.pipetteId === pipetteId
) {
// TODO(sb, 11/9/23): add support for quadrant and row configurations when needed
if (c.params.configurationParams.style === 'SINGLE') {
usedChannels = 1
} else if (c.params.configurationParams.style === 'COLUMN') {
usedChannels = 8
}
break
}
}
}
if (usedChannels === 96) {
const channelCount = usedChannels(pipetteId, commands, pipetteChannels)
if (channelCount === 96) {
return 'A1 - H12'
} else if (usedChannels === 8) {
} else if (channelCount === 8) {
const column = wellName.substr(1)
return `A${column} - H${column}`
}
Expand Down

0 comments on commit d907591

Please sign in to comment.