-
+
{areSuggestionsVisible && (
{/* Tags (`name:`, `modified:`, etc.) */}
@@ -244,7 +261,7 @@ export default function AssetSearchBar(props: AssetSearchBarProps) {
data-testid="asset-search-tag-names"
className="flex flex-wrap gap-2 whitespace-nowrap px-2 pointer-events-auto"
>
- {AssetQuery.tagNames.flatMap(entry => {
+ {(isCloud ? AssetQuery.tagNames : AssetQuery.localTagNames).flatMap(entry => {
const [key, tag] = entry
return tag == null || isShiftPressed !== tag.startsWith('-')
? []
@@ -263,38 +280,41 @@ export default function AssetSearchBar(props: AssetSearchBarProps) {
})}
{/* Asset labels */}
-
- {labels.map(label => {
- const negated = query.negativeLabels.some(term =>
- array.shallowEqual(term, [label.value])
- )
- return (
-
- )
- })}
-
+ {isCloud && (
+
+ {labels.map(label => {
+ const negated = query.negativeLabels.some(term =>
+ array.shallowEqual(term, [label.value])
+ )
+ return (
+
+ )
+ })}
+
+ )}
{/* Suggestions */}
{suggestions.map((suggestion, index) => (
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/AssetsTable.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/AssetsTable.tsx
index f7eda5c97675..152a33e9bfe2 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/AssetsTable.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/AssetsTable.tsx
@@ -23,6 +23,7 @@ import type * as assetSearchBar from '#/layouts/dashboard/AssetSearchBar'
import AssetsTableContextMenu from '#/layouts/dashboard/AssetsTableContextMenu'
import Category from '#/layouts/dashboard/CategorySwitcher/Category'
import DuplicateAssetsModal from '#/layouts/dashboard/DuplicateAssetsModal'
+import UpsertSecretModal from '#/layouts/dashboard/UpsertSecretModal'
import Button from '#/components/Button'
import type * as assetRow from '#/components/dashboard/AssetRow'
@@ -33,6 +34,7 @@ import NameColumn from '#/components/dashboard/column/NameColumn'
import * as columnHeading from '#/components/dashboard/columnHeading'
import Label from '#/components/dashboard/Label'
import DragModal from '#/components/DragModal'
+import SelectionBrush from '#/components/SelectionBrush'
import Spinner, * as spinner from '#/components/Spinner'
import * as backendModule from '#/services/Backend'
@@ -44,6 +46,7 @@ import AssetTreeNode from '#/utilities/AssetTreeNode'
import * as dateTime from '#/utilities/dateTime'
import * as drag from '#/utilities/drag'
import * as fileInfo from '#/utilities/fileInfo'
+import type * as geometry from '#/utilities/geometry'
import LocalStorage from '#/utilities/LocalStorage'
import type * as pasteDataModule from '#/utilities/pasteData'
import PasteType from '#/utilities/PasteType'
@@ -78,8 +81,21 @@ LocalStorage.registerKey('extraColumns', {
// === Constants ===
// =================
+/** If the drag pointer is less than this distance away from the top or bottom of the
+ * scroll container, then the scroll container automatically scrolls upwards if the cursor is near
+ * the top of the scroll container, or downwards if the cursor is near the bottom. */
+const AUTOSCROLL_THRESHOLD_PX = 50
+/** An arbitrary constant that controls the speed of autoscroll. */
+const AUTOSCROLL_SPEED = 100
+/** The autoscroll speed is `AUTOSCROLL_SPEED / (distance + AUTOSCROLL_DAMPENING)`. */
+const AUTOSCROLL_DAMPENING = 10
+/** The height of the header row. */
+const HEADER_HEIGHT_PX = 34
+/** The height of each row in the table body. MUST be identical to the value as set by the
+ * Tailwind styling. */
+const ROW_HEIGHT_PX = 32
/** The size of the loading spinner. */
-const LOADING_SPINNER_SIZE = 36
+const LOADING_SPINNER_SIZE_PX = 36
/** The number of pixels the header bar should shrink when the extra column selector is visible. */
const TABLE_HEADER_WIDTH_SHRINKAGE_PX = 116
/** The default placeholder row. */
@@ -135,9 +151,14 @@ const SUGGESTIONS_FOR_TYPE: assetSearchBar.Suggestion[] = [
deleteFromQuery: query => query.deleteFromLastTerm({ types: ['file'] }),
},
{
- render: () => 'type:connector',
- addToQuery: query => query.addToLastTerm({ types: ['connector'] }),
- deleteFromQuery: query => query.deleteFromLastTerm({ types: ['connector'] }),
+ render: () => 'type:secret',
+ addToQuery: query => query.addToLastTerm({ types: ['secret'] }),
+ deleteFromQuery: query => query.deleteFromLastTerm({ types: ['secret'] }),
+ },
+ {
+ render: () => 'type:datalink',
+ addToQuery: query => query.addToLastTerm({ types: ['datalink'] }),
+ deleteFromQuery: query => query.deleteFromLastTerm({ types: ['datalink'] }),
},
]
const SUGGESTIONS_FOR_NEGATIVE_TYPE: assetSearchBar.Suggestion[] = [
@@ -234,6 +255,17 @@ function insertArbitraryAssetTreeNodeChildren(
return newNodes === nodes ? item : item.with({ children: newNodes })
}
+// =========================
+// === DragSelectionInfo ===
+// =========================
+
+/** Information related to a drag selection. */
+interface DragSelectionInfo {
+ readonly initialIndex: number
+ readonly start: number
+ readonly end: number
+}
+
// =============================
// === Category to filter by ===
// =============================
@@ -251,6 +283,7 @@ const CATEGORY_TO_FILTER_BY: Readonly
>
+ readonly scrollContainerRef: React.RefObject
readonly visibilities: ReadonlyMap
readonly category: Category
readonly labels: Map
@@ -266,9 +299,8 @@ export interface AssetsTableState {
readonly dispatchAssetListEvent: (event: assetListEvent.AssetListEvent) => void
readonly assetEvents: assetEvent.AssetEvent[]
readonly dispatchAssetEvent: (event: assetEvent.AssetEvent) => void
- readonly setAssetPanelProps: React.Dispatch<
- React.SetStateAction
- >
+ readonly setAssetPanelProps: (props: assetPanel.AssetPanelRequiredProps | null) => void
+ readonly setIsAssetPanelTemporarilyVisible: (visible: boolean) => void
readonly nodeMap: Readonly<
React.MutableRefObject>
>
@@ -280,12 +312,12 @@ export interface AssetsTableState {
) => void
/** Called when the project is opened via the `ProjectActionButton`. */
readonly doOpenManually: (projectId: backendModule.ProjectId) => void
- readonly doOpenIde: (
+ readonly doOpenEditor: (
project: backendModule.ProjectAsset,
setProject: React.Dispatch>,
switchPage: boolean
) => void
- readonly doCloseIde: (project: backendModule.ProjectAsset) => void
+ readonly doCloseEditor: (project: backendModule.ProjectAsset) => void
readonly doCreateLabel: (value: string, color: backendModule.LChColor) => Promise
readonly doCopy: () => void
readonly doCut: () => void
@@ -305,6 +337,7 @@ export interface AssetRowState {
/** Props for a {@link AssetsTable}. */
export interface AssetsTableProps {
+ readonly hidden: boolean
readonly query: AssetQuery
readonly setQuery: React.Dispatch>
readonly setCanDownloadFiles: (canDownloadFiles: boolean) => void
@@ -321,25 +354,25 @@ export interface AssetsTableProps {
readonly dispatchAssetListEvent: (event: assetListEvent.AssetListEvent) => void
readonly assetEvents: assetEvent.AssetEvent[]
readonly dispatchAssetEvent: (event: assetEvent.AssetEvent) => void
- readonly setAssetPanelProps: React.Dispatch<
- React.SetStateAction
- >
- readonly doOpenIde: (
+ readonly setAssetPanelProps: (props: assetPanel.AssetPanelRequiredProps | null) => void
+ readonly setIsAssetPanelTemporarilyVisible: (visible: boolean) => void
+ readonly doOpenEditor: (
project: backendModule.ProjectAsset,
setProject: React.Dispatch>,
switchPage: boolean
) => void
- readonly doCloseIde: (project: backendModule.ProjectAsset) => void
+ readonly doCloseEditor: (project: backendModule.ProjectAsset) => void
readonly doCreateLabel: (value: string, color: backendModule.LChColor) => Promise
}
/** The table of project assets. */
export default function AssetsTable(props: AssetsTableProps) {
- const { query, setQuery, setCanDownloadFiles, category, allLabels, setSuggestions } = props
- const { deletedLabelNames, initialProjectName, projectStartupInfo } = props
+ const { hidden, query, setQuery, setCanDownloadFiles, category, allLabels } = props
+ const { setSuggestions, deletedLabelNames, initialProjectName, projectStartupInfo } = props
const { queuedAssetEvents: rawQueuedAssetEvents } = props
const { assetListEvents, dispatchAssetListEvent, assetEvents, dispatchAssetEvent } = props
- const { setAssetPanelProps, doOpenIde, doCloseIde: rawDoCloseIde, doCreateLabel } = props
+ const { setAssetPanelProps, doOpenEditor, doCloseEditor: rawDoCloseEditor, doCreateLabel } = props
+ const { setIsAssetPanelTemporarilyVisible } = props
const { user, userInfo, accessToken } = authProvider.useNonPartialUserSession()
const { backend } = backendProvider.useBackend()
@@ -407,8 +440,8 @@ export default function AssetsTable(props: AssetsTableProps) {
const assetType =
node.item.type === backendModule.AssetType.directory
? 'folder'
- : node.item.type === backendModule.AssetType.secret
- ? 'connector'
+ : node.item.type === backendModule.AssetType.dataLink
+ ? 'datalink'
: String(node.item.type)
const assetExtension =
node.item.type !== backendModule.AssetType.file
@@ -513,14 +546,9 @@ export default function AssetsTable(props: AssetsTableProps) {
switch (sortColumn) {
case columnUtils.Column.name: {
compare = (a, b) => {
- const aTypeOrder = backendModule.ASSET_TYPE_ORDER[a.item.type]
- const bTypeOrder = backendModule.ASSET_TYPE_ORDER[b.item.type]
- const typeDelta = aTypeOrder - bTypeOrder
const aTitle = a.item.title.toLowerCase()
const bTitle = b.item.title.toLowerCase()
- if (typeDelta !== 0) {
- return typeDelta
- } else if (aTitle === bTitle) {
+ if (aTitle === bTitle) {
const delta = a.item.title > b.item.title ? 1 : a.item.title < b.item.title ? -1 : 0
return multiplier * delta
} else {
@@ -532,16 +560,9 @@ export default function AssetsTable(props: AssetsTableProps) {
}
case columnUtils.Column.modified: {
compare = (a, b) => {
- const aTypeOrder = backendModule.ASSET_TYPE_ORDER[a.item.type]
- const bTypeOrder = backendModule.ASSET_TYPE_ORDER[b.item.type]
- const typeDelta = aTypeOrder - bTypeOrder
- if (typeDelta !== 0) {
- return typeDelta
- } else {
- const aOrder = Number(new Date(a.item.modifiedAt))
- const bOrder = Number(new Date(b.item.modifiedAt))
- return multiplier * (aOrder - bOrder)
- }
+ const aOrder = Number(new Date(a.item.modifiedAt))
+ const bOrder = Number(new Date(b.item.modifiedAt))
+ return multiplier * (aOrder - bOrder)
}
break
}
@@ -573,6 +594,10 @@ export default function AssetsTable(props: AssetsTableProps) {
processNode(assetTree)
return map
}, [assetTree, filter])
+ const visibleItems = React.useMemo(
+ () => displayItems.filter(item => visibilities.get(item.key) !== Visibility.hidden),
+ [displayItems, visibilities]
+ )
React.useEffect(() => {
if (category === Category.trash) {
@@ -631,12 +656,12 @@ export default function AssetsTable(props: AssetsTableProps) {
}
case 'no':
case '-has': {
- setSuggestions(SUGGESTIONS_FOR_NO)
+ setSuggestions(isCloud ? SUGGESTIONS_FOR_NO : [])
break
}
case 'has':
case '-no': {
- setSuggestions(SUGGESTIONS_FOR_HAS)
+ setSuggestions(isCloud ? SUGGESTIONS_FOR_HAS : [])
break
}
case 'type': {
@@ -738,24 +763,26 @@ export default function AssetsTable(props: AssetsTableProps) {
case 'label':
case '-label': {
setSuggestions(
- Array.from(
- allLabels.values(),
- (label): assetSearchBar.Suggestion => ({
- render: () => (
-
- ),
- addToQuery: oldQuery =>
- oldQuery.addToLastTerm(
- negative ? { negativeLabels: [label.value] } : { labels: [label.value] }
- ),
- deleteFromQuery: oldQuery =>
- oldQuery.deleteFromLastTerm(
- negative ? { negativeLabels: [label.value] } : { labels: [label.value] }
- ),
- })
- )
+ !isCloud
+ ? []
+ : Array.from(
+ allLabels.values(),
+ (label): assetSearchBar.Suggestion => ({
+ render: () => (
+
+ ),
+ addToQuery: oldQuery =>
+ oldQuery.addToLastTerm(
+ negative ? { negativeLabels: [label.value] } : { labels: [label.value] }
+ ),
+ deleteFromQuery: oldQuery =>
+ oldQuery.deleteFromLastTerm(
+ negative ? { negativeLabels: [label.value] } : { labels: [label.value] }
+ ),
+ })
+ )
)
break
@@ -766,7 +793,7 @@ export default function AssetsTable(props: AssetsTableProps) {
}
}
}
- }, [assetTree, query, visibilities, allLabels, /* should never change */ setSuggestions])
+ }, [isCloud, assetTree, query, visibilities, allLabels, /* should never change */ setSuggestions])
React.useEffect(() => {
if (rawQueuedAssetEvents.length !== 0) {
@@ -837,16 +864,29 @@ export default function AssetsTable(props: AssetsTableProps) {
(newSelectedKeys: ReadonlySet) => {
selectedKeysRef.current = newSelectedKeys
setSelectedKeysRaw(newSelectedKeys)
+ if (!isCloud) {
+ setCanDownloadFiles(newSelectedKeys.size !== 0)
+ } else {
+ setCanDownloadFiles(
+ newSelectedKeys.size !== 0 &&
+ Array.from(newSelectedKeys).every(key => {
+ const node = nodeMapRef.current.get(key)
+ return node?.item.type === backendModule.AssetType.file
+ })
+ )
+ }
},
- []
+ [isCloud, /* should never change */ setCanDownloadFiles]
)
const clearSelectedKeys = React.useCallback(() => {
setSelectedKeys(new Set())
- }, [/* should never change */ setSelectedKeys])
+ }, [setSelectedKeys])
const overwriteNodes = React.useCallback(
(newAssets: backendModule.AnyAsset[]) => {
+ mostRecentlySelectedIndexRef.current = null
+ selectionStartIndexRef.current = null
// This is required, otherwise we are using an outdated
// `nameOfProjectToImmediatelyOpen`.
setNameOfProjectToImmediatelyOpen(oldNameOfProjectToImmediatelyOpen => {
@@ -1071,8 +1111,13 @@ export default function AssetsTable(props: AssetsTableProps) {
React.useEffect(() => {
if (selectedKeysRef.current.size !== 1) {
setAssetPanelProps(null)
+ setIsAssetPanelTemporarilyVisible(false)
}
- }, [selectedKeysRef.current.size, /* should never change */ setAssetPanelProps])
+ }, [
+ selectedKeysRef.current.size,
+ /* should never change */ setAssetPanelProps,
+ /* should never change */ setIsAssetPanelTemporarilyVisible,
+ ])
const directoryListAbortControllersRef = React.useRef(
new Map()
@@ -1179,6 +1224,168 @@ export default function AssetsTable(props: AssetsTableProps) {
[category, backend]
)
+ const [spinnerState, setSpinnerState] = React.useState(spinner.SpinnerState.initial)
+ const [keyboardSelectedIndex, setKeyboardSelectedIndexRaw] = React.useState(null)
+ const mostRecentlySelectedIndexRef = React.useRef(null)
+ const selectionStartIndexRef = React.useRef(null)
+ const bodyRef = React.useRef(null)
+
+ const setMostRecentlySelectedIndex = React.useCallback(
+ (index: number | null, isKeyboard = false) => {
+ mostRecentlySelectedIndexRef.current = index
+ setKeyboardSelectedIndexRaw(isKeyboard ? index : null)
+ },
+ []
+ )
+
+ React.useEffect(() => {
+ // This is not a React component, even though it contains JSX.
+ // eslint-disable-next-line no-restricted-syntax
+ const onKeyDown = (event: KeyboardEvent) => {
+ const prevIndex = mostRecentlySelectedIndexRef.current
+ const item = prevIndex == null ? null : visibleItems[prevIndex]
+ if (selectedKeysRef.current.size === 1 && item != null) {
+ switch (event.key) {
+ case 'Enter':
+ case ' ': {
+ if (event.key === ' ' && event.ctrlKey) {
+ const keys = selectedKeysRef.current
+ setSelectedKeys(set.withPresence(keys, item.key, !keys.has(item.key)))
+ } else {
+ switch (item.item.type) {
+ case backendModule.AssetType.directory: {
+ event.preventDefault()
+ event.stopPropagation()
+ doToggleDirectoryExpansion(item.item.id, item.key)
+ break
+ }
+ case backendModule.AssetType.project: {
+ event.preventDefault()
+ event.stopPropagation()
+ dispatchAssetEvent({
+ type: AssetEventType.openProject,
+ id: item.item.id,
+ runInBackground: false,
+ shouldAutomaticallySwitchPage: true,
+ })
+ break
+ }
+ case backendModule.AssetType.dataLink: {
+ event.preventDefault()
+ event.stopPropagation()
+ setIsAssetPanelTemporarilyVisible(true)
+ break
+ }
+ case backendModule.AssetType.secret: {
+ event.preventDefault()
+ event.stopPropagation()
+ const id = item.item.id
+ setModal(
+ {
+ try {
+ await backend.updateSecret(id, { value }, item.item.title)
+ } catch (error) {
+ toastAndLog(null, error)
+ }
+ }}
+ />
+ )
+ break
+ }
+ default: {
+ break
+ }
+ }
+ }
+ break
+ }
+ case 'ArrowLeft': {
+ if (item.item.type === backendModule.AssetType.directory && item.children != null) {
+ event.preventDefault()
+ event.stopPropagation()
+ doToggleDirectoryExpansion(item.item.id, item.key, null, false)
+ }
+ break
+ }
+ case 'ArrowRight': {
+ if (item.item.type === backendModule.AssetType.directory && item.children == null) {
+ event.preventDefault()
+ event.stopPropagation()
+ doToggleDirectoryExpansion(item.item.id, item.key, null, true)
+ }
+ break
+ }
+ }
+ }
+ switch (event.key) {
+ case ' ': {
+ if (event.ctrlKey && item != null) {
+ const keys = selectedKeysRef.current
+ setSelectedKeys(set.withPresence(keys, item.key, !keys.has(item.key)))
+ }
+ break
+ }
+ case 'Escape': {
+ setSelectedKeys(new Set())
+ setMostRecentlySelectedIndex(null)
+ selectionStartIndexRef.current = null
+ break
+ }
+ case 'ArrowUp':
+ case 'ArrowDown': {
+ event.preventDefault()
+ event.stopPropagation()
+ if (!event.shiftKey) {
+ selectionStartIndexRef.current = null
+ }
+ const index =
+ prevIndex == null
+ ? 0
+ : event.key === 'ArrowUp'
+ ? Math.max(0, prevIndex - 1)
+ : Math.min(visibleItems.length - 1, prevIndex + 1)
+ setMostRecentlySelectedIndex(index, true)
+ if (event.shiftKey) {
+ // On Windows, Ctrl+Shift+Arrow behaves the same as Shift+Arrow.
+ if (selectionStartIndexRef.current == null) {
+ selectionStartIndexRef.current = prevIndex ?? 0
+ }
+ const startIndex = Math.min(index, selectionStartIndexRef.current)
+ const endIndex = Math.max(index, selectionStartIndexRef.current) + 1
+ const selection = visibleItems.slice(startIndex, endIndex)
+ setSelectedKeys(new Set(selection.map(newItem => newItem.key)))
+ } else if (event.ctrlKey) {
+ selectionStartIndexRef.current = null
+ } else {
+ const newItem = visibleItems[index]
+ if (newItem != null) {
+ setSelectedKeys(new Set([newItem.key]))
+ }
+ selectionStartIndexRef.current = null
+ }
+ break
+ }
+ }
+ }
+ document.addEventListener('keydown', onKeyDown)
+ return () => {
+ document.removeEventListener('keydown', onKeyDown)
+ }
+ }, [
+ visibleItems,
+ backend,
+ doToggleDirectoryExpansion,
+ /* should never change */ toastAndLog,
+ /* should never change */ setModal,
+ /* should never change */ setMostRecentlySelectedIndex,
+ /* should never change */ setSelectedKeys,
+ /* should never change */ setIsAssetPanelTemporarilyVisible,
+ /* should never change */ dispatchAssetEvent,
+ ])
+
const getNewProjectName = React.useCallback(
(templateName: string | null, parentKey: backendModule.DirectoryId | null) => {
const prefix = `${templateName ?? 'New Project'} `
@@ -1544,16 +1751,13 @@ export default function AssetsTable(props: AssetsTableProps) {
[/* should never change */ dispatchAssetEvent]
)
- const doCloseIde = React.useCallback(
+ const doCloseEditor = React.useCallback(
(project: backendModule.ProjectAsset) => {
if (project.id === projectStartupInfo?.projectAsset.id) {
- dispatchAssetEvent({
- type: AssetEventType.cancelOpeningAllProjects,
- })
- rawDoCloseIde(project)
+ rawDoCloseEditor(project)
}
},
- [projectStartupInfo, rawDoCloseIde, /* should never change */ dispatchAssetEvent]
+ [projectStartupInfo, rawDoCloseEditor]
)
const doCopy = React.useCallback(() => {
@@ -1571,7 +1775,7 @@ export default function AssetsTable(props: AssetsTableProps) {
setSelectedKeys(new Set())
}, [
pasteData,
- /* should never change */ setSelectedKeys,
+ setSelectedKeys,
/* should never change */ unsetModal,
/* should never change */ dispatchAssetEvent,
])
@@ -1658,6 +1862,7 @@ export default function AssetsTable(props: AssetsTableProps) {
(): AssetsTableState => ({
visibilities,
selectedKeys: selectedKeysRef,
+ scrollContainerRef,
category,
labels: allLabels,
deletedLabelNames,
@@ -1673,11 +1878,12 @@ export default function AssetsTable(props: AssetsTableProps) {
dispatchAssetEvent,
dispatchAssetListEvent,
setAssetPanelProps,
+ setIsAssetPanelTemporarilyVisible,
nodeMap: nodeMapRef,
doToggleDirectoryExpansion,
doOpenManually,
- doOpenIde,
- doCloseIde,
+ doOpenEditor: doOpenEditor,
+ doCloseEditor: doCloseEditor,
doCreateLabel,
doCopy,
doCut,
@@ -1695,24 +1901,20 @@ export default function AssetsTable(props: AssetsTableProps) {
query,
doToggleDirectoryExpansion,
doOpenManually,
- doOpenIde,
- doCloseIde,
+ doOpenEditor,
+ doCloseEditor,
doCreateLabel,
doCopy,
doCut,
doPaste,
/* should never change */ setAssetPanelProps,
+ /* should never change */ setIsAssetPanelTemporarilyVisible,
/* should never change */ setQuery,
/* should never change */ dispatchAssetEvent,
/* should never change */ dispatchAssetListEvent,
]
)
- const [spinnerState, setSpinnerState] = React.useState(spinner.SpinnerState.initial)
- const [previouslySelectedKey, setPreviouslySelectedKey] =
- React.useState(null)
- const bodyRef = React.useRef(null)
-
// This is required to prevent the table body from overlapping the table header, because
// the table header is transparent.
React.useEffect(() => {
@@ -1754,13 +1956,18 @@ export default function AssetsTable(props: AssetsTableProps) {
selectedKeysRef.current.size !== 0
) {
setSelectedKeys(new Set())
+ setMostRecentlySelectedIndex(null)
}
}
document.addEventListener('click', onDocumentClick)
return () => {
document.removeEventListener('click', onDocumentClick)
}
- }, [shortcutManager, /* should never change */ setSelectedKeys])
+ }, [
+ shortcutManager,
+ /* should never change */ setSelectedKeys,
+ /* should never change */ setMostRecentlySelectedIndex,
+ ])
React.useEffect(() => {
if (isLoading) {
@@ -1774,38 +1981,24 @@ export default function AssetsTable(props: AssetsTableProps) {
}
}, [isLoading])
- const onRowClick = React.useCallback(
- (innerRowProps: assetRow.AssetRowInnerProps, event: React.MouseEvent) => {
- const { key } = innerRowProps
+ const calculateNewKeys = React.useCallback(
+ (
+ event: MouseEvent | React.MouseEvent,
+ keys: backendModule.AssetId[],
+ getRange: () => backendModule.AssetId[]
+ ) => {
event.stopPropagation()
- const getNewlySelectedKeys = () => {
- if (previouslySelectedKey == null) {
- return [key]
- } else {
- const index1 = displayItems.findIndex(
- innerItem => AssetTreeNode.getKey(innerItem) === previouslySelectedKey
- )
- const index2 = displayItems.findIndex(
- innerItem => AssetTreeNode.getKey(innerItem) === key
- )
- const selectedItems =
- index1 <= index2
- ? displayItems.slice(index1, index2 + 1)
- : displayItems.slice(index2, index1 + 1)
- return selectedItems.map(AssetTreeNode.getKey)
- }
- }
if (
shortcutManager.matchesMouseAction(shortcutManagerModule.MouseAction.selectRange, event)
) {
- setSelectedKeys(new Set(getNewlySelectedKeys()))
+ return new Set(getRange())
} else if (
shortcutManager.matchesMouseAction(
shortcutManagerModule.MouseAction.selectAdditionalRange,
event
)
) {
- setSelectedKeys(new Set([...selectedKeysRef.current, ...getNewlySelectedKeys()]))
+ return new Set([...selectedKeysRef.current, ...getRange()])
} else if (
shortcutManager.matchesMouseAction(
shortcutManagerModule.MouseAction.selectAdditional,
@@ -1813,22 +2006,147 @@ export default function AssetsTable(props: AssetsTableProps) {
)
) {
const newSelectedKeys = new Set(selectedKeysRef.current)
- if (selectedKeysRef.current.has(key)) {
- newSelectedKeys.delete(key)
- } else {
- newSelectedKeys.add(key)
+ let count = 0
+ for (const key of keys) {
+ if (selectedKeysRef.current.has(key)) {
+ count += 1
+ }
}
- setSelectedKeys(newSelectedKeys)
+ for (const key of keys) {
+ const add = count * 2 < keys.length
+ set.setPresence(newSelectedKeys, key, add)
+ }
+ return newSelectedKeys
} else {
- setSelectedKeys(new Set([key]))
+ return new Set(keys)
+ }
+ },
+ [shortcutManager]
+ )
+
+ // Only non-`null` when it is different to`selectedKeys`.
+ const [visuallySelectedKeysOverride, setVisuallySelectedKeysOverride] =
+ React.useState | null>(null)
+
+ const dragSelectionChangeLoopHandle = React.useRef(0)
+ const dragSelectionRangeRef = React.useRef(null)
+ const onSelectionDrag = React.useCallback(
+ (rectangle: geometry.DetailedRectangle, event: MouseEvent) => {
+ if (mostRecentlySelectedIndexRef.current != null) {
+ setKeyboardSelectedIndexRaw(null)
+ }
+ cancelAnimationFrame(dragSelectionChangeLoopHandle.current)
+ const scrollContainer = scrollContainerRef.current
+ if (scrollContainer != null) {
+ const rect = scrollContainer.getBoundingClientRect()
+ if (rectangle.signedHeight <= 0 && scrollContainer.scrollTop > 0) {
+ const distanceToTop = Math.max(0, rectangle.top - rect.top - HEADER_HEIGHT_PX)
+ if (distanceToTop < AUTOSCROLL_THRESHOLD_PX) {
+ scrollContainer.scrollTop -= Math.floor(
+ AUTOSCROLL_SPEED / (distanceToTop + AUTOSCROLL_DAMPENING)
+ )
+ dragSelectionChangeLoopHandle.current = requestAnimationFrame(() => {
+ onSelectionDrag(rectangle, event)
+ })
+ }
+ }
+ if (
+ rectangle.signedHeight >= 0 &&
+ scrollContainer.scrollTop + rect.height < scrollContainer.scrollHeight
+ ) {
+ const distanceToBottom = Math.max(0, rect.bottom - rectangle.bottom)
+ if (distanceToBottom < AUTOSCROLL_THRESHOLD_PX) {
+ scrollContainer.scrollTop += Math.floor(
+ AUTOSCROLL_SPEED / (distanceToBottom + AUTOSCROLL_DAMPENING)
+ )
+ dragSelectionChangeLoopHandle.current = requestAnimationFrame(() => {
+ onSelectionDrag(rectangle, event)
+ })
+ }
+ }
+ const overlapsHorizontally = rect.right > rectangle.left && rect.left < rectangle.right
+ const selectionTop = Math.max(0, rectangle.top - rect.top - HEADER_HEIGHT_PX)
+ const selectionBottom = Math.max(
+ 0,
+ Math.min(rect.height, rectangle.bottom - rect.top - HEADER_HEIGHT_PX)
+ )
+ const range = dragSelectionRangeRef.current
+ if (!overlapsHorizontally) {
+ dragSelectionRangeRef.current = null
+ } else if (range == null) {
+ const topIndex = (selectionTop + scrollContainer.scrollTop) / ROW_HEIGHT_PX
+ const bottomIndex = (selectionBottom + scrollContainer.scrollTop) / ROW_HEIGHT_PX
+ dragSelectionRangeRef.current = {
+ initialIndex: rectangle.signedHeight < 0 ? bottomIndex : topIndex,
+ start: Math.floor(topIndex),
+ end: Math.ceil(bottomIndex),
+ }
+ } else {
+ const topIndex = (selectionTop + scrollContainer.scrollTop) / ROW_HEIGHT_PX
+ const bottomIndex = (selectionBottom + scrollContainer.scrollTop) / ROW_HEIGHT_PX
+ const endIndex = rectangle.signedHeight < 0 ? topIndex : bottomIndex
+ dragSelectionRangeRef.current = {
+ initialIndex: range.initialIndex,
+ start: Math.floor(Math.min(range.initialIndex, endIndex)),
+ end: Math.ceil(Math.max(range.initialIndex, endIndex)),
+ }
+ }
+ if (range == null) {
+ setVisuallySelectedKeysOverride(null)
+ } else {
+ const keys = displayItems.slice(range.start, range.end).map(node => node.key)
+ setVisuallySelectedKeysOverride(calculateNewKeys(event, keys, () => []))
+ }
+ }
+ },
+ [displayItems, calculateNewKeys]
+ )
+
+ const onSelectionDragEnd = React.useCallback(
+ (event: MouseEvent) => {
+ const range = dragSelectionRangeRef.current
+ if (range != null) {
+ const keys = displayItems.slice(range.start, range.end).map(node => node.key)
+ setSelectedKeys(calculateNewKeys(event, keys, () => []))
+ }
+ setVisuallySelectedKeysOverride(null)
+ dragSelectionRangeRef.current = null
+ },
+ [displayItems, calculateNewKeys, /* should never change */ setSelectedKeys]
+ )
+
+ const onSelectionDragCancel = React.useCallback(() => {
+ setVisuallySelectedKeysOverride(null)
+ dragSelectionRangeRef.current = null
+ }, [])
+
+ const onRowClick = React.useCallback(
+ (innerRowProps: assetRow.AssetRowInnerProps, event: React.MouseEvent) => {
+ const { key } = innerRowProps
+ event.stopPropagation()
+ const newIndex = visibleItems.findIndex(innerItem => AssetTreeNode.getKey(innerItem) === key)
+ const getRange = () => {
+ if (mostRecentlySelectedIndexRef.current == null) {
+ return [key]
+ } else {
+ const index1 = mostRecentlySelectedIndexRef.current
+ const index2 = newIndex
+ const startIndex = Math.min(index1, index2)
+ const endIndex = Math.max(index1, index2) + 1
+ return visibleItems.slice(startIndex, endIndex).map(AssetTreeNode.getKey)
+ }
+ }
+ setSelectedKeys(calculateNewKeys(event, [key], getRange))
+ setMostRecentlySelectedIndex(newIndex)
+ if (!event.shiftKey) {
+ selectionStartIndexRef.current = null
}
- setPreviouslySelectedKey(key)
},
[
- displayItems,
- previouslySelectedKey,
- shortcutManager,
+ visibleItems,
+ calculateNewKeys,
/* should never change */ setSelectedKeys,
+ /* should never change */ setMostRecentlySelectedIndex,
]
)
@@ -1856,15 +2174,15 @@ export default function AssetsTable(props: AssetsTableProps) {
-
+
|
) : (
displayItems.map(item => {
const key = AssetTreeNode.getKey(item)
- const isSelected = selectedKeys.has(key)
- const isSoleSelectedItem = selectedKeys.size === 1 && isSelected
+ const isSelected = (visuallySelectedKeysOverride ?? selectedKeys).has(key)
+ const isSoleSelected = selectedKeys.size === 1 && isSelected
return (
{
setSelectedKeys(set.withPresence(selectedKeysRef.current, key, selected))
}}
- isSoleSelectedItem={isSoleSelectedItem}
- allowContextMenu={selectedKeysRef.current.size === 0 || !isSelected || isSoleSelectedItem}
+ isSoleSelected={isSoleSelected}
+ isKeyboardSelected={
+ keyboardSelectedIndex != null && item === visibleItems[keyboardSelectedIndex]
+ }
+ allowContextMenu={selectedKeysRef.current.size === 0 || !isSelected || isSoleSelected}
onClick={onRowClick}
onContextMenu={(_innerProps, event) => {
if (!isSelected) {
event.preventDefault()
event.stopPropagation()
- setPreviouslySelectedKey(key)
+ setMostRecentlySelectedIndex(visibleItems.indexOf(item))
+ selectionStartIndexRef.current = null
setSelectedKeys(new Set([key]))
}
}}
onDragStart={event => {
let newSelectedKeys = selectedKeysRef.current
- if (!selectedKeysRef.current.has(key)) {
- setPreviouslySelectedKey(key)
+ if (!newSelectedKeys.has(key)) {
+ setMostRecentlySelectedIndex(visibleItems.indexOf(item))
+ selectionStartIndexRef.current = null
newSelectedKeys = new Set([key])
setSelectedKeys(newSelectedKeys)
}
@@ -1918,7 +2241,7 @@ export default function AssetsTable(props: AssetsTableProps) {
item={node.with({ depth: 0 })}
state={state}
// Default states.
- isSoleSelectedItem={false}
+ isSoleSelected={false}
selected={false}
rowState={assetRowUtils.INITIAL_ROW_STATE}
// The drag placeholder cannot be interacted with.
@@ -2031,9 +2354,9 @@ export default function AssetsTable(props: AssetsTableProps) {
category={category}
pasteData={pasteData}
selectedKeys={selectedKeys}
+ clearSelectedKeys={clearSelectedKeys}
nodeMapRef={nodeMapRef}
event={event}
- clearSelectedKeys={clearSelectedKeys}
dispatchAssetEvent={dispatchAssetEvent}
dispatchAssetListEvent={dispatchAssetListEvent}
doCopy={doCopy}
@@ -2106,6 +2429,13 @@ export default function AssetsTable(props: AssetsTableProps) {
return (
+ {!hidden && (
+
+ )}
{isCloud && (
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/ChangePasswordModal.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/ChangePasswordModal.tsx
deleted file mode 100644
index 94cb89ed5619..000000000000
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/ChangePasswordModal.tsx
+++ /dev/null
@@ -1,103 +0,0 @@
-/** @file A modal for changing the user's password. */
-import * as React from 'react'
-
-import ArrowRightIcon from 'enso-assets/arrow_right.svg'
-import LockIcon from 'enso-assets/lock.svg'
-
-import * as authProvider from '#/providers/AuthProvider'
-import * as modalProvider from '#/providers/ModalProvider'
-
-import Input from '#/components/Input'
-import Modal from '#/components/Modal'
-import SubmitButton from '#/components/SubmitButton'
-
-import * as string from '#/utilities/string'
-import * as validation from '#/utilities/validation'
-
-// ===========================
-// === ChangePasswordModal ===
-// ===========================
-
-/** A modal for changing the user's password. */
-export default function ChangePasswordModal() {
- const { user } = authProvider.useNonPartialUserSession()
- const { changePassword } = authProvider.useAuth()
- const { unsetModal } = modalProvider.useSetModal()
-
- const [oldPassword, setOldPassword] = React.useState('')
- const [newPassword, setNewPassword] = React.useState('')
- const [confirmNewPassword, setConfirmNewPassword] = React.useState('')
- const [isSubmitting, setIsSubmitting] = React.useState(false)
-
- return (
-
-
-
- )
-}
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/Drive.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/Drive.tsx
index aed10375ee51..83a96cb2fd00 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/Drive.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/Drive.tsx
@@ -31,6 +31,7 @@ import * as backendModule from '#/services/Backend'
import * as array from '#/utilities/array'
import type AssetQuery from '#/utilities/AssetQuery'
+import * as download from '#/utilities/download'
import * as github from '#/utilities/github'
import LocalStorage from '#/utilities/LocalStorage'
import * as projectManager from '#/utilities/ProjectManager'
@@ -92,9 +93,8 @@ export interface DriveProps {
readonly setLabels: React.Dispatch
>
readonly setSuggestions: (suggestions: assetSearchBar.Suggestion[]) => void
readonly projectStartupInfo: backendModule.ProjectStartupInfo | null
- readonly setAssetPanelProps: React.Dispatch<
- React.SetStateAction
- >
+ readonly setAssetPanelProps: (props: assetPanel.AssetPanelRequiredProps | null) => void
+ readonly setIsAssetPanelTemporarilyVisible: (visible: boolean) => void
readonly doCreateProject: (templateId: string | null) => void
readonly doOpenEditor: (
project: backendModule.ProjectAsset,
@@ -110,6 +110,7 @@ export default function Drive(props: DriveProps) {
const { query, setQuery, labels, setLabels, setSuggestions, projectStartupInfo } = props
const { assetListEvents, dispatchAssetListEvent, assetEvents, dispatchAssetEvent } = props
const { setAssetPanelProps, doOpenEditor, doCloseEditor } = props
+ const { setIsAssetPanelTemporarilyVisible } = props
const navigate = navigateHooks.useNavigate()
const toastAndLog = toastAndLogHooks.useToastAndLog()
@@ -336,7 +337,7 @@ export default function Drive(props: DriveProps) {
if (downloadUrl == null) {
toastAndLog('Could not find a download link for the current OS')
} else {
- window.open(downloadUrl, '_blank')
+ download.download(downloadUrl)
}
}}
>
@@ -390,6 +391,7 @@ export default function Drive(props: DriveProps) {
)}
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/DriveBar.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/DriveBar.tsx
index f3558c8caecd..a46d43e01c3d 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/DriveBar.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/DriveBar.tsx
@@ -177,9 +177,7 @@ export default function DriveBar(props: DriveBarProps) {
onClick={event => {
event.stopPropagation()
unsetModal()
- dispatchAssetEvent({
- type: AssetEventType.downloadSelected,
- })
+ dispatchAssetEvent({ type: AssetEventType.downloadSelected })
}}
/>
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/GlobalContextMenu.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/GlobalContextMenu.tsx
index 141c14c157d3..a0c3bd0ff847 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/GlobalContextMenu.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/GlobalContextMenu.tsx
@@ -65,7 +65,7 @@ export default function GlobalContextMenu(props: GlobalContextMenuProps) {
unsetModal()
}
}}
- >
+ />
)}
+ readonly onSubmit?: (value: string) => void
}
-/** A transparent wrapper component */
-// This is a React component even though it does not contain JSX.
-// eslint-disable-next-line no-restricted-syntax
-function Name(props: InternalTransparentWrapperProps) {
- return props.children
-}
+/** A styled input. */
+function Input(props: InternalInputProps) {
+ const { originalValue, type, placeholder, onChange, onSubmit } = props
+ const [isShowingPassword, setIsShowingPassword] = React.useState(false)
+ const cancelled = React.useRef(false)
-/** A transparent wrapper component */
-// This is a React component even though it does not contain JSX.
-// eslint-disable-next-line no-restricted-syntax
-function Value(props: InternalTransparentWrapperProps) {
- return props.children
-}
+ const onKeyDown = (event: React.KeyboardEvent) => {
+ switch (event.key) {
+ case 'Escape': {
+ cancelled.current = true
+ event.stopPropagation()
+ event.currentTarget.value = originalValue
+ event.currentTarget.blur()
+ break
+ }
+ case 'Enter': {
+ cancelled.current = false
+ event.stopPropagation()
+ event.currentTarget.blur()
+ break
+ }
+ case 'Tab': {
+ cancelled.current = false
+ event.currentTarget.blur()
+ break
+ }
+ default: {
+ cancelled.current = false
+ break
+ }
+ }
+ }
-/** Props for a {@link InfoEntry}. */
-interface InternalInfoEntryProps {
- readonly children: [React.ReactNode, React.ReactNode]
-}
+ const input = (
+ {
+ if (!cancelled.current) {
+ onSubmit?.(event.currentTarget.value)
+ }
+ }}
+ />
+ )
-/** Styled information display containing key and value. */
-function InfoEntry(props: InternalInfoEntryProps) {
- const { children } = props
- const [name, value] = children
- return (
-
-
{name}
-
{value}
+ return type !== 'password' ? (
+ input
+ ) : (
+
+ {input}
+ {
+ {
+ setIsShowingPassword(show => !show)
+ }}
+ />
+ }
)
}
@@ -60,15 +107,24 @@ function InfoEntry(props: InternalInfoEntryProps) {
/** Settings tab for viewing and editing account information. */
export default function AccountSettingsTab() {
const toastAndLog = toastAndLogHooks.useToastAndLog()
- const { setUser, signOut } = authProvider.useAuth()
+ const { setUser, changePassword, signOut } = authProvider.useAuth()
const { setModal } = modalProvider.useSetModal()
const { backend } = backendProvider.useBackend()
- const { user } = authProvider.useNonPartialUserSession()
- const nameInputRef = React.useRef
(null)
+ const { user, accessToken } = authProvider.useNonPartialUserSession()
+ const [passwordFormKey, setPasswordFormKey] = React.useState('')
+ const [currentPassword, setCurrentPassword] = React.useState('')
+ const [newPassword, setNewPassword] = React.useState('')
+ const [confirmNewPassword, setConfirmNewPassword] = React.useState('')
+
+ // The shape of the JWT payload is statically known.
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ const username: string | null =
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-non-null-assertion
+ accessToken != null ? JSON.parse(atob(accessToken.split('.')[1]!)).username : null
+ const canChangePassword = username != null ? !/^Github_|^Google_/.test(username) : false
- const doUpdateName = async () => {
+ const doUpdateName = async (newName: string) => {
const oldName = user?.name ?? ''
- const newName = nameInputRef.current?.value ?? ''
if (newName === oldName) {
return
} else {
@@ -77,9 +133,6 @@ export default function AccountSettingsTab() {
setUser(object.merger({ name: newName }))
} catch (error) {
toastAndLog(null, error)
- if (nameInputRef.current) {
- nameInputRef.current.value = oldName
- }
}
return
}
@@ -108,45 +161,106 @@ export default function AccountSettingsTab() {
+ {canChangePassword && (
+
+
Change Password
+
+ Current Password
+
+ {
+ setCurrentPassword(event.currentTarget.value)
}}
/>
-
-
-
- Email
- {user?.email ?? ''}
-
+
+
+
+ New Password
+
+ {
+ const newValue = event.currentTarget.value
+ setNewPassword(newValue)
+ event.currentTarget.setCustomValidity(
+ newValue === '' || validation.PASSWORD_REGEX.test(newValue)
+ ? ''
+ : validation.PASSWORD_ERROR
+ )
+ }}
+ />
+
+
+
+ Confirm New Password
+
+ {
+ const newValue = event.currentTarget.value
+ setConfirmNewPassword(newValue)
+ event.currentTarget.setCustomValidity(
+ newValue === '' || newValue === newPassword ? '' : 'Passwords must match.'
+ )
+ }}
+ />
+
+
+
+
+
+
-
+ )}
Danger Zone
@@ -293,7 +270,12 @@ export default function OrganizationSettingsTab(props: OrganizationSettingsTabPr
accept="image/*"
onChange={doUploadOrganizationPicture}
/>
-
+
Your organization's profile picture should not be irrelevant, abusive or vulgar. It
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/TopBar.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/TopBar.tsx
index ea1be45bb4b3..6e1692aeb63a 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/TopBar.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/TopBar.tsx
@@ -21,6 +21,7 @@ import type AssetQuery from '#/utilities/AssetQuery'
export interface TopBarProps {
/** Whether the application may have the local backend running. */
readonly supportsLocalBackend: boolean
+ readonly isCloud: boolean
readonly page: pageSwitcher.Page
readonly setPage: (page: pageSwitcher.Page) => void
readonly projectAsset: backendModule.ProjectAsset | null
@@ -43,7 +44,7 @@ export interface TopBarProps {
/** The {@link TopBarProps.setQuery} parameter is used to communicate with the parent component,
* because `searchVal` may change parent component's project list. */
export default function TopBar(props: TopBarProps) {
- const { supportsLocalBackend, page, setPage, projectAsset, setProjectAsset } = props
+ const { supportsLocalBackend, isCloud, page, setPage, projectAsset, setProjectAsset } = props
const { isEditorDisabled, setBackendType, isHelpChatOpen, setIsHelpChatOpen } = props
const { query, setQuery, labels, suggestions, canToggleAssetPanel } = props
const { isAssetPanelVisible, setIsAssetPanelVisible, doRemoveSelf, onSignOut } = props
@@ -63,6 +64,7 @@ export default function TopBar(props: TopBarProps) {
) : (
Value
{
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserBar.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserBar.tsx
index bfdf2cee09be..8868728ba8a0 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserBar.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserBar.tsx
@@ -118,6 +118,7 @@ export default function UserBar(props: UserBarProps) {
diff --git a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserMenu.tsx b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserMenu.tsx
index 9c535f5c2bae..42b048dd8896 100644
--- a/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserMenu.tsx
+++ b/app/ide-desktop/lib/dashboard/src/layouts/dashboard/UserMenu.tsx
@@ -11,12 +11,12 @@ import * as toastAndLogHooks from '#/hooks/toastAndLogHooks'
import * as authProvider from '#/providers/AuthProvider'
import * as modalProvider from '#/providers/ModalProvider'
-import ChangePasswordModal from '#/layouts/dashboard/ChangePasswordModal'
import * as pageSwitcher from '#/layouts/dashboard/PageSwitcher'
import MenuEntry from '#/components/MenuEntry'
import Modal from '#/components/Modal'
+import * as download from '#/utilities/download'
import * as github from '#/utilities/github'
import * as shortcutManager from '#/utilities/ShortcutManager'
@@ -38,17 +38,10 @@ export default function UserMenu(props: UserMenuProps) {
const { hidden = false, setPage, supportsLocalBackend, onSignOut } = props
const navigate = navigateHooks.useNavigate()
const { signOut } = authProvider.useAuth()
- const { accessToken, user } = authProvider.useNonPartialUserSession()
- const { setModal, unsetModal } = modalProvider.useSetModal()
+ const { user } = authProvider.useNonPartialUserSession()
+ const { unsetModal } = modalProvider.useSetModal()
const toastAndLog = toastAndLogHooks.useToastAndLog()
- // The shape of the JWT payload is statically known.
- // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
- const username: string | null =
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-non-null-assertion
- accessToken != null ? JSON.parse(atob(accessToken.split('.')[1]!)).username : null
- const canChangePassword = username != null ? !/^Github_|^Google_/.test(username) : false
-
return (
-
+
{user.name}
- {canChangePassword && (
-
{
- setModal()
- }}
- />
- )}
{!supportsLocalBackend && (
diff --git a/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx b/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx
index 13faad3bf2eb..a5d6bb1a81ac 100644
--- a/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx
+++ b/app/ide-desktop/lib/dashboard/src/pages/dashboard/Dashboard.tsx
@@ -139,11 +139,13 @@ export default function Dashboard(props: DashboardProps) {
const [isAssetPanelVisible, setIsAssetPanelVisible] = React.useState(
() => localStorage.get('isAssetPanelVisible') ?? false
)
+ const [isAssetPanelTemporarilyVisible, setIsAssetPanelTemporarilyVisible] = React.useState(false)
const [initialProjectName, setInitialProjectName] = React.useState(rawInitialProjectName)
const rootDirectoryId = React.useMemo(
() => session.user?.rootDirectoryId ?? backendModule.DirectoryId(''),
[session.user]
)
+ const isCloud = backend.type === backendModule.BackendType.remote
React.useEffect(() => {
setInitialized(true)
@@ -207,7 +209,7 @@ export default function Dashboard(props: DashboardProps) {
savedProjectStartupInfo.projectAsset.id,
savedProjectStartupInfo.projectAsset.title
)
- if (backendModule.DOES_PROJECT_STATE_INDICATE_VM_EXISTS[oldProject.state.type]) {
+ if (backendModule.IS_OPENING_OR_OPENED[oldProject.state.type]) {
await remoteBackendModule.waitUntilProjectIsReady(
remoteBackend,
savedProjectStartupInfo.projectAsset,
@@ -378,7 +380,7 @@ export default function Dashboard(props: DashboardProps) {
[rootDirectoryId, /* should never change */ dispatchAssetListEvent]
)
- const openEditor = React.useCallback(
+ const doOpenEditor = React.useCallback(
async (
newProject: backendModule.ProjectAsset,
setProjectAsset: React.Dispatch>,
@@ -400,7 +402,7 @@ export default function Dashboard(props: DashboardProps) {
[backend, projectStartupInfo?.project.projectId, session.accessToken]
)
- const closeEditor = React.useCallback((closingProject: backendModule.ProjectAsset) => {
+ const doCloseEditor = React.useCallback((closingProject: backendModule.ProjectAsset) => {
setProjectStartupInfo(oldInfo =>
oldInfo?.projectAsset.id === closingProject.id ? null : oldInfo
)
@@ -408,10 +410,8 @@ export default function Dashboard(props: DashboardProps) {
const doRemoveSelf = React.useCallback(() => {
if (projectStartupInfo?.projectAsset != null) {
- dispatchAssetListEvent({
- type: AssetListEventType.removeSelf,
- id: projectStartupInfo.projectAsset.id,
- })
+ const id = projectStartupInfo.projectAsset.id
+ dispatchAssetListEvent({ type: AssetListEventType.removeSelf, id })
setProjectStartupInfo(null)
}
}, [projectStartupInfo?.projectAsset, /* should never change */ dispatchAssetListEvent])
@@ -439,6 +439,7 @@ export default function Dashboard(props: DashboardProps) {
>
- {assetPanelProps && isAssetPanelVisible && (
+ {assetPanelProps && (isAssetPanelVisible || isAssetPanelTemporarilyVisible) && (
) : (
-
+
)}
diff --git a/app/ide-desktop/lib/dashboard/src/services/Backend.ts b/app/ide-desktop/lib/dashboard/src/services/Backend.ts
index 7c4bacd1c190..820539b832bd 100644
--- a/app/ide-desktop/lib/dashboard/src/services/Backend.ts
+++ b/app/ide-desktop/lib/dashboard/src/services/Backend.ts
@@ -124,6 +124,7 @@ export interface CreatedDirectory {
export enum ProjectState {
created = 'Created',
new = 'New',
+ scheduled = 'Scheduled',
openInProgress = 'OpenInProgress',
provisioned = 'Provisioned',
opened = 'Opened',
@@ -152,9 +153,22 @@ export interface ProjectStateType {
/* eslint-enable @typescript-eslint/naming-convention */
}
-export const DOES_PROJECT_STATE_INDICATE_VM_EXISTS: Readonly
> = {
+export const IS_OPENING: Readonly> = {
[ProjectState.created]: false,
[ProjectState.new]: false,
+ [ProjectState.scheduled]: true,
+ [ProjectState.openInProgress]: true,
+ [ProjectState.provisioned]: true,
+ [ProjectState.opened]: false,
+ [ProjectState.closed]: false,
+ [ProjectState.placeholder]: true,
+ [ProjectState.closing]: false,
+}
+
+export const IS_OPENING_OR_OPENED: Readonly> = {
+ [ProjectState.created]: false,
+ [ProjectState.new]: false,
+ [ProjectState.scheduled]: true,
[ProjectState.openInProgress]: true,
[ProjectState.provisioned]: true,
[ProjectState.opened]: true,
@@ -225,8 +239,8 @@ export interface ProjectStartupInfo {
readonly accessToken: string | null
}
-/** Metadata describing an uploaded file. */
-export interface File {
+/** Metadata describing the location of an uploaded file. */
+export interface FileLocator {
readonly fileId: FileId
readonly fileName: string | null
readonly path: S3FilePath
@@ -241,9 +255,17 @@ export interface FileInfo {
readonly project: CreatedProject | null
}
+/** Metadata for a file. */
+export interface FileMetadata {
+ readonly size: number
+}
+
/** All metadata related to a file. */
export interface FileDetails {
- readonly file: File
+ readonly file: FileLocator
+ readonly metadata: FileMetadata
+ /** On the Remote (Cloud) Backend, this is a S3 url that is valid for only 120 seconds. */
+ readonly url?: string
}
/** A secret environment variable. */
@@ -862,7 +884,6 @@ export interface UpdateProjectRequestBody {
/** HTTP request body for the "open project" endpoint. */
export interface OpenProjectRequestBody {
- readonly forceCreate: boolean
readonly executeAsync: boolean
}
@@ -1091,7 +1112,7 @@ export default abstract class Backend {
/** Return project memory, processor and storage usage. */
abstract checkResources(projectId: ProjectId, title: string | null): Promise
/** Return a list of files accessible by the current user. */
- abstract listFiles(): Promise
+ abstract listFiles(): Promise
/** Upload a file. */
abstract uploadFile(params: UploadFileRequestParams, file: Blob): Promise
/** Return file details. */
diff --git a/app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts b/app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts
index 6c4929393626..b02ecbbc776d 100644
--- a/app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts
+++ b/app/ide-desktop/lib/dashboard/src/services/RemoteBackend.ts
@@ -11,7 +11,6 @@ import Backend, * as backendModule from '#/services/Backend'
import * as remoteBackendPaths from '#/services/remoteBackendPaths'
import * as config from '#/utilities/config'
-import * as errorModule from '#/utilities/error'
import type HttpClient from '#/utilities/HttpClient'
import * as object from '#/utilities/object'
@@ -32,9 +31,18 @@ const STATUS_SERVER_ERROR = 500
const ONE_DAY_MS = 86_400_000
/** Default HTTP body for an "open project" request. */
-const DEFAULT_OPEN_PROJECT_BODY: backendModule.OpenProjectRequestBody = {
- forceCreate: false,
- executeAsync: false,
+const DEFAULT_OPEN_PROJECT_BODY: backendModule.OpenProjectRequestBody = { executeAsync: false }
+
+// =============
+// === Types ===
+// =============
+
+/** The format of all errors returned by the backend. */
+interface RemoteBackendError {
+ readonly type: string
+ readonly code: string
+ readonly message: string
+ readonly param: string
}
// ============================
@@ -60,7 +68,7 @@ export async function waitUntilProjectIsReady(
abortController: AbortController = new AbortController()
) {
let project = await backend.getProjectDetails(item.id, item.title)
- if (!backendModule.DOES_PROJECT_STATE_INDICATE_VM_EXISTS[project.state.type]) {
+ if (!backendModule.IS_OPENING_OR_OPENED[project.state.type]) {
await backend.openProject(item.id, null, item.title)
}
let nextCheckTimestamp = 0
@@ -98,7 +106,7 @@ export interface ListProjectsResponseBody {
/** HTTP response body for the "list files" endpoint. */
export interface ListFilesResponseBody {
- readonly files: backendModule.File[]
+ readonly files: backendModule.FileLocator[]
}
/** HTTP response body for the "list secrets" endpoint. */
@@ -141,7 +149,9 @@ export default class RemoteBackend extends Backend {
// All of our API endpoints are authenticated, so we expect the `Authorization` header to be
// set.
if (!new Headers(this.client.defaultHeaders).has('Authorization')) {
- return this.throw('Authorization header not set.')
+ const message = 'Authorization header not set'
+ this.logger.error(message)
+ throw new Error(message)
} else {
if (detect.IS_DEV_MODE) {
// @ts-expect-error This exists only for debugging purposes. It does not have types
@@ -154,7 +164,14 @@ export default class RemoteBackend extends Backend {
/** Log an error message and throws an {@link Error} with the specified message.
* @throws {Error} Always. */
- throw(message: string): never {
+ async throw(prefix: string, response: Response | null): Promise {
+ const error =
+ response == null
+ ? { message: 'unknown error' }
+ : // This is SAFE only when the response has been confirmed to have an erroring status code.
+ // eslint-disable-next-line no-restricted-syntax
+ ((await response.json()) as RemoteBackendError)
+ const message = `${prefix}: ${error.message}.`
this.logger.error(message)
throw new Error(message)
}
@@ -164,7 +181,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.LIST_USERS_PATH
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not list users in the organization.`)
+ return this.throw(`Could not list users in the organization`, response)
} else {
return (await response.json()).users
}
@@ -177,7 +194,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_USER_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not create user.')
+ return this.throw('Could not create user', response)
} else {
return await response.json()
}
@@ -189,9 +206,9 @@ export default class RemoteBackend extends Backend {
const response = await this.put(path, body)
if (!responseIsSuccessful(response)) {
if (body.username != null) {
- return this.throw('Could not change username.')
+ return this.throw('Could not change username', response)
} else {
- return this.throw('Could not update user.')
+ return this.throw('Could not update user', response)
}
} else {
return
@@ -202,7 +219,7 @@ export default class RemoteBackend extends Backend {
override async deleteUser(): Promise {
const response = await this.delete(remoteBackendPaths.DELETE_USER_PATH)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not delete user.')
+ return this.throw('Could not delete user', response)
} else {
return
}
@@ -213,7 +230,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.INVITE_USER_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not invite user '${body.userEmail}'.`)
+ return this.throw(`Could not invite user '${body.userEmail}'`, response)
} else {
return
}
@@ -232,7 +249,7 @@ export default class RemoteBackend extends Backend {
const path = `${remoteBackendPaths.UPLOAD_USER_PICTURE_PATH}?${paramsString}`
const response = await this.putBinary(path, file)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not upload user profile picture.')
+ return this.throw('Could not upload user profile picture', response)
} else {
return await response.json()
}
@@ -247,7 +264,7 @@ export default class RemoteBackend extends Backend {
// Organization info has not yet been created.
return null
} else if (!responseIsSuccessful(response)) {
- return this.throw('Could not get organization.')
+ return this.throw('Could not get organization', response)
} else {
return await response.json()
}
@@ -264,7 +281,7 @@ export default class RemoteBackend extends Backend {
// Organization info has not yet been created.
return null
} else if (!responseIsSuccessful(response)) {
- return this.throw('Could not update organization.')
+ return this.throw('Could not update organization', response)
} else {
return await response.json()
}
@@ -283,7 +300,7 @@ export default class RemoteBackend extends Backend {
const path = `${remoteBackendPaths.UPLOAD_ORGANIZATION_PICTURE_PATH}?${paramsString}`
const response = await this.putBinary(path, file)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not upload user profile picture.')
+ return this.throw('Could not upload user profile picture', response)
} else {
return await response.json()
}
@@ -294,7 +311,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_PERMISSION_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not set permissions.`)
+ return this.throw('Could not set permissions', response)
} else {
return
}
@@ -338,9 +355,9 @@ export default class RemoteBackend extends Backend {
return []
} else if (query.parentId != null) {
const name = title != null ? `'${title}'` : `with ID '${query.parentId}'`
- return this.throw(`Could not list folder ${name}.`)
+ return this.throw(`Could not list folder ${name}`, response)
} else {
- return this.throw('Could not list root folder.')
+ return this.throw('Could not list root folder', response)
}
} else {
return (await response.json()).assets
@@ -366,7 +383,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_DIRECTORY_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create folder with name '${body.title}'.`)
+ return this.throw(`Could not create folder with name '${body.title}'`, response)
} else {
return await response.json()
}
@@ -383,7 +400,7 @@ export default class RemoteBackend extends Backend {
const response = await this.put(path, body)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${directoryId}'`
- return this.throw(`Could not update folder ${name}.`)
+ return this.throw(`Could not update folder ${name}`, response)
} else {
return await response.json()
}
@@ -398,7 +415,7 @@ export default class RemoteBackend extends Backend {
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${assetId}'`
- return this.throw(`Could not list versions for ${name}.`)
+ return this.throw(`Could not list versions for ${name}`, response)
} else {
return await response.json()
}
@@ -415,7 +432,7 @@ export default class RemoteBackend extends Backend {
const response = await this.patch(path, body)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `asset with ID '${assetId}'`
- return this.throw(`Could not update ${name}.`)
+ return this.throw(`Could not update ${name}.`, response)
} else {
return
}
@@ -428,7 +445,7 @@ export default class RemoteBackend extends Backend {
const response = await this.delete(path)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `asset with ID '${assetId}'`
- return this.throw(`Unable to delete ${name}.`)
+ return this.throw(`Unable to delete ${name}.`, response)
} else {
return
}
@@ -446,7 +463,8 @@ export default class RemoteBackend extends Backend {
return this.throw(
`Unable to restore ${
title != null ? `'${title}'` : `asset with ID '${assetId}'`
- } from Trash.`
+ } from Trash`,
+ response
)
} else {
return
@@ -471,7 +489,8 @@ export default class RemoteBackend extends Backend {
parentDirectoryTitle != null
? `'${parentDirectoryTitle}'`
: `directory with ID '${parentDirectoryId}'`
- }.`
+ }`,
+ response
)
} else {
return await response.json()
@@ -484,7 +503,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.LIST_PROJECTS_PATH
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not list projects.')
+ return this.throw('Could not list projects', response)
} else {
return (await response.json()).projects.map(project => ({
...project,
@@ -504,7 +523,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_PROJECT_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create project with name '${body.projectName}'.`)
+ return this.throw(`Could not create project with name '${body.projectName}'`, response)
} else {
return await response.json()
}
@@ -520,7 +539,8 @@ export default class RemoteBackend extends Backend {
const response = await this.post(path, {})
if (!responseIsSuccessful(response)) {
return this.throw(
- `Could not close project ${title != null ? `'${title}'` : `with ID '${projectId}'`}.`
+ `Could not close project ${title != null ? `'${title}'` : `with ID '${projectId}'`}`,
+ response
)
} else {
return
@@ -539,7 +559,8 @@ export default class RemoteBackend extends Backend {
return this.throw(
`Could not get details of project ${
title != null ? `'${title}'` : `with ID '${projectId}'`
- }.`
+ }`,
+ response
)
} else {
const project = await response.json()
@@ -568,7 +589,8 @@ export default class RemoteBackend extends Backend {
const response = await this.post(path, body ?? DEFAULT_OPEN_PROJECT_BODY)
if (!responseIsSuccessful(response)) {
return this.throw(
- `Could not open project ${title != null ? `'${title}'` : `with ID '${projectId}'`}.`
+ `Could not open project ${title != null ? `'${title}'` : `with ID '${projectId}'`}`,
+ response
)
} else {
return
@@ -586,7 +608,8 @@ export default class RemoteBackend extends Backend {
const response = await this.put(path, body)
if (!responseIsSuccessful(response)) {
return this.throw(
- `Could not update project ${title != null ? `'${title}'` : `with ID '${projectId}'`}.`
+ `Could not update project ${title != null ? `'${title}'` : `with ID '${projectId}'`}`,
+ response
)
} else {
return await response.json()
@@ -605,7 +628,8 @@ export default class RemoteBackend extends Backend {
return this.throw(
`Could not get resource usage for project ${
title != null ? `'${title}'` : `with ID '${projectId}'`
- }.`
+ }`,
+ response
)
} else {
return await response.json()
@@ -614,11 +638,11 @@ export default class RemoteBackend extends Backend {
/** Return a list of files accessible by the current user.
* @throws An error if a non-successful status code (not 200-299) was received. */
- override async listFiles(): Promise {
+ override async listFiles(): Promise {
const path = remoteBackendPaths.LIST_FILES_PATH
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not list files.')
+ return this.throw('Could not list files', response)
} else {
return (await response.json()).files
}
@@ -640,19 +664,10 @@ export default class RemoteBackend extends Backend {
const path = `${remoteBackendPaths.UPLOAD_FILE_PATH}?${paramsString}`
const response = await this.postBinary(path, file)
if (!responseIsSuccessful(response)) {
- let suffix = '.'
- try {
- const error = errorModule.tryGetError(await response.json())
- if (error != null) {
- suffix = `: ${error}`
- }
- } catch {
- // Ignored.
- }
if (params.fileId != null) {
- return this.throw(`Could not upload file with ID '${params.fileId}'${suffix}`)
+ return this.throw(`Could not upload file with ID '${params.fileId}'`, response)
} else {
- return this.throw(`Could not upload file${suffix}`)
+ return this.throw('Could not upload file', response)
}
} else {
return await response.json()
@@ -669,7 +684,8 @@ export default class RemoteBackend extends Backend {
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
return this.throw(
- `Could not get details of project ${title != null ? `'${title}'` : `with ID '${fileId}'`}.`
+ `Could not get details of project ${title != null ? `'${title}'` : `with ID '${fileId}'`}`,
+ response
)
} else {
return await response.json()
@@ -684,7 +700,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_CONNECTOR_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create Data Link with name '${body.name}'.`)
+ return this.throw(`Could not create Data Link with name '${body.name}'`, response)
} else {
return await response.json()
}
@@ -700,7 +716,7 @@ export default class RemoteBackend extends Backend {
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${connectorId}'`
- return this.throw(`Could not get Data Link ${name}.`)
+ return this.throw(`Could not get Data Link ${name}`, response)
} else {
return await response.json()
}
@@ -716,7 +732,7 @@ export default class RemoteBackend extends Backend {
const response = await this.delete(path)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${connectorId}'`
- return this.throw(`Could not delete Data Link ${name}.`)
+ return this.throw(`Could not delete Data Link ${name}`, response)
} else {
return
}
@@ -730,7 +746,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_SECRET_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create secret with name '${body.name}'.`)
+ return this.throw(`Could not create secret with name '${body.name}'`, response)
} else {
return await response.json()
}
@@ -746,7 +762,7 @@ export default class RemoteBackend extends Backend {
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${secretId}'`
- return this.throw(`Could not get secret ${name}.`)
+ return this.throw(`Could not get secret ${name}`, response)
} else {
return await response.json()
}
@@ -763,7 +779,7 @@ export default class RemoteBackend extends Backend {
const response = await this.put(path, body)
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${secretId}'`
- return this.throw(`Could not update secret ${name}.`)
+ return this.throw(`Could not update secret ${name}`, response)
} else {
return
}
@@ -775,7 +791,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.LIST_SECRETS_PATH
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw('Could not list secrets.')
+ return this.throw('Could not list secrets', response)
} else {
return (await response.json()).secrets
}
@@ -787,7 +803,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.CREATE_TAG_PATH
const response = await this.post(path, body)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create label '${body.value}'.`)
+ return this.throw(`Could not create label '${body.value}'`, response)
} else {
return await response.json()
}
@@ -799,7 +815,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.LIST_TAGS_PATH
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not list labels.`)
+ return this.throw(`Could not list labels`, response)
} else {
return (await response.json()).tags
}
@@ -816,7 +832,7 @@ export default class RemoteBackend extends Backend {
const response = await this.patch(path, { labels })
if (!responseIsSuccessful(response)) {
const name = title != null ? `'${title}'` : `with ID '${assetId}'`
- return this.throw(`Could not set labels for asset ${name}.`)
+ return this.throw(`Could not set labels for asset ${name}`, response)
} else {
return
}
@@ -831,7 +847,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.deleteTagPath(tagId)
const response = await this.delete(path)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not delete label '${value}'.`)
+ return this.throw(`Could not delete label '${value}'`, response)
} else {
return
}
@@ -850,7 +866,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.LIST_VERSIONS_PATH + '?' + paramsString
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not list versions of type '${params.versionType}'.`)
+ return this.throw(`Could not list versions of type '${params.versionType}'`, response)
} else {
return (await response.json()).versions
}
@@ -866,7 +882,7 @@ export default class RemoteBackend extends Backend {
{ plan } satisfies backendModule.CreateCheckoutSessionRequestBody
)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not create checkout session for plan '${plan}'.`)
+ return this.throw(`Could not create checkout session for plan '${plan}'.`, response)
} else {
return await response.json()
}
@@ -880,7 +896,7 @@ export default class RemoteBackend extends Backend {
const path = remoteBackendPaths.getCheckoutSessionPath(sessionId)
const response = await this.get(path)
if (!responseIsSuccessful(response)) {
- return this.throw(`Could not get checkout session for session ID '${sessionId}'.`)
+ return this.throw(`Could not get checkout session for session ID '${sessionId}'.`, response)
} else {
return await response.json()
}
@@ -895,7 +911,7 @@ export default class RemoteBackend extends Backend {
} else {
const version = (await this.listVersions({ versionType, default: true }))[0]?.number
if (version == null) {
- return this.throw(`No default ${versionType} version found.`)
+ return this.throw(`No default ${versionType} version found`, null)
} else {
const info: DefaultVersionInfo = { version, lastUpdatedEpochMs: nowEpochMs }
this.defaultVersions[versionType] = info
diff --git a/app/ide-desktop/lib/dashboard/src/tailwind.css b/app/ide-desktop/lib/dashboard/src/tailwind.css
index 417eac70158d..8d0ee0b79a97 100644
--- a/app/ide-desktop/lib/dashboard/src/tailwind.css
+++ b/app/ide-desktop/lib/dashboard/src/tailwind.css
@@ -49,7 +49,7 @@ body::before {
.enso-dashboard *:focus,
.enso-chat *:focus {
- outline: none !important;
+ outline: none;
}
/* Must be kept in sync with app/gui/view/graph-editor/src/builtin/visualization/java_script/helpers/scrollable.js. */
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts b/app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts
index 7aa3e14d80d1..cc30cfc1d86b 100644
--- a/app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts
+++ b/app/ide-desktop/lib/dashboard/src/utilities/AssetQuery.ts
@@ -63,6 +63,21 @@ export default class AssetQuery {
['nos', 'no'],
['negativeNos', 'has'],
] as const satisfies readonly (readonly [keyof AssetQueryData, string | null])[]
+ /** The subset of {@link AssetQuery.tagNames} that are applicable for the Local Backend. */
+ // `key` MUST be a string literal type.
+ // eslint-disable-next-line no-restricted-syntax
+ static localTagNames = [
+ ['keywords', null],
+ ['negativeKeywords', '-'],
+ ['names', 'name'],
+ ['negativeNames', '-name'],
+ ['types', 'type'],
+ ['negativeTypes', '-type'],
+ ['extensions', 'extension'],
+ ['negativeExtensions', '-extension'],
+ ['modifieds', 'modified'],
+ ['negativeModifieds', '-modified'],
+ ] as const satisfies readonly (readonly [keyof AssetQueryData, string | null])[]
readonly query
diff --git a/app/ide-desktop/lib/dashboard/src/utilities/ShortcutManager.ts b/app/ide-desktop/lib/dashboard/src/utilities/ShortcutManager.ts
index 63289cc5fcfe..31edcfc71cd2 100644
--- a/app/ide-desktop/lib/dashboard/src/utilities/ShortcutManager.ts
+++ b/app/ide-desktop/lib/dashboard/src/utilities/ShortcutManager.ts
@@ -8,7 +8,6 @@ import AddNetworkIcon from 'enso-assets/add_network.svg'
import AppDownloadIcon from 'enso-assets/app_download.svg'
import BlankIcon from 'enso-assets/blank_16.svg'
import CameraIcon from 'enso-assets/camera.svg'
-import ChangePasswordIcon from 'enso-assets/change_password.svg'
import CloseIcon from 'enso-assets/close.svg'
import CloudToIcon from 'enso-assets/cloud_to.svg'
import CopyIcon from 'enso-assets/copy.svg'
@@ -87,7 +86,6 @@ export enum KeyboardAction {
newDataLink = 'new-data-link',
closeModal = 'close-modal',
cancelEditName = 'cancel-edit-name',
- changeYourPassword = 'change-your-password',
signIn = 'sign-in',
signOut = 'sign-out',
downloadApp = 'download-app',
@@ -293,7 +291,7 @@ export default class ShortcutManager {
const button: number = shortcut.button
return (
button === event.button &&
- event.detail >= shortcut.clicks &&
+ Math.max(event.detail, 1) >= shortcut.clicks &&
modifiersMatchEvent(shortcut, event)
)
}
@@ -471,7 +469,6 @@ const DEFAULT_KEYBOARD_SHORTCUTS: Readonly
col_vals.map col->
- if col.isNa row_num then "Nothing" else get_item_string col row_num
+ if col.isNothing row_num then "Nothing" else get_item_string col row_num
table = print_table col_names rows indices_count format_terminal
if display_rows == all_rows_count then table else
missing_rows_count = all_rows_count - display_rows
diff --git a/distribution/lib/Standard/Google_Api/0.0.0-dev/src/Main.enso b/distribution/lib/Standard/Google_Api/0.0.0-dev/src/Main.enso
index 40e9a228fa1b..21b3ba87a5b7 100644
--- a/distribution/lib/Standard/Google_Api/0.0.0-dev/src/Main.enso
+++ b/distribution/lib/Standard/Google_Api/0.0.0-dev/src/Main.enso
@@ -1,6 +1,8 @@
from Standard.Base import all
import Standard.Base.Data.Array_Proxy.Array_Proxy
-
+import Standard.Base.Metadata.Display
+from Standard.Base.Metadata import make_single_choice, Widget
+from Standard.Base.Metadata.Widget import Single_Choice, Vector_Editor
from Standard.Table import Table
polyglot java import com.google.api.client.googleapis.auth.oauth2.GoogleCredential
@@ -68,29 +70,46 @@ initialize secret_file =
json_factory = GsonFactory.getDefaultInstance
Google_Api_Client.Value credential json_factory http_transport
+## PRIVATE
+make_dimensions_vector_selector : Widget
+make_dimensions_vector_selector =
+ item_editor = make_single_choice ['country', 'date', 'isConversionEvent', 'language', 'userAgeBracket', 'userGender']
+ Vector_Editor item_editor=item_editor item_default=item_editor.values.first.value display=Display.Always
+
+## PRIVATE
+make_metrics_vector_selector : Widget
+make_metrics_vector_selector =
+ item_editor = make_single_choice ['activeUsers', 'bounceRate', 'conversions', 'newUsers', 'sessionsPerUser', 'userConversionRate']
+ Vector_Editor item_editor=item_editor item_default=item_editor.values.first.value display=Display.Always
+
## PLACEHOLDER, performs google analytics call
- This method calls the google reporting v4 api. Presently it specifically returns activeUsers by City
+ This method calls the google reporting v4 api.
Arguments:
- property_id: The Google Analytics property_id that is being queried
- start_date: The beginning date of the query. Default is 2020-03-31
- end_date: The end date being queried. Defaults to today.
-run_analytics_report : Text -> Date -> Date -> Table
-run_analytics_report property_id:Text start_date:Date=(Date.new 2020 3 31) end_date:Date=Date.today -> Table =
+@dimensions make_dimensions_vector_selector
+@metrics make_metrics_vector_selector
+run_analytics_report : Text -> Date -> Date -> (Vector Text) -> (Vector Text) -> Table
+run_analytics_report property_id:Text start_date:Date=(Date.new 2020 3 31) end_date:Date=Date.today dimensions:Vector=['userType'] metrics:Vector=['users'] -> Table =
analytics_data = BetaAnalyticsDataClient.create
- request = RunReportRequest.newBuilder
+ request_builder = RunReportRequest.newBuilder
. setProperty ("properties/"+property_id)
- . addDimensions (Dimension.newBuilder.setName "city")
- . addMetrics (Metric.newBuilder.setName "activeUsers")
. addDateRanges (DateRange.newBuilder.setStartDate start_date.to_text . setEndDate end_date.to_text)
- . build
+ dimensions.distinct.each dimension->
+ request_builder.addDimensions (Dimension.newBuilder.setName dimension)
+ metrics.distinct.each metric->
+ request_builder.addMetrics (Metric.newBuilder.setName metric)
+
+ request = request_builder.build
response = analytics_data.runReport request
dimension_count = response.getDimensionHeadersCount
- dimensions = 0.up_to dimension_count . map i-> response.getDimensionHeaders i . getName
+ dimension_headers = 0.up_to dimension_count . map i-> response.getDimensionHeaders i . getName
metric_count = response.getMetricHeadersCount
- metrics = 0.up_to metric_count . map i-> response.getMetricHeaders i . getName
- headers = dimensions + metrics
+ metric_headers = 0.up_to metric_count . map i-> response.getMetricHeaders i . getName
+ headers = dimension_headers + metric_headers
row_count = response.getRowCount
row_proxy = Array_Proxy.new row_count i->
diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso
index e7388ff41b67..96a3226d4662 100644
--- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso
+++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Column.enso
@@ -161,7 +161,7 @@ type Column
num_rows = java_col.getSize
display_rows = num_rows.min show_rows
items = Vector.new display_rows num->
- row = if storage.isNa num then "Nothing" else
+ row = if storage.isNothing num then "Nothing" else
get_item_string storage num
[num.to_text, row]
table = print_table ["", col_name] items 1 format_terminal
@@ -2141,7 +2141,7 @@ type Column
valid_index = (index >= 0) && (index < self.length)
if valid_index.not then default else
storage = self.java_column.getStorage
- if storage.isNa index then Nothing else
+ if storage.isNothing index then Nothing else
storage.getItem index
## ICON data_input
diff --git a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso
index fa0b101094ea..a67f3a096eb9 100644
--- a/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso
+++ b/distribution/lib/Standard/Table/0.0.0-dev/src/Data/Table.enso
@@ -185,7 +185,7 @@ type Table
display_rows = num_rows.min show_rows
rows = Vector.new display_rows row_num->
cols = col_vals.map col->
- if col.isNa row_num then "Nothing" else get_item_string col row_num
+ if col.isNothing row_num then "Nothing" else get_item_string col row_num
[row_num.to_text] + cols
table = print_table col_names rows 1 format_terminal
if num_rows - display_rows <= 0 then table else
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java
index 96a784dbb629..7d4495c90181 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BigIntegerBuilder.java
@@ -113,7 +113,7 @@ public void appendBulkStorage(Storage> storage) {
if (storage instanceof AbstractLongStorage longStorage) {
int n = longStorage.size();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
data[currentSize++] = null;
} else {
long item = longStorage.getItem(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java
index a13585f78171..a92fe3751641 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/BoolBuilder.java
@@ -11,23 +11,23 @@
/** A builder for boolean columns. */
public class BoolBuilder extends TypedBuilder {
private final BitSet vals;
- private final BitSet isNa;
+ private final BitSet isNothing;
int size = 0;
public BoolBuilder() {
vals = new BitSet();
- isNa = new BitSet();
+ isNothing = new BitSet();
}
public BoolBuilder(int capacity) {
vals = new BitSet(capacity);
- isNa = new BitSet(capacity);
+ isNothing = new BitSet(capacity);
}
@Override
public void appendNoGrow(Object o) {
if (o == null) {
- isNa.set(size);
+ isNothing.set(size);
} else {
if (o instanceof Boolean b) {
if (b) {
@@ -64,7 +64,7 @@ public void appendBoolean(boolean data) {
@Override
public void appendNulls(int count) {
- isNa.set(size, size + count);
+ isNothing.set(size, size + count);
size += count;
}
@@ -73,7 +73,7 @@ public void appendBulkStorage(Storage> storage) {
if (storage.getType().equals(getType())) {
if (storage instanceof BoolStorage boolStorage) {
BitSets.copy(boolStorage.getValues(), vals, size, boolStorage.size());
- BitSets.copy(boolStorage.getIsMissing(), isNa, size, boolStorage.size());
+ BitSets.copy(boolStorage.getIsNothingMap(), isNothing, size, boolStorage.size());
size += boolStorage.size();
} else {
throw new IllegalStateException(
@@ -88,7 +88,7 @@ public void appendBulkStorage(Storage> storage) {
@Override
public Storage seal() {
- return new BoolStorage(vals, isNa, size, false);
+ return new BoolStorage(vals, isNothing, size, false);
}
@Override
@@ -99,7 +99,7 @@ public int getCurrentSize() {
@Override
public void retypeToMixed(Object[] items) {
for (int i = 0; i < size; i++) {
- if (isNa.get(i)) {
+ if (isNothing.get(i)) {
items[i] = null;
} else {
items[i] = vals.get(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java
index 3c2bf8097308..f915ab4dcb74 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/DoubleBuilder.java
@@ -23,8 +23,8 @@
/** A builder for floating point columns. */
public class DoubleBuilder extends NumericBuilder {
DoubleBuilder(
- BitSet isMissing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
- super(isMissing, data, currentSize);
+ BitSet isNothing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
+ super(isNothing, data, currentSize);
precisionLossAggregator = new PrecisionLossAggregator(problemAggregator);
}
@@ -55,7 +55,7 @@ public StorageType getType() {
@Override
public void appendNoGrow(Object o) {
if (o == null) {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
} else if (NumericConverter.isFloatLike(o)) {
double value = NumericConverter.coerceToDouble(o);
data[currentSize++] = Double.doubleToRawLongBits(value);
@@ -83,7 +83,7 @@ public void appendBulkStorage(Storage> storage) {
int n = doubleStorage.size();
ensureFreeSpaceFor(n);
System.arraycopy(doubleStorage.getRawData(), 0, data, currentSize, n);
- BitSets.copy(doubleStorage.getIsMissing(), isMissing, currentSize, n);
+ BitSets.copy(doubleStorage.getIsNothingMap(), isNothing, currentSize, n);
currentSize += n;
} else {
throw new IllegalStateException(
@@ -94,7 +94,7 @@ public void appendBulkStorage(Storage> storage) {
} else if (storage.getType() instanceof IntegerType) {
if (storage instanceof AbstractLongStorage longStorage) {
int n = longStorage.size();
- BitSets.copy(longStorage.getIsMissing(), isMissing, currentSize, n);
+ BitSets.copy(longStorage.getIsNothingMap(), isNothing, currentSize, n);
for (int i = 0; i < n; i++) {
long item = longStorage.getItem(i);
double converted = convertIntegerToDouble(item);
@@ -112,7 +112,7 @@ public void appendBulkStorage(Storage> storage) {
for (int i = 0; i < n; i++) {
BigInteger item = bigIntegerStorage.getItem(i);
if (item == null) {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
} else {
double converted = convertBigIntegerToDouble(item);
data[currentSize++] = Double.doubleToRawLongBits(converted);
@@ -128,8 +128,8 @@ public void appendBulkStorage(Storage> storage) {
if (storage instanceof BoolStorage boolStorage) {
int n = boolStorage.size();
for (int i = 0; i < n; i++) {
- if (boolStorage.isNa(i)) {
- isMissing.set(currentSize++);
+ if (boolStorage.isNothing(i)) {
+ isNothing.set(currentSize++);
} else {
double x = ToFloatStorageConverter.booleanAsDouble(boolStorage.getItem(i));
data[currentSize++] = Double.doubleToRawLongBits(x);
@@ -183,7 +183,7 @@ public void appendBigInteger(BigInteger integer) {
@Override
public Storage seal() {
- return new DoubleStorage(data, currentSize, isMissing);
+ return new DoubleStorage(data, currentSize, isNothing);
}
/**
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferringDoubleBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferringDoubleBuilder.java
index 44758a03c19b..55977439ed28 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferringDoubleBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/InferringDoubleBuilder.java
@@ -19,11 +19,11 @@ static InferringDoubleBuilder retypeFromLongBuilder(LongBuilder longBuilder) {
int currentSize = longBuilder.currentSize;
InferringDoubleBuilder newBuilder =
new InferringDoubleBuilder(
- longBuilder.isMissing, longBuilder.data, currentSize, longBuilder.problemAggregator);
+ longBuilder.isNothing, longBuilder.data, currentSize, longBuilder.problemAggregator);
// Invalidate the old builder.
longBuilder.data = null;
- longBuilder.isMissing = null;
+ longBuilder.isNothing = null;
longBuilder.currentSize = -1;
// Assume all longs will be compacted.
@@ -31,7 +31,7 @@ static InferringDoubleBuilder retypeFromLongBuilder(LongBuilder longBuilder) {
// Translate the data in-place to avoid unnecessary allocations.
for (int i = 0; i < currentSize; i++) {
- if (!newBuilder.isMissing.get(i)) {
+ if (!newBuilder.isNothing.get(i)) {
long currentIntegerValue = newBuilder.data[i];
double convertedFloatValue = (double) currentIntegerValue;
boolean isLossy = currentIntegerValue != (long) convertedFloatValue;
@@ -52,8 +52,8 @@ static InferringDoubleBuilder retypeFromLongBuilder(LongBuilder longBuilder) {
}
InferringDoubleBuilder(
- BitSet isMissing, long[] doubleData, int currentSize, ProblemAggregator problemAggregator) {
- super(isMissing, doubleData, currentSize, problemAggregator);
+ BitSet isNothing, long[] doubleData, int currentSize, ProblemAggregator problemAggregator) {
+ super(isNothing, doubleData, currentSize, problemAggregator);
rawData = null;
isLongCompactedAsDouble = new BitSet();
}
@@ -81,7 +81,7 @@ static InferringDoubleBuilder retypeFromLongBuilder(LongBuilder longBuilder) {
public void retypeToMixed(Object[] items) {
int rawN = rawData == null ? 0 : rawData.length;
for (int i = 0; i < currentSize; i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
items[i] = null;
} else {
if (isLongCompactedAsDouble.get(i)) {
@@ -157,7 +157,7 @@ public void appendBigInteger(BigInteger integer) {
@Override
public void appendNoGrow(Object o) {
if (o == null) {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
} else if (NumericConverter.isFloatLike(o)) {
double value = NumericConverter.coerceToDouble(o);
data[currentSize++] = Double.doubleToRawLongBits(value);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java
index 65d0cece24f4..e56e4b86722b 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilder.java
@@ -21,25 +21,25 @@ public abstract class LongBuilder extends NumericBuilder {
protected final ProblemAggregator problemAggregator;
protected LongBuilder(
- BitSet isMissing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
- super(isMissing, data, currentSize);
+ BitSet isNothing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
+ super(isNothing, data, currentSize);
this.problemAggregator = problemAggregator;
}
static LongBuilder make(int initialSize, IntegerType type, ProblemAggregator problemAggregator) {
- BitSet isMissing = new BitSet();
+ BitSet isNothing = new BitSet();
long[] data = new long[initialSize];
if (type.equals(IntegerType.INT_64)) {
- return new LongBuilderUnchecked(isMissing, data, 0, problemAggregator);
+ return new LongBuilderUnchecked(isNothing, data, 0, problemAggregator);
} else {
- return new LongBuilderChecked(isMissing, data, 0, type, problemAggregator);
+ return new LongBuilderChecked(isNothing, data, 0, type, problemAggregator);
}
}
@Override
public void retypeToMixed(Object[] items) {
for (int i = 0; i < currentSize; i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
items[i] = null;
} else {
items[i] = data[i];
@@ -80,15 +80,15 @@ public void appendBulkStorage(Storage> storage) {
int n = longStorage.size();
ensureFreeSpaceFor(n);
System.arraycopy(longStorage.getRawData(), 0, data, currentSize, n);
- BitSets.copy(longStorage.getIsMissing(), isMissing, currentSize, n);
+ BitSets.copy(longStorage.getIsNothingMap(), isNothing, currentSize, n);
currentSize += n;
} else if (storage.getType() instanceof IntegerType otherType && getType().fits(otherType)) {
if (storage instanceof AbstractLongStorage longStorage) {
int n = longStorage.size();
ensureFreeSpaceFor(n);
for (int i = 0; i < n; i++) {
- if (longStorage.isNa(i)) {
- isMissing.set(currentSize++);
+ if (longStorage.isNothing(i)) {
+ isNothing.set(currentSize++);
} else {
appendLongNoGrow(longStorage.getItem(i));
}
@@ -103,8 +103,8 @@ public void appendBulkStorage(Storage> storage) {
if (storage instanceof BoolStorage boolStorage) {
int n = boolStorage.size();
for (int i = 0; i < n; i++) {
- if (boolStorage.isNa(i)) {
- isMissing.set(currentSize++);
+ if (boolStorage.isNothing(i)) {
+ isNothing.set(currentSize++);
} else {
data[currentSize++] = ToIntegerStorageConverter.booleanAsLong(boolStorage.getItem(i));
}
@@ -147,6 +147,6 @@ public void appendLongUnchecked(long data) {
@Override
public Storage seal() {
- return new LongStorage(data, currentSize, isMissing, getType());
+ return new LongStorage(data, currentSize, isNothing, getType());
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderChecked.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderChecked.java
index 10129429f757..47ac9751c73f 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderChecked.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderChecked.java
@@ -13,12 +13,12 @@ public class LongBuilderChecked extends LongBuilder {
private final CastProblemAggregator castProblemAggregator;
protected LongBuilderChecked(
- BitSet isMissing,
+ BitSet isNothing,
long[] data,
int currentSize,
IntegerType type,
ProblemAggregator problemAggregator) {
- super(isMissing, data, currentSize, problemAggregator);
+ super(isNothing, data, currentSize, problemAggregator);
this.type = type;
// Currently we have no correlation with column name, and it may not be necessary for now.
@@ -31,7 +31,7 @@ protected LongBuilderChecked(
@Override
public void appendNoGrow(Object o) {
if (o == null) {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
} else {
Long x = NumericConverter.tryConvertingToLong(o);
if (x != null) {
@@ -52,7 +52,7 @@ public void appendLongNoGrow(long x) {
if (type.fits(x)) {
data[currentSize++] = x;
} else {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
castProblemAggregator.reportNumberOutOfRange(x);
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderUnchecked.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderUnchecked.java
index c2d315fa42cd..b899eb283de2 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderUnchecked.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/LongBuilderUnchecked.java
@@ -12,14 +12,14 @@
*/
public class LongBuilderUnchecked extends LongBuilder {
protected LongBuilderUnchecked(
- BitSet isMissing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
- super(isMissing, data, currentSize, problemAggregator);
+ BitSet isNothing, long[] data, int currentSize, ProblemAggregator problemAggregator) {
+ super(isNothing, data, currentSize, problemAggregator);
}
@Override
public void appendNoGrow(Object o) {
if (o == null) {
- isMissing.set(currentSize++);
+ isNothing.set(currentSize++);
} else {
Long x = NumericConverter.tryConvertingToLong(o);
if (x != null) {
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/builder/NumericBuilder.java b/std-bits/table/src/main/java/org/enso/table/data/column/builder/NumericBuilder.java
index a2527cb8b15c..a2bbacedf7ac 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/builder/NumericBuilder.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/builder/NumericBuilder.java
@@ -7,12 +7,12 @@
/** A common base for numeric builders. */
public abstract class NumericBuilder extends TypedBuilder {
- protected BitSet isMissing;
+ protected BitSet isNothing;
protected long[] data;
protected int currentSize;
- NumericBuilder(BitSet isMissing, long[] data, int currentSize) {
- this.isMissing = isMissing;
+ NumericBuilder(BitSet isNothing, long[] data, int currentSize) {
+ this.isNothing = isNothing;
this.data = data;
this.currentSize = currentSize;
}
@@ -38,7 +38,7 @@ public static LongBuilder createLongBuilder(
@Override
public void appendNulls(int count) {
- isMissing.set(currentSize, currentSize + count);
+ isNothing.set(currentSize, currentSize + count);
currentSize += count;
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java
index bc035013eebb..7f489254dccd 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToBigIntegerConverter.java
@@ -34,7 +34,7 @@ private Storage convertDoubleStorage(
int n = doubleStorage.size();
BigIntegerBuilder builder = new BigIntegerBuilder(n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (doubleStorage.isNa(i)) {
+ if (doubleStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
double x = doubleStorage.getItemAsDouble(i);
@@ -50,7 +50,7 @@ private Storage convertLongStorage(
int n = longStorage.size();
BigIntegerBuilder builder = new BigIntegerBuilder(n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (longStorage.isNa(i)) {
+ if (longStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
long x = longStorage.getItem(i);
@@ -66,7 +66,7 @@ private Storage convertBoolStorage(
int n = boolStorage.size();
BigIntegerBuilder builder = new BigIntegerBuilder(n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (boolStorage.isNa(i)) {
+ if (boolStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
boolean x = boolStorage.getItem(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java
index 52fdcaa96d2f..13102e4cff6c 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToFloatStorageConverter.java
@@ -75,7 +75,7 @@ private Storage convertLongStorage(
int n = longStorage.size();
DoubleBuilder builder = NumericBuilder.createDoubleBuilder(n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (longStorage.isNa(i)) {
+ if (longStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
long value = longStorage.getItem(i);
@@ -91,7 +91,7 @@ private Storage convertBoolStorage(
int n = boolStorage.size();
DoubleBuilder builder = NumericBuilder.createDoubleBuilder(n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (boolStorage.isNa(i)) {
+ if (boolStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
boolean value = boolStorage.getItem(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java
index d9606e0ee82c..8a98b3ef6f7c 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToIntegerStorageConverter.java
@@ -97,7 +97,7 @@ private Storage convertBoolStorage(
int n = boolStorage.size();
LongBuilder builder = NumericBuilder.createLongBuilder(n, targetType, problemAggregator);
for (int i = 0; i < n; i++) {
- if (boolStorage.isNa(i)) {
+ if (boolStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
boolean value = boolStorage.getItem(i);
@@ -116,7 +116,7 @@ private Storage convertDoubleStorage(
int n = doubleStorage.size();
LongBuilder builder = NumericBuilder.createLongBuilder(n, targetType, problemAggregator);
for (int i = 0; i < n; i++) {
- if (doubleStorage.isNa(i)) {
+ if (doubleStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
double value = doubleStorage.getItemAsDouble(i);
@@ -147,14 +147,14 @@ private Storage convertLongStorage(
Context context = Context.getCurrent();
int n = longStorage.size();
long[] data = new long[n];
- BitSet isMissing = BitSets.makeDuplicate(longStorage.getIsMissing());
+ BitSet isNothing = BitSets.makeDuplicate(longStorage.getIsNothingMap());
for (int i = 0; i < n; i++) {
- if (!isMissing.get(i)) {
+ if (!isNothing.get(i)) {
long value = longStorage.getItem(i);
if (targetType.fits(value)) {
data[i] = value;
} else {
- isMissing.set(i);
+ isNothing.set(i);
problemAggregator.reportNumberOutOfRange(value);
}
}
@@ -162,7 +162,7 @@ private Storage convertLongStorage(
context.safepoint();
}
- return new LongStorage(data, n, isMissing, targetType);
+ return new LongStorage(data, n, isNothing, targetType);
}
}
@@ -171,22 +171,22 @@ private Storage convertBigIntegerStorage(
Context context = Context.getCurrent();
int n = storage.size();
long[] data = new long[n];
- BitSet isMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
BigInteger value = storage.getItemBoxed(i);
if (value == null) {
- isMissing.set(i);
+ isNothing.set(i);
} else if (targetType.fits(value)) {
data[i] = value.longValue();
} else {
- isMissing.set(i);
+ isNothing.set(i);
problemAggregator.reportNumberOutOfRange(value);
}
context.safepoint();
}
- return new LongStorage(data, n, isMissing, targetType);
+ return new LongStorage(data, n, isNothing, targetType);
}
public static long booleanAsLong(boolean value) {
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java
index a75604605e9e..3c1afce68cca 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/cast/ToTextStorageConverter.java
@@ -101,7 +101,7 @@ private Storage castLongStorage(
Context context = Context.getCurrent();
StringBuilder builder = new StringBuilder(longStorage.size(), targetType);
for (int i = 0; i < longStorage.size(); i++) {
- if (longStorage.isNa(i)) {
+ if (longStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
long value = longStorage.getItem(i);
@@ -119,7 +119,7 @@ private Storage castBoolStorage(
Context context = Context.getCurrent();
StringBuilder builder = new StringBuilder(boolStorage.size(), targetType);
for (int i = 0; i < boolStorage.size(); i++) {
- if (boolStorage.isNa(i)) {
+ if (boolStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
boolean value = boolStorage.getItem(i);
@@ -137,7 +137,7 @@ private Storage castDoubleStorage(
Context context = Context.getCurrent();
StringBuilder builder = new StringBuilder(doubleStorage.size(), targetType);
for (int i = 0; i < doubleStorage.size(); i++) {
- if (doubleStorage.isNa(i)) {
+ if (doubleStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
double value = doubleStorage.getItemAsDouble(i);
@@ -155,7 +155,7 @@ private Storage castDateTimeStorage(
Context context = Context.getCurrent();
StringBuilder builder = new StringBuilder(storage.size(), targetType);
for (int i = 0; i < storage.size(); i++) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
builder.appendNulls(1);
} else {
T value = storage.getItemBoxed(i);
@@ -192,7 +192,7 @@ private Storage adaptStringStorage(
Context context = Context.getCurrent();
StringBuilder builder = new StringBuilder(stringStorage.size(), targetType);
for (int i = 0; i < stringStorage.size(); i++) {
- if (stringStorage.isNa(i)) {
+ if (stringStorage.isNothing(i)) {
builder.appendNulls(1);
} else {
String value = stringStorage.getItem(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java
index f06d727ab88c..a25102d4df05 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/GenericBinaryObjectMapOperation.java
@@ -42,7 +42,7 @@ public Storage> runBinaryMap(
Builder builder = createOutputBuilder(n);
Context context = Context.getCurrent();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
builder.appendNulls(1);
} else {
OutputType result = run(storage.getItemBoxed(i), casted);
@@ -67,7 +67,7 @@ public Storage> runZip(
Builder builder = createOutputBuilder(n);
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
- if (storage.isNa(i) || otherCasted.isNa(i)) {
+ if (storage.isNothing(i) || otherCasted.isNothing(i)) {
builder.appendNulls(1);
} else {
InputType left = storage.getItemBoxed(i);
@@ -85,7 +85,7 @@ public Storage> runZip(
Builder builder = createOutputBuilder(n);
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
- if (storage.isNa(i) || arg.isNa(i)) {
+ if (storage.isNothing(i) || arg.isNothing(i)) {
builder.appendNulls(1);
} else {
InputType left = storage.getItemBoxed(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java
index 9409ca1d7862..1c33277d1376 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/SpecializedIsInOp.java
@@ -55,23 +55,22 @@ public Storage> runMap(S storage, List> arg) {
Context context = Context.getCurrent();
CompactRepresentation compactRepresentation = prepareList(arg);
BitSet newVals = new BitSet();
- BitSet missing = new BitSet();
- if (arg.size() > 0) {
+ BitSet isNothing = new BitSet();
+ if (!arg.isEmpty()) {
for (int i = 0; i < storage.size(); i++) {
- if (storage.isNa(i)) {
- missing.set(i);
+ if (storage.isNothing(i)) {
+ isNothing.set(i);
} else if (compactRepresentation.coercedValues.contains(storage.getItemBoxed(i))) {
newVals.set(i);
} else if (compactRepresentation.hasNulls) {
- missing.set(i);
- } else {
- // Leave as default=false
+ isNothing.set(i);
}
+ // Otherwise leave as default=false
context.safepoint();
}
}
- return new BoolStorage(newVals, missing, storage.size(), false);
+ return new BoolStorage(newVals, isNothing, storage.size(), false);
}
@Override
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java
index b19f687e2c8a..80a9cd7b4797 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/bool/BooleanIsInOp.java
@@ -62,28 +62,32 @@ public Storage> runZip(
private BoolStorage run(BoolStorage storage, boolean hadNull, boolean hadTrue, boolean hadFalse) {
int size = storage.size();
ImmutableBitSet values = new ImmutableBitSet(storage.getValues(), size);
- ImmutableBitSet missing = new ImmutableBitSet(storage.getIsMissing(), size);
+ ImmutableBitSet isNothing = new ImmutableBitSet(storage.getIsNothingMap(), size);
boolean negated = storage.isNegated();
ImmutableBitSet newValues;
- ImmutableBitSet newMissing;
+ ImmutableBitSet newIsNothing;
if (hadTrue && !hadFalse) {
- newValues = storage.isNegated() ? missing.notAndNot(values) : missing.notAnd(values);
- newMissing =
- hadNull ? (storage.isNegated() ? missing.or(values) : missing.orNot(values)) : missing;
+ newValues = storage.isNegated() ? isNothing.notAndNot(values) : isNothing.notAnd(values);
+ newIsNothing =
+ hadNull
+ ? (storage.isNegated() ? isNothing.or(values) : isNothing.orNot(values))
+ : isNothing;
} else if (!hadTrue && hadFalse) {
- newValues = storage.isNegated() ? missing.notAnd(values) : missing.notAndNot(values);
- newMissing =
- hadNull ? (storage.isNegated() ? missing.orNot(values) : missing.or(values)) : missing;
- } else if (hadTrue && hadFalse) {
- newValues = missing.not();
- newMissing = missing;
+ newValues = storage.isNegated() ? isNothing.notAnd(values) : isNothing.notAndNot(values);
+ newIsNothing =
+ hadNull
+ ? (storage.isNegated() ? isNothing.orNot(values) : isNothing.or(values))
+ : isNothing;
+ } else if (hadTrue) {
+ newValues = isNothing.not();
+ newIsNothing = isNothing;
} else {
newValues = ImmutableBitSet.allFalse(size);
- newMissing = hadNull ? ImmutableBitSet.allTrue(size) : ImmutableBitSet.allFalse(size);
+ newIsNothing = hadNull ? ImmutableBitSet.allTrue(size) : ImmutableBitSet.allFalse(size);
}
- return new BoolStorage(newValues.toBitSet(), newMissing.toBitSet(), size, false);
+ return new BoolStorage(newValues.toBitSet(), newIsNothing.toBitSet(), size, false);
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java
index badd717f6af4..28439815b769 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/DoubleRoundOp.java
@@ -39,10 +39,10 @@ public Storage> runTernaryMap(
if (decimalPlaces <= 0) {
// Return Long storage
long[] out = new long[storage.size()];
- BitSet isMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
double item = storage.getItemAsDouble(i);
boolean special = Double.isNaN(item) || Double.isInfinite(item);
if (!special) {
@@ -50,22 +50,22 @@ public Storage> runTernaryMap(
} else {
String msg = "Value is " + item;
problemAggregator.reportArithmeticError(msg, i);
- isMissing.set(i);
+ isNothing.set(i);
}
} else {
- isMissing.set(i);
+ isNothing.set(i);
}
context.safepoint();
}
- return new LongStorage(out, storage.size(), isMissing, IntegerType.INT_64);
+ return new LongStorage(out, storage.size(), isNothing, IntegerType.INT_64);
} else {
// Return double storage.
DoubleBuilder doubleBuilder =
NumericBuilder.createDoubleBuilder(storage.size(), problemAggregator);
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
double item = storage.getItemAsDouble(i);
boolean special = Double.isNaN(item) || Double.isInfinite(item);
if (!special) {
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java
index 505cd3541a83..6d247b27dbad 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/LongRoundOp.java
@@ -45,10 +45,10 @@ public Storage runTernaryMap(
Context context = Context.getCurrent();
long[] out = new long[storage.size()];
- BitSet isMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
long item = storage.getItem(i);
boolean outOfRange = item < ROUND_MIN_LONG || item > ROUND_MAX_LONG;
if (!outOfRange) {
@@ -62,16 +62,16 @@ public Storage runTernaryMap(
+ " (inclusive), but was "
+ item;
problemAggregator.reportIllegalArgumentError(msg, i);
- isMissing.set(i);
+ isNothing.set(i);
}
} else {
- isMissing.set(i);
+ isNothing.set(i);
}
context.safepoint();
}
- return new LongStorage(out, storage.size(), isMissing, IntegerType.INT_64);
+ return new LongStorage(out, storage.size(), isNothing, IntegerType.INT_64);
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java
index ae03315f549d..ede9667b08e6 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/arithmetic/NumericBinaryOpImplementation.java
@@ -122,10 +122,10 @@ protected DoubleStorage runDoubleZip(
int n = a.size();
int m = Math.min(a.size(), b.size());
long[] out = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < m; i++) {
- if (a.isNa(i) || b.isNa(i)) {
- newMissing.set(i);
+ if (a.isNothing(i) || b.isNothing(i)) {
+ isNothing.set(i);
} else {
double r = doDouble(a.getItemAsDouble(i), b.getItemAsDouble(i), i, problemAggregator);
out[i] = Double.doubleToRawLongBits(r);
@@ -135,10 +135,10 @@ protected DoubleStorage runDoubleZip(
}
if (m < n) {
- newMissing.set(m, n);
+ isNothing.set(m, n);
}
- return new DoubleStorage(out, n, newMissing);
+ return new DoubleStorage(out, n, isNothing);
}
private static Storage extends Number> allNullStorageOfSameType(Storage> storage) {
@@ -161,10 +161,10 @@ protected DoubleStorage runDoubleMap(
Context context = Context.getCurrent();
int n = a.size();
long[] out = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (a.isNa(i)) {
- newMissing.set(i);
+ if (a.isNothing(i)) {
+ isNothing.set(i);
} else {
double r = doDouble(a.getItemAsDouble(i), bNonNull, i, problemAggregator);
out[i] = Double.doubleToRawLongBits(r);
@@ -173,7 +173,7 @@ protected DoubleStorage runDoubleMap(
context.safepoint();
}
- return new DoubleStorage(out, n, newMissing);
+ return new DoubleStorage(out, n, isNothing);
}
protected LongStorage runLongZip(
@@ -184,14 +184,14 @@ protected LongStorage runLongZip(
int n = a.size();
int m = Math.min(a.size(), b.size());
long[] out = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < m; i++) {
- if (a.isNa(i) || b.isNa(i)) {
- newMissing.set(i);
+ if (a.isNothing(i) || b.isNothing(i)) {
+ isNothing.set(i);
} else {
Long r = doLong(a.getItem(i), b.getItem(i), i, problemAggregator);
if (r == null) {
- newMissing.set(i);
+ isNothing.set(i);
} else {
out[i] = r;
}
@@ -201,10 +201,10 @@ protected LongStorage runLongZip(
}
if (m < n) {
- newMissing.set(m, n);
+ isNothing.set(m, n);
}
- return new LongStorage(out, n, newMissing, INTEGER_RESULT_TYPE);
+ return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE);
}
protected LongStorage runLongMap(
@@ -217,14 +217,14 @@ protected LongStorage runLongMap(
Context context = Context.getCurrent();
int n = a.size();
long[] out = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (a.isNa(i)) {
- newMissing.set(i);
+ if (a.isNothing(i)) {
+ isNothing.set(i);
} else {
Long r = doLong(a.getItem(i), bNonNull, i, problemAggregator);
if (r == null) {
- newMissing.set(i);
+ isNothing.set(i);
} else {
out[i] = r;
}
@@ -233,7 +233,7 @@ protected LongStorage runLongMap(
context.safepoint();
}
- return new LongStorage(out, n, newMissing, INTEGER_RESULT_TYPE);
+ return new LongStorage(out, n, isNothing, INTEGER_RESULT_TYPE);
}
protected BigIntegerStorage runBigIntegerZip(
@@ -244,24 +244,16 @@ protected BigIntegerStorage runBigIntegerZip(
int n = a.size();
int m = Math.min(a.size(), b.size());
BigInteger[] out = new BigInteger[n];
- BitSet newMissing = new BitSet();
for (int i = 0; i < m; i++) {
BigInteger x = a.getItem(i);
BigInteger y = b.getItem(i);
- if (x == null || y == null) {
- newMissing.set(i);
- } else {
+ if (x != null && y != null) {
BigInteger r = doBigInteger(x, y, i, problemAggregator);
out[i] = r;
}
-
context.safepoint();
}
- if (m < n) {
- newMissing.set(m, n);
- }
-
return new BigIntegerStorage(out, n);
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java
index 8efe80a86746..fcef5f955574 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/comparisons/NumericComparison.java
@@ -67,13 +67,13 @@ public BoolStorage runBinaryMap(
return runDoubleMap(lhs, rhs, problemAggregator);
} else {
int n = storage.size();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
BitSet comparisonResults = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
Object item = storage.getItemBoxed(i);
if (item == null) {
- missing.set(i);
+ isNothing.set(i);
} else {
boolean r = onOtherType(item, arg);
if (r) {
@@ -84,7 +84,7 @@ public BoolStorage runBinaryMap(
context.safepoint();
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
}
@@ -92,10 +92,10 @@ protected BoolStorage runLongMap(
AbstractLongStorage lhs, long rhs, MapOperationProblemAggregator problemAggregator) {
int n = lhs.size();
BitSet comparisonResults = new BitSet();
- BitSet missing = BitSets.makeDuplicate(lhs.getIsMissing());
+ BitSet isNothing = BitSets.makeDuplicate(lhs.getIsNothingMap());
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
- if (!lhs.isNa(i)) {
+ if (!lhs.isNothing(i)) {
long item = lhs.getItem(i);
boolean r = doLong(item, rhs);
if (r) {
@@ -106,18 +106,18 @@ protected BoolStorage runLongMap(
context.safepoint();
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
protected BoolStorage runDoubleMap(
DoubleArrayAdapter lhs, double rhs, MapOperationProblemAggregator problemAggregator) {
int n = lhs.size();
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
- if (lhs.isNa(i)) {
- missing.set(i);
+ if (lhs.isNothing(i)) {
+ isNothing.set(i);
} else {
double item = lhs.getItemAsDouble(i);
boolean r = doDouble(item, rhs);
@@ -129,19 +129,19 @@ protected BoolStorage runDoubleMap(
context.safepoint();
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
protected BoolStorage runBigIntegerMap(
BigIntegerArrayAdapter lhs, BigInteger rhs, MapOperationProblemAggregator problemAggregator) {
int n = lhs.size();
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < n; ++i) {
BigInteger item = lhs.getItem(i);
if (item == null) {
- missing.set(i);
+ isNothing.set(i);
} else {
boolean r = doBigInteger(item, rhs);
if (r) {
@@ -152,7 +152,7 @@ protected BoolStorage runBigIntegerMap(
context.safepoint();
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
@Override
@@ -208,11 +208,11 @@ protected BoolStorage runLongZip(
int n = lhs.size();
int m = Math.min(lhs.size(), rhs.size());
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < m; ++i) {
- if (lhs.isNa(i) || rhs.isNa(i)) {
- missing.set(i);
+ if (lhs.isNothing(i) || rhs.isNothing(i)) {
+ isNothing.set(i);
} else {
long x = lhs.getItem(i);
long y = rhs.getItem(i);
@@ -226,10 +226,10 @@ protected BoolStorage runLongZip(
}
if (m < n) {
- missing.set(m, n);
+ isNothing.set(m, n);
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
protected BoolStorage runDoubleZip(
@@ -239,11 +239,11 @@ protected BoolStorage runDoubleZip(
int n = lhs.size();
int m = Math.min(lhs.size(), rhs.size());
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < m; ++i) {
- if (lhs.isNa(i) || rhs.isNa(i)) {
- missing.set(i);
+ if (lhs.isNothing(i) || rhs.isNothing(i)) {
+ isNothing.set(i);
} else {
double x = lhs.getItemAsDouble(i);
double y = rhs.getItemAsDouble(i);
@@ -257,10 +257,10 @@ protected BoolStorage runDoubleZip(
}
if (m < n) {
- missing.set(m, n);
+ isNothing.set(m, n);
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
protected BoolStorage runBigIntegerZip(
@@ -270,13 +270,13 @@ protected BoolStorage runBigIntegerZip(
int n = lhs.size();
int m = Math.min(lhs.size(), rhs.size());
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < m; ++i) {
BigInteger x = lhs.getItem(i);
BigInteger y = rhs.getItem(i);
if (x == null || y == null) {
- missing.set(i);
+ isNothing.set(i);
} else {
boolean r = doBigInteger(x, y);
if (r) {
@@ -288,10 +288,10 @@ protected BoolStorage runBigIntegerZip(
}
if (m < n) {
- missing.set(m, n);
+ isNothing.set(m, n);
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
protected BoolStorage runMixedZip(
@@ -299,13 +299,13 @@ protected BoolStorage runMixedZip(
int n = lhs.size();
int m = Math.min(lhs.size(), rhs.size());
BitSet comparisonResults = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < m; ++i) {
Object x = lhs.getItemBoxed(i);
Object y = rhs.getItemBoxed(i);
if (x == null || y == null) {
- missing.set(i);
+ isNothing.set(i);
} else {
boolean r = false;
// Any number is coercible to double, if the value is not coercible, it is not a supported
@@ -341,9 +341,9 @@ protected BoolStorage runMixedZip(
}
if (m < n) {
- missing.set(m, n);
+ isNothing.set(m, n);
}
- return new BoolStorage(comparisonResults, missing, n, false);
+ return new BoolStorage(comparisonResults, isNothing, n, false);
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java
index 62f2bbc919c2..2d6032791dbe 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/BigIntegerArrayAdapter.java
@@ -44,7 +44,7 @@ private LongStorageAsBigInteger(AbstractLongStorage storage) {
@Override
public BigInteger getItem(int i) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
return null;
} else {
long x = storage.getItem(i);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java
index 628eda61b075..aa28de2128a9 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/numeric/helpers/DoubleArrayAdapter.java
@@ -9,7 +9,7 @@
public interface DoubleArrayAdapter {
double getItemAsDouble(int i);
- boolean isNa(int i);
+ boolean isNothing(long i);
int size();
@@ -49,8 +49,8 @@ public double getItemAsDouble(int i) {
}
@Override
- public boolean isNa(int i) {
- return storage.isNa(i);
+ public boolean isNothing(long i) {
+ return storage.isNothing(i);
}
@Override
@@ -73,7 +73,7 @@ public double getItemAsDouble(int i) {
}
@Override
- public boolean isNa(int i) {
+ public boolean isNothing(long i) {
return storage.getItem(i) == null;
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java
index eef9349eab20..ffdcde1512d2 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/LikeOp.java
@@ -41,24 +41,24 @@ public BoolStorage runBinaryMap(
MapOperationProblemAggregator problemAggregator) {
if (arg == null) {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
- newMissing.set(0, storage.size());
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ BitSet newIsNothing = new BitSet();
+ newIsNothing.set(0, storage.size());
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
} else if (arg instanceof String argString) {
Pattern pattern = createRegexPatternFromSql(argString);
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < storage.size(); i++) {
- if (storage.isNa(i)) {
- newMissing.set(i);
+ if (storage.isNothing(i)) {
+ newIsNothing.set(i);
} else if (pattern.matcher(storage.getItem(i)).matches()) {
newVals.set(i);
}
context.safepoint();
}
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
} else {
throw new UnexpectedTypeException("a Text");
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java
index f90c42ebb3a3..10dcad687de5 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringBooleanOp.java
@@ -29,37 +29,37 @@ public BoolStorage runBinaryMap(
MapOperationProblemAggregator problemAggregator) {
if (arg == null) {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
- newMissing.set(0, storage.size());
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ BitSet newIsNothing = new BitSet();
+ newIsNothing.set(0, storage.size());
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
} else if (arg instanceof String argString) {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < storage.size(); i++) {
- if (storage.isNa(i)) {
- newMissing.set(i);
+ if (storage.isNothing(i)) {
+ newIsNothing.set(i);
} else if (doString(storage.getItem(i), argString)) {
newVals.set(i);
}
context.safepoint();
}
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
} else {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < storage.size(); i++) {
- if (storage.isNa(i)) {
- newMissing.set(i);
+ if (storage.isNothing(i)) {
+ newIsNothing.set(i);
} else if (doObject(storage.getItem(i), arg)) {
newVals.set(i);
}
context.safepoint();
}
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
}
}
@@ -71,24 +71,24 @@ public BoolStorage runZip(
Context context = Context.getCurrent();
if (arg instanceof StringStorage v) {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i) && i < v.size() && !v.isNa(i)) {
+ if (!storage.isNothing(i) && i < v.size() && !v.isNothing(i)) {
if (doString(storage.getItem(i), v.getItem(i))) {
newVals.set(i);
}
} else {
- newMissing.set(i);
+ newIsNothing.set(i);
}
context.safepoint();
}
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
} else {
BitSet newVals = new BitSet();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i) && i < arg.size() && !arg.isNa(i)) {
+ if (!storage.isNothing(i) && i < arg.size() && !arg.isNothing(i)) {
Object x = arg.getItemBoxed(i);
if (x instanceof String) {
if (doString(storage.getItem(i), (String) x)) {
@@ -100,12 +100,12 @@ public BoolStorage runZip(
}
}
} else {
- newMissing.set(i);
+ newIsNothing.set(i);
}
context.safepoint();
}
- return new BoolStorage(newVals, newMissing, storage.size(), false);
+ return new BoolStorage(newVals, newIsNothing, storage.size(), false);
}
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java
index c58b9d5fad75..e6c784e3cf84 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringLongToStringOp.java
@@ -33,7 +33,7 @@ public Storage> runBinaryMap(
String[] newVals = new String[size];
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
newVals[i] = null;
} else {
newVals[i] = doOperation(storage.getItem(i), argLong);
@@ -58,7 +58,7 @@ public Storage> runZip(
String[] newVals = new String[size];
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
- if (storage.isNa(i) || v.isNa(i)) {
+ if (storage.isNothing(i) || v.isNothing(i)) {
newVals[i] = null;
} else {
newVals[i] = doOperation(storage.getItem(i), v.getItem(i));
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java
index 893ee17db127..5638056ba7ef 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/operation/map/text/StringStringOp.java
@@ -34,7 +34,7 @@ public Storage> runBinaryMap(
String[] newVals = new String[size];
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
- if (storage.isNa(i)) {
+ if (storage.isNothing(i)) {
newVals[i] = null;
} else {
newVals[i] = doString(storage.getItem(i), argString);
@@ -61,7 +61,7 @@ public Storage> runZip(
String[] newVals = new String[size];
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
- if (storage.isNa(i) || v.isNa(i)) {
+ if (storage.isNothing(i) || v.isNothing(i)) {
newVals[i] = null;
} else {
newVals[i] = doString(storage.getItem(i), v.getItem(i));
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java
index fd54d4d9a9c2..ea504b0ef43d 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/BoolStorage.java
@@ -25,21 +25,21 @@ public final class BoolStorage extends Storage
implements ColumnBooleanStorage, ColumnStorageWithNothingMap {
private static final MapOperationStorage ops = buildOps();
private final BitSet values;
- private final BitSet isMissing;
+ private final BitSet isNothing;
private final int size;
private final boolean negated;
- public BoolStorage(BitSet values, BitSet isMissing, int size, boolean negated) {
+ public BoolStorage(BitSet values, BitSet isNothing, int size, boolean negated) {
this.values = values;
- this.isMissing = isMissing;
+ this.isNothing = isNothing;
this.size = size;
this.negated = negated;
}
public static BoolStorage makeEmpty(int size) {
- BitSet isMissing = new BitSet(size);
- isMissing.set(0, size);
- return new BoolStorage(new BitSet(), isMissing, size, false);
+ BitSet isNothing = new BitSet(size);
+ isNothing.set(0, size);
+ return new BoolStorage(new BitSet(), isNothing, size, false);
}
public static BoolStorage makeConstant(int size, boolean r) {
@@ -58,7 +58,7 @@ public StorageType getType() {
@Override
public Boolean getItemBoxed(int idx) {
- return isMissing.get(idx) ? null : getItem(idx);
+ return isNothing.get(idx) ? null : getItem(idx);
}
public boolean getItem(long idx) {
@@ -66,8 +66,8 @@ public boolean getItem(long idx) {
}
@Override
- public boolean isNa(long idx) {
- return isMissing.get((int) idx);
+ public boolean isNothing(long idx) {
+ return isNothing.get((int) idx);
}
@Override
@@ -91,10 +91,6 @@ public BitSet getValues() {
return values;
}
- public BitSet getIsMissing() {
- return isMissing;
- }
-
/**
* Creates a new BoolStorage in which all missing values have been replaced by arg.
*
@@ -105,9 +101,9 @@ public BitSet getIsMissing() {
private Storage> fillMissingBoolean(boolean arg) {
final var newValues = (BitSet) values.clone();
if (arg != negated) {
- newValues.or(isMissing);
+ newValues.or(isNothing);
} else {
- newValues.andNot(isMissing);
+ newValues.andNot(isNothing);
}
return new BoolStorage(newValues, new BitSet(), size, negated);
}
@@ -131,17 +127,17 @@ public Storage> fillMissingFromPrevious(BoolStorage missingIndicator) {
boolean previousValue = false;
boolean hasPrevious = false;
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
BitSet newValues = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
- boolean isCurrentValueMissing = isMissing.get(i);
+ boolean isCurrentValueMissing = isNothing.get(i);
if (isCurrentValueMissing) {
if (hasPrevious) {
newValues.set(i, previousValue);
} else {
- newMissing.set(i);
+ newIsNothing.set(i);
}
} else {
boolean currentValue = getItem(i);
@@ -153,19 +149,19 @@ public Storage> fillMissingFromPrevious(BoolStorage missingIndicator) {
context.safepoint();
}
- return new BoolStorage(newValues, newMissing, size, false);
+ return new BoolStorage(newValues, newIsNothing, size, false);
}
@Override
public BoolStorage applyFilter(BitSet filterMask, int newLength) {
Context context = Context.getCurrent();
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
BitSet newValues = new BitSet();
int resultIx = 0;
for (int i = 0; i < size; i++) {
if (filterMask.get(i)) {
- if (isMissing.get(i)) {
- newMissing.set(resultIx++);
+ if (isNothing.get(i)) {
+ newIsNothing.set(resultIx++);
} else if (values.get(i)) {
newValues.set(resultIx++);
} else {
@@ -177,7 +173,7 @@ public BoolStorage applyFilter(BitSet filterMask, int newLength) {
context.safepoint();
}
- return new BoolStorage(newValues, newMissing, newLength, negated);
+ return new BoolStorage(newValues, newIsNothing, newLength, negated);
}
@Override
@@ -187,7 +183,7 @@ public BoolStorage applyMask(OrderMask mask) {
BitSet newVals = new BitSet();
for (int i = 0; i < mask.length(); i++) {
int position = mask.get(i);
- if (position == Storage.NOT_FOUND_INDEX || isMissing.get(position)) {
+ if (position == Storage.NOT_FOUND_INDEX || isNothing.get(position)) {
newNa.set(i);
} else if (values.get(position)) {
newVals.set(i);
@@ -212,7 +208,7 @@ public Storage> iif(
var on_false = makeRowProvider(when_false);
Builder builder = Builder.getForType(resultStorageType, size, problemAggregator);
for (int i = 0; i < size; i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.append(null);
} else if (getItem(i)) {
builder.append(on_true.apply(i));
@@ -250,10 +246,10 @@ public BoolStorage runBinaryMap(
return storage;
} else {
return new BoolStorage(
- storage.values, storage.isMissing, storage.size, !storage.negated);
+ storage.values, storage.isNothing, storage.size, !storage.negated);
}
} else {
- return new BoolStorage(new BitSet(), storage.isMissing, storage.size, false);
+ return new BoolStorage(new BitSet(), storage.isNothing, storage.size, false);
}
}
@@ -264,19 +260,19 @@ public BoolStorage runZip(
MapOperationProblemAggregator problemAggregator) {
Context context = Context.getCurrent();
BitSet out = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < storage.size; i++) {
- if (!storage.isNa(i) && i < arg.size() && !arg.isNa(i)) {
+ if (!storage.isNothing(i) && i < arg.size() && !arg.isNothing(i)) {
if (((Boolean) storage.getItem(i)).equals(arg.getItemBoxed(i))) {
out.set(i);
}
} else {
- missing.set(i);
+ isNothing.set(i);
}
context.safepoint();
}
- return new BoolStorage(out, missing, storage.size, false);
+ return new BoolStorage(out, isNothing, storage.size, false);
}
})
.add(
@@ -293,7 +289,7 @@ public BoolStorage runBinaryMap(
newMissing.xor(storage.values);
return new BoolStorage(storage.values, newMissing, storage.size, true);
} else {
- var newMissing = storage.isMissing.get(0, storage.size);
+ var newMissing = storage.isNothing.get(0, storage.size);
newMissing.or(storage.values);
return new BoolStorage(new BitSet(), newMissing, storage.size, false);
}
@@ -332,20 +328,20 @@ public BoolStorage runZip(
negated = false;
}
- BitSet missing = BitSets.makeDuplicate(storage.isMissing);
- missing.or(v.isMissing);
- int current = missing.nextSetBit(0);
+ BitSet isNothing = BitSets.makeDuplicate(storage.isNothing);
+ isNothing.or(v.isNothing);
+ int current = isNothing.nextSetBit(0);
while (current != -1) {
var value = negated != out.get(current);
if (!value
&& (storage.getItemBoxed(current) == Boolean.FALSE
|| v.getItemBoxed(current) == Boolean.FALSE)) {
- missing.clear(current);
+ isNothing.clear(current);
}
- current = missing.nextSetBit(current + 1);
+ current = isNothing.nextSetBit(current + 1);
}
- return new BoolStorage(out, missing, storage.size, negated);
+ return new BoolStorage(out, isNothing, storage.size, negated);
}
})
.add(
@@ -357,7 +353,7 @@ public BoolStorage runBinaryMap(
MapOperationProblemAggregator problemAggregator) {
if (arg == null) {
if (storage.negated) {
- var newMissing = storage.isMissing.get(0, storage.size);
+ var newMissing = storage.isNothing.get(0, storage.size);
newMissing.or(storage.values);
return new BoolStorage(new BitSet(), newMissing, storage.size, true);
} else {
@@ -402,20 +398,20 @@ public BoolStorage runZip(
negated = false;
}
- BitSet missing = BitSets.makeDuplicate(storage.isMissing);
- missing.or(v.isMissing);
- int current = missing.nextSetBit(0);
+ BitSet isNothing = BitSets.makeDuplicate(storage.isNothing);
+ isNothing.or(v.isNothing);
+ int current = isNothing.nextSetBit(0);
while (current != -1) {
var value = negated != out.get(current);
if (value
&& (storage.getItemBoxed(current) == Boolean.TRUE
|| v.getItemBoxed(current) == Boolean.TRUE)) {
- missing.clear(current);
+ isNothing.clear(current);
}
- current = missing.nextSetBit(current + 1);
+ current = isNothing.nextSetBit(current + 1);
}
- return new BoolStorage(out, missing, storage.size, negated);
+ return new BoolStorage(out, isNothing, storage.size, negated);
}
})
.add(new BooleanIsInOp());
@@ -429,7 +425,7 @@ public static BitSet toMask(BoolStorage storage) {
if (storage.isNegated()) {
mask.flip(0, storage.size());
}
- mask.andNot(storage.getIsMissing());
+ mask.andNot(storage.getIsNothingMap());
return mask;
}
@@ -438,16 +434,16 @@ public BoolStorage slice(int offset, int limit) {
int newSize = Math.min(size - offset, limit);
return new BoolStorage(
values.get(offset, offset + limit),
- isMissing.get(offset, offset + limit),
+ isNothing.get(offset, offset + limit),
newSize,
negated);
}
@Override
public Storage> appendNulls(int count) {
- BitSet newMissing = BitSets.makeDuplicate(isMissing);
- newMissing.set(size, size + count);
- return new BoolStorage(values, newMissing, size + count, negated);
+ BitSet isNothing = BitSets.makeDuplicate(this.isNothing);
+ isNothing.set(size, size + count);
+ return new BoolStorage(values, isNothing, size + count, negated);
}
@Override
@@ -455,24 +451,24 @@ public BoolStorage slice(List ranges) {
Context context = Context.getCurrent();
int newSize = SliceRange.totalLength(ranges);
BitSet newValues = new BitSet(newSize);
- BitSet newMissing = new BitSet(newSize);
+ BitSet newIsNothing = new BitSet(newSize);
int offset = 0;
for (SliceRange range : ranges) {
int length = range.end() - range.start();
for (int i = 0; i < length; ++i) {
newValues.set(offset + i, values.get(range.start() + i));
- newMissing.set(offset + i, isMissing.get(range.start() + i));
+ newIsNothing.set(offset + i, isNothing.get(range.start() + i));
context.safepoint();
}
offset += length;
}
- return new BoolStorage(newValues, newMissing, newSize, negated);
+ return new BoolStorage(newValues, newIsNothing, newSize, negated);
}
@Override
public BitSet getIsNothingMap() {
- return isMissing;
+ return isNothing;
}
@Override
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java
index 04988201b678..362503ce27b5 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/ColumnStorage.java
@@ -10,7 +10,12 @@ public interface ColumnStorage {
/* Gets the value type of the storage. */
StorageType getType();
- /* Gets if a value is Nothing at a given index. */
+ /**
+ * Checks whether the value at idx is Nothing.
+ *
+ * @param index – the index to check.
+ * @return whether the value is Nothing.
+ */
boolean isNothing(long index);
/* Gets the value at a given index. */
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java
index e66678a0bb32..aa728f3b8f34 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/MixedStorageFacade.java
@@ -42,8 +42,8 @@ public StorageType inferPreciseTypeShrunk() {
}
@Override
- public boolean isNa(long idx) {
- return underlyingStorage.isNa(idx);
+ public boolean isNothing(long idx) {
+ return underlyingStorage.isNothing(idx);
}
@Override
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java
index f149dc1d7349..53e057963939 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/SpecializedStorage.java
@@ -56,11 +56,8 @@ public T getItemBoxed(int idx) {
return data[idx];
}
- /**
- * @inheritDoc
- */
@Override
- public boolean isNa(long idx) {
+ public boolean isNothing(long idx) {
return data[(int) idx] == null;
}
@@ -157,7 +154,7 @@ public Storage fillMissingFromPrevious(BoolStorage missingIndicator) {
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
boolean isCurrentValueMissing =
- missingIndicator == null ? isNa(i) : missingIndicator.getItem(i);
+ missingIndicator == null ? isNothing(i) : missingIndicator.getItem(i);
if (!isCurrentValueMissing) {
previous = data[i];
hasPrevious = true;
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java
index 3df2b2f6a35c..cde141dcd583 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/Storage.java
@@ -28,9 +28,12 @@ public abstract class Storage implements ColumnStorage {
*/
public abstract int size();
- /**
- * @return the type tag of this column's storage.
- */
+ @Override
+ public long getSize() {
+ return size();
+ }
+
+ @Override
public abstract StorageType getType();
/**
@@ -64,13 +67,8 @@ public Storage> tryGettingMoreSpecializedStorage() {
return this;
}
- /**
- * Checks whether the value at {@code idx} is missing.
- *
- * @param idx the index to check.
- * @return whether or not the value is missing.
- */
- public abstract boolean isNa(long idx);
+ @Override
+ public abstract boolean isNothing(long index);
/**
* Returns a boxed representation of an item. Missing values are denoted with null.
@@ -356,7 +354,7 @@ public Storage> fillMissingFrom(
var builder = Builder.getForType(commonType, size(), problemAggregator);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isNa(i)) {
+ if (isNothing(i)) {
builder.appendNoGrow(other.getItemBoxed(i));
} else {
builder.appendNoGrow(getItemBoxed(i));
@@ -441,16 +439,6 @@ public final Storage> cast(
return converter.cast(this, castProblemAggregator);
}
- @Override
- public long getSize() {
- return size();
- }
-
- @Override
- public boolean isNothing(long index) {
- return isNa(index);
- }
-
@Override
public Object getItemAsObject(long index) {
return getItemBoxed((int) index);
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java
index 4a18de32d9ad..4a77e2104d0a 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/StringStorage.java
@@ -54,18 +54,18 @@ public BoolStorage runBinaryMap(
Object arg,
MapOperationProblemAggregator problemAggregator) {
BitSet r = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < storage.size(); i++) {
if (storage.getItem(i) == null || arg == null) {
- missing.set(i);
+ isNothing.set(i);
} else if (arg instanceof String s && Text_Utils.equals(storage.getItem(i), s)) {
r.set(i);
}
context.safepoint();
}
- return new BoolStorage(r, missing, storage.size(), false);
+ return new BoolStorage(r, isNothing, storage.size(), false);
}
@Override
@@ -74,11 +74,11 @@ public BoolStorage runZip(
Storage> arg,
MapOperationProblemAggregator problemAggregator) {
BitSet r = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < storage.size(); i++) {
- if (storage.getItem(i) == null || i >= arg.size() || arg.isNa(i)) {
- missing.set(i);
+ if (storage.getItem(i) == null || i >= arg.size() || arg.isNothing(i)) {
+ isNothing.set(i);
} else if (arg.getItemBoxed(i) instanceof String s
&& Text_Utils.equals(storage.getItem(i), s)) {
r.set(i);
@@ -86,7 +86,7 @@ public BoolStorage runZip(
context.safepoint();
}
- return new BoolStorage(r, missing, storage.size(), false);
+ return new BoolStorage(r, isNothing, storage.size(), false);
}
});
t.add(
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java
index 954a778e7418..bd4717dc334e 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/AbstractLongStorage.java
@@ -25,8 +25,6 @@ public abstract class AbstractLongStorage extends NumericStorage
implements ColumnLongStorage, ColumnStorageWithNothingMap {
public abstract long getItem(int idx);
- public abstract BitSet getIsMissing();
-
private static final MapOperationStorage ops = buildOps();
@Override
@@ -84,7 +82,7 @@ public StorageType inferPreciseTypeShrunk() {
int n = size();
Context context = Context.getCurrent();
for (int i = 0; i < n; i++) {
- if (isNa(i)) {
+ if (isNothing(i)) {
continue;
}
@@ -130,18 +128,18 @@ public AbstractLongStorage fillMissingFromPrevious(BoolStorage missingIndicator)
int n = size();
long[] newData = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long previousValue = 0;
boolean hasPrevious = false;
Context context = Context.getCurrent();
for (int i = 0; i < n; i++) {
- boolean isCurrentMissing = isNa(i);
- if (isCurrentMissing) {
+ boolean isCurrentNothing = isNothing(i);
+ if (isCurrentNothing) {
if (hasPrevious) {
newData[i] = previousValue;
} else {
- newMissing.set(i);
+ newIsNothing.set(i);
}
} else {
long currentValue = getItem(i);
@@ -153,7 +151,7 @@ public AbstractLongStorage fillMissingFromPrevious(BoolStorage missingIndicator)
context.safepoint();
}
- return new LongStorage(newData, n, newMissing, getType());
+ return new LongStorage(newData, n, newIsNothing, getType());
}
/**
@@ -172,7 +170,5 @@ public long get(long index) throws ValueIsNothingException {
}
@Override
- public BitSet getIsNothingMap() {
- return getIsMissing();
- }
+ public abstract BitSet getIsNothingMap();
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java
index 02e9d6776a75..774397997bd2 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedLongStorage.java
@@ -33,7 +33,7 @@ public IntegerType getType() {
}
@Override
- public boolean isNa(long idx) {
+ public boolean isNothing(long idx) {
return false;
}
@@ -51,14 +51,9 @@ public long getItem(int idx) {
return computeItem(idx);
}
- @Override
- public BitSet getIsMissing() {
- return EMPTY;
- }
-
@Override
public Storage applyFilter(BitSet filterMask, int newLength) {
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long[] newData = new long[newLength];
int resIx = 0;
Context context = Context.getCurrent();
@@ -69,25 +64,25 @@ public Storage applyFilter(BitSet filterMask, int newLength) {
context.safepoint();
}
- return new LongStorage(newData, newLength, newMissing, getType());
+ return new LongStorage(newData, newLength, newIsNothing, getType());
}
@Override
public Storage applyMask(OrderMask mask) {
long[] newData = new long[mask.length()];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < mask.length(); i++) {
int position = mask.get(i);
if (position == Storage.NOT_FOUND_INDEX) {
- newMissing.set(i);
+ newIsNothing.set(i);
} else {
newData[i] = getItem(position);
}
context.safepoint();
}
- return new LongStorage(newData, newData.length, newMissing, getType());
+ return new LongStorage(newData, newData.length, newIsNothing, getType());
}
@Override
@@ -107,7 +102,7 @@ public Storage slice(int offset, int limit) {
public Storage slice(List ranges) {
int newSize = SliceRange.totalLength(ranges);
long[] newData = new long[newSize];
- BitSet newMissing = new BitSet(newSize);
+ BitSet newIsNothing = new BitSet(newSize);
int offset = 0;
Context context = Context.getCurrent();
for (SliceRange range : ranges) {
@@ -120,7 +115,7 @@ public Storage slice(List ranges) {
offset += length;
}
- return new LongStorage(newData, newSize, newMissing, getType());
+ return new LongStorage(newData, newSize, newIsNothing, getType());
}
private static final BitSet EMPTY = new BitSet();
@@ -148,4 +143,9 @@ protected Long computeItem(int idx) {
}
};
}
+
+ @Override
+ public BitSet getIsNothingMap() {
+ return EMPTY;
+ }
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java
index 3244197eb4b8..8cbefdc2525f 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/ComputedNullableLongStorage.java
@@ -17,7 +17,7 @@
public abstract class ComputedNullableLongStorage extends AbstractLongStorage {
protected final int size;
- protected BitSet isMissing = null;
+ protected BitSet isNothing = null;
protected abstract Long computeItem(int idx);
@@ -36,7 +36,7 @@ public IntegerType getType() {
}
@Override
- public boolean isNa(long idx) {
+ public boolean isNothing(long idx) {
if (idx < 0 || idx >= size) {
throw new IndexOutOfBoundsException(
"Index " + idx + " is out of bounds for range of length " + size + ".");
@@ -60,26 +60,26 @@ public long getItem(int idx) {
}
@Override
- public BitSet getIsMissing() {
- if (isMissing == null) {
+ public BitSet getIsNothingMap() {
+ if (isNothing == null) {
// Only compute once as needed.
- BitSet missing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
if (computeItem(i) == null) {
- missing.set(i);
+ newIsNothing.set(i);
}
context.safepoint();
}
- isMissing = missing;
+ isNothing = newIsNothing;
}
- return isMissing;
+ return isNothing;
}
@Override
public Storage applyFilter(BitSet filterMask, int newLength) {
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long[] newData = new long[newLength];
int resIx = 0;
Context context = Context.getCurrent();
@@ -87,7 +87,7 @@ public Storage applyFilter(BitSet filterMask, int newLength) {
if (filterMask.get(i)) {
Long item = computeItem(i);
if (item == null) {
- newMissing.set(resIx++);
+ newIsNothing.set(resIx++);
} else {
newData[resIx++] = item;
}
@@ -95,22 +95,22 @@ public Storage applyFilter(BitSet filterMask, int newLength) {
context.safepoint();
}
- return new LongStorage(newData, newLength, newMissing, getType());
+ return new LongStorage(newData, newLength, newIsNothing, getType());
}
@Override
public Storage applyMask(OrderMask mask) {
long[] newData = new long[mask.length()];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < mask.length(); i++) {
int position = mask.get(i);
if (position == Storage.NOT_FOUND_INDEX) {
- newMissing.set(i);
+ newIsNothing.set(i);
} else {
Long item = computeItem(position);
if (item == null) {
- newMissing.set(i);
+ newIsNothing.set(i);
} else {
newData[i] = item;
}
@@ -118,32 +118,32 @@ public Storage applyMask(OrderMask mask) {
context.safepoint();
}
- return new LongStorage(newData, newData.length, newMissing, getType());
+ return new LongStorage(newData, newData.length, newIsNothing, getType());
}
@Override
public Storage slice(int offset, int limit) {
int newSize = Math.min(size - offset, limit);
long[] newData = new long[newSize];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < newSize; i++) {
Long item = computeItem(offset + i);
if (item == null) {
- newMissing.set(i);
+ newIsNothing.set(i);
} else {
newData[i] = item;
}
context.safepoint();
}
- return new LongStorage(newData, newSize, newMissing, getType());
+ return new LongStorage(newData, newSize, newIsNothing, getType());
}
@Override
public Storage slice(List ranges) {
int newSize = SliceRange.totalLength(ranges);
long[] newData = new long[newSize];
- BitSet newMissing = new BitSet(newSize);
+ BitSet newIsNothing = new BitSet(newSize);
int offset = 0;
Context context = Context.getCurrent();
for (SliceRange range : ranges) {
@@ -152,7 +152,7 @@ public Storage slice(List ranges) {
for (int i = 0; i < length; i++) {
Long item = computeItem(rangeStart + i);
if (item == null) {
- newMissing.set(offset + i);
+ newIsNothing.set(offset + i);
} else {
newData[offset + i] = item;
}
@@ -161,7 +161,7 @@ public Storage slice(List ranges) {
offset += length;
}
- return new LongStorage(newData, newSize, newMissing, getType());
+ return new LongStorage(newData, newSize, newIsNothing, getType());
}
@Override
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java
index c21e32d56ed5..01f92b3b18df 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/DoubleStorage.java
@@ -37,26 +37,26 @@
public final class DoubleStorage extends NumericStorage
implements DoubleArrayAdapter, ColumnStorageWithNothingMap {
private final long[] data;
- private final BitSet isMissing;
+ private final BitSet isNothing;
private final int size;
private static final MapOperationStorage ops = buildOps();
/**
* @param data the underlying data
* @param size the number of items stored
- * @param isMissing a bit set denoting at index {@code i} whether the value at index {@code i} is
- * missing.
+ * @param isNothing a bit set denoting at index {@code i} whether the value at index {@code i} is
+ * Nothing.
*/
- public DoubleStorage(long[] data, int size, BitSet isMissing) {
+ public DoubleStorage(long[] data, int size, BitSet isNothing) {
this.data = data;
- this.isMissing = isMissing;
+ this.isNothing = isNothing;
this.size = size;
}
public static DoubleStorage makeEmpty(int size) {
- BitSet isMissing = new BitSet(size);
- isMissing.set(0, size);
- return new DoubleStorage(new long[0], size, isMissing);
+ BitSet isNothing = new BitSet(size);
+ isNothing.set(0, size);
+ return new DoubleStorage(new long[0], size, isNothing);
}
/**
@@ -77,7 +77,7 @@ public double getItem(long idx) {
@Override
public Double getItemBoxed(int idx) {
- return isMissing.get(idx) ? null : Double.longBitsToDouble(data[idx]);
+ return isNothing.get(idx) ? null : Double.longBitsToDouble(data[idx]);
}
/**
@@ -92,8 +92,8 @@ public StorageType getType() {
* @inheritDoc
*/
@Override
- public boolean isNa(long idx) {
- return isMissing.get((int) idx);
+ public boolean isNothing(long idx) {
+ return isNothing.get((int) idx);
}
@Override
@@ -101,11 +101,6 @@ public double getItemAsDouble(int i) {
return Double.longBitsToDouble(data[i]);
}
- @Override
- public boolean isNa(int i) {
- return isMissing.get(i);
- }
-
@Override
public boolean isBinaryOpVectorized(String op) {
return ops.isSupportedBinary(op);
@@ -142,7 +137,7 @@ private Storage> fillMissingDouble(double arg, ProblemAggregator problemAggreg
long rawArg = Double.doubleToRawLongBits(arg);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendRawNoGrow(rawArg);
} else {
builder.appendRawNoGrow(data[i]);
@@ -158,7 +153,7 @@ private Storage> fillMissingBigInteger(BigInteger arg, ProblemAggregator probl
final var builder = NumericBuilder.createDoubleBuilder(size(), problemAggregator);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendBigInteger(arg);
} else {
builder.appendRawNoGrow(data[i]);
@@ -174,7 +169,7 @@ private Storage> fillMissingLong(long arg, ProblemAggregator problemAggregator
final var builder = NumericBuilder.createDoubleBuilder(size(), problemAggregator);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendLong(arg);
} else {
builder.appendRawNoGrow(data[i]);
@@ -210,18 +205,18 @@ public DoubleStorage fillMissingFromPrevious(BoolStorage missingIndicator) {
int n = size();
long[] newData = new long[n];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long previousValueRaw = 0;
boolean hasPrevious = false;
Context context = Context.getCurrent();
for (int i = 0; i < n; i++) {
- boolean isCurrentMissing = isNa(i);
+ boolean isCurrentMissing = isNothing(i);
if (isCurrentMissing) {
if (hasPrevious) {
newData[i] = previousValueRaw;
} else {
- newMissing.set(i);
+ newIsNothing.set(i);
}
} else {
long currentValueRaw = data[i];
@@ -233,19 +228,19 @@ public DoubleStorage fillMissingFromPrevious(BoolStorage missingIndicator) {
context.safepoint();
}
- return new DoubleStorage(newData, n, newMissing);
+ return new DoubleStorage(newData, n, newIsNothing);
}
@Override
public Storage applyFilter(BitSet filterMask, int newLength) {
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long[] newData = new long[newLength];
int resIx = 0;
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
if (filterMask.get(i)) {
- if (isMissing.get(i)) {
- newMissing.set(resIx++);
+ if (isNothing.get(i)) {
+ newIsNothing.set(resIx++);
} else {
newData[resIx++] = data[i];
}
@@ -253,29 +248,25 @@ public Storage applyFilter(BitSet filterMask, int newLength) {
context.safepoint();
}
- return new DoubleStorage(newData, newLength, newMissing);
+ return new DoubleStorage(newData, newLength, newIsNothing);
}
@Override
public Storage applyMask(OrderMask mask) {
long[] newData = new long[mask.length()];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < mask.length(); i++) {
int position = mask.get(i);
- if (position == Storage.NOT_FOUND_INDEX || isMissing.get(position)) {
- newMissing.set(i);
+ if (position == Storage.NOT_FOUND_INDEX || isNothing.get(position)) {
+ newIsNothing.set(i);
} else {
newData[i] = data[position];
}
context.safepoint();
}
- return new DoubleStorage(newData, newData.length, newMissing);
- }
-
- public BitSet getIsMissing() {
- return isMissing;
+ return new DoubleStorage(newData, newData.length, newIsNothing);
}
public long[] getRawData() {
@@ -305,38 +296,38 @@ public Storage slice(int offset, int limit) {
int newSize = Math.min(size - offset, limit);
long[] newData = new long[newSize];
System.arraycopy(data, offset, newData, 0, newSize);
- BitSet newMask = isMissing.get(offset, offset + limit);
+ BitSet newMask = isNothing.get(offset, offset + limit);
return new DoubleStorage(newData, newSize, newMask);
}
@Override
public DoubleStorage appendNulls(int count) {
- BitSet newMissing = BitSets.makeDuplicate(isMissing);
- newMissing.set(size, size + count);
+ BitSet newIsNothing = BitSets.makeDuplicate(isNothing);
+ newIsNothing.set(size, size + count);
long[] newData = new long[size + count];
System.arraycopy(data, 0, newData, 0, size);
- return new DoubleStorage(newData, size + count, newMissing);
+ return new DoubleStorage(newData, size + count, newIsNothing);
}
@Override
public Storage slice(List ranges) {
int newSize = SliceRange.totalLength(ranges);
long[] newData = new long[newSize];
- BitSet newMissing = new BitSet(newSize);
+ BitSet newIsNothing = new BitSet(newSize);
int offset = 0;
Context context = Context.getCurrent();
for (SliceRange range : ranges) {
int length = range.end() - range.start();
System.arraycopy(data, range.start(), newData, offset, length);
for (int i = 0; i < length; ++i) {
- newMissing.set(offset + i, isMissing.get(range.start() + i));
+ newIsNothing.set(offset + i, isNothing.get(range.start() + i));
context.safepoint();
}
offset += length;
}
- return new DoubleStorage(newData, newSize, newMissing);
+ return new DoubleStorage(newData, newSize, newIsNothing);
}
private StorageType inferredType = null;
@@ -347,7 +338,7 @@ public StorageType inferPreciseType() {
boolean areAllIntegers = true;
int visitedNumbers = 0;
for (int i = 0; i < size; i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
continue;
}
@@ -388,7 +379,7 @@ private StorageType findSmallestIntegerTypeThatFits() {
new ComputedNullableLongStorage(size) {
@Override
protected Long computeItem(int idx) {
- if (parent.isNa(idx)) {
+ if (parent.isNothing(idx)) {
return null;
}
@@ -405,6 +396,6 @@ protected Long computeItem(int idx) {
@Override
public BitSet getIsNothingMap() {
- return isMissing;
+ return isNothing;
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java
index e143ee19b7bc..a30332d64c0b 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/column/storage/numeric/LongStorage.java
@@ -22,7 +22,7 @@ public final class LongStorage extends AbstractLongStorage {
// for more compact storage and more efficient handling of smaller integers; for now we will be
// handling this just by checking the bounds
private final long[] data;
- private final BitSet isMissing;
+ private final BitSet isNothing;
private final int size;
private final IntegerType type;
@@ -30,13 +30,13 @@ public final class LongStorage extends AbstractLongStorage {
/**
* @param data the underlying data
* @param size the number of items stored
- * @param isMissing a bit set denoting at index {@code i} whether or not the value at index {@code
+ * @param isNothing a bit set denoting at index {@code i} whether or not the value at index {@code
* i} is missing.
* @param type the type specifying the bit-width of integers that are allowed in this storage
*/
- public LongStorage(long[] data, int size, BitSet isMissing, IntegerType type) {
+ public LongStorage(long[] data, int size, BitSet isNothing, IntegerType type) {
this.data = data;
- this.isMissing = isMissing;
+ this.isNothing = isNothing;
this.size = size;
this.type = type;
}
@@ -46,9 +46,9 @@ public static LongStorage fromArray(long[] data) {
}
public static LongStorage makeEmpty(int size, IntegerType type) {
- BitSet isMissing = new BitSet(size);
- isMissing.set(0, size);
- return new LongStorage(new long[0], size, isMissing, type);
+ BitSet isNothing = new BitSet(size);
+ isNothing.set(0, size);
+ return new LongStorage(new long[0], size, isNothing, type);
}
public LongStorage(long[] data, IntegerType type) {
@@ -73,7 +73,7 @@ public long getItem(int idx) {
@Override
public Long getItemBoxed(int idx) {
- return isMissing.get(idx) ? null : data[idx];
+ return isNothing.get(idx) ? null : data[idx];
}
/**
@@ -88,8 +88,8 @@ public IntegerType getType() {
* @inheritDoc
*/
@Override
- public boolean isNa(long idx) {
- return isMissing.get((int) idx);
+ public boolean isNothing(long idx) {
+ return isNothing.get((int) idx);
}
private Storage> fillMissingDouble(double arg, ProblemAggregator problemAggregator) {
@@ -97,7 +97,7 @@ private Storage> fillMissingDouble(double arg, ProblemAggregator problemAggreg
long rawArg = Double.doubleToRawLongBits(arg);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendRawNoGrow(rawArg);
} else {
double coerced = data[i];
@@ -115,7 +115,7 @@ private Storage> fillMissingLong(long arg, ProblemAggregator problemAggregator
NumericBuilder.createLongBuilder(size, IntegerType.INT_64, problemAggregator);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendRawNoGrow(arg);
} else {
builder.appendRawNoGrow(data[i]);
@@ -132,7 +132,7 @@ private Storage> fillMissingBigInteger(
final var builder = new BigIntegerBuilder(size, problemAggregator);
Context context = Context.getCurrent();
for (int i = 0; i < size(); i++) {
- if (isMissing.get(i)) {
+ if (isNothing.get(i)) {
builder.appendRawNoGrow(bigInteger);
} else {
builder.appendRawNoGrow(BigInteger.valueOf(data[i]));
@@ -162,14 +162,14 @@ public Storage> fillMissing(
@Override
public Storage applyFilter(BitSet filterMask, int newLength) {
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
long[] newData = new long[newLength];
int resIx = 0;
Context context = Context.getCurrent();
for (int i = 0; i < size; i++) {
if (filterMask.get(i)) {
- if (isMissing.get(i)) {
- newMissing.set(resIx++);
+ if (isNothing.get(i)) {
+ newIsNothing.set(resIx++);
} else {
newData[resIx++] = data[i];
}
@@ -177,30 +177,30 @@ public Storage applyFilter(BitSet filterMask, int newLength) {
context.safepoint();
}
- return new LongStorage(newData, newLength, newMissing, type);
+ return new LongStorage(newData, newLength, newIsNothing, type);
}
@Override
public Storage applyMask(OrderMask mask) {
long[] newData = new long[mask.length()];
- BitSet newMissing = new BitSet();
+ BitSet newIsNothing = new BitSet();
Context context = Context.getCurrent();
for (int i = 0; i < mask.length(); i++) {
int position = mask.get(i);
- if (position == Storage.NOT_FOUND_INDEX || isMissing.get(position)) {
- newMissing.set(i);
+ if (position == Storage.NOT_FOUND_INDEX || isNothing.get(position)) {
+ newIsNothing.set(i);
} else {
newData[i] = data[position];
}
context.safepoint();
}
- return new LongStorage(newData, newData.length, newMissing, type);
+ return new LongStorage(newData, newData.length, newIsNothing, type);
}
@Override
- public BitSet getIsMissing() {
- return isMissing;
+ public BitSet getIsNothingMap() {
+ return isNothing;
}
public long[] getRawData() {
@@ -212,43 +212,43 @@ public LongStorage slice(int offset, int limit) {
int newSize = Math.min(size - offset, limit);
long[] newData = new long[newSize];
System.arraycopy(data, offset, newData, 0, newSize);
- BitSet newMask = isMissing.get(offset, offset + limit);
+ BitSet newMask = isNothing.get(offset, offset + limit);
return new LongStorage(newData, newSize, newMask, type);
}
@Override
public LongStorage appendNulls(int count) {
- BitSet newMissing = BitSets.makeDuplicate(isMissing);
- newMissing.set(size, size + count);
+ BitSet newIsNothing = BitSets.makeDuplicate(isNothing);
+ newIsNothing.set(size, size + count);
long[] newData = new long[size + count];
System.arraycopy(data, 0, newData, 0, size);
- return new LongStorage(newData, size + count, newMissing, type);
+ return new LongStorage(newData, size + count, newIsNothing, type);
}
@Override
public LongStorage slice(List ranges) {
int newSize = SliceRange.totalLength(ranges);
long[] newData = new long[newSize];
- BitSet newMissing = new BitSet(newSize);
+ BitSet newIsNothing = new BitSet(newSize);
int offset = 0;
Context context = Context.getCurrent();
for (SliceRange range : ranges) {
int length = range.end() - range.start();
System.arraycopy(data, range.start(), newData, offset, length);
for (int i = 0; i < length; ++i) {
- newMissing.set(offset + i, isMissing.get(range.start() + i));
+ newIsNothing.set(offset + i, isNothing.get(range.start() + i));
context.safepoint();
}
offset += length;
}
- return new LongStorage(newData, newSize, newMissing, type);
+ return new LongStorage(newData, newSize, newIsNothing, type);
}
/** Widening to a bigger type can be done without copying the data. */
@Override
public LongStorage widen(IntegerType widerType) {
assert widerType.fits(type);
- return new LongStorage(data, size, isMissing, widerType);
+ return new LongStorage(data, size, isNothing, widerType);
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/data/index/MultiValueKeyBase.java b/std-bits/table/src/main/java/org/enso/table/data/index/MultiValueKeyBase.java
index e8ad683ac08c..db594a201637 100644
--- a/std-bits/table/src/main/java/org/enso/table/data/index/MultiValueKeyBase.java
+++ b/std-bits/table/src/main/java/org/enso/table/data/index/MultiValueKeyBase.java
@@ -50,7 +50,7 @@ public int getNumberOfColumns() {
/** Checks if all cells in the current row are missing. */
public boolean areAllNull() {
for (Storage> storage : storages) {
- if (!storage.isNa(rowIndex)) {
+ if (!storage.isNothing(rowIndex)) {
return false;
}
}
@@ -60,7 +60,7 @@ public boolean areAllNull() {
/** Checks if any cells in the current row are missing. */
public boolean hasAnyNulls() {
for (Storage> storage : storages) {
- if (storage.isNa(rowIndex)) {
+ if (storage.isNothing(rowIndex)) {
return true;
}
}
diff --git a/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java b/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java
index 963e68070907..cfc2c698c707 100644
--- a/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java
+++ b/std-bits/table/src/main/java/org/enso/table/write/ExcelWriter.java
@@ -489,7 +489,7 @@ private static CellStyle getDateTimeStyle(Workbook workbook, String format) {
private static void writeValueToCell(Cell cell, int j, Storage> storage, Workbook workbook)
throws IllegalStateException {
- if (storage.isNa(j)) {
+ if (storage.isNothing(j)) {
cell.setBlank();
} else if (storage instanceof DoubleStorage doubleStorage) {
cell.setCellValue(doubleStorage.getItemAsDouble(j));
diff --git a/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java b/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java
index bbee33be42fc..865f111c439c 100644
--- a/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java
+++ b/test/Base_Tests/polyglot-sources/enso-test-java-helpers/src/main/java/org/enso/table_test_helpers/ExplodingStorage.java
@@ -40,7 +40,7 @@ public StorageType getType() {
}
@Override
- public boolean isNa(long idx) {
+ public boolean isNothing(long idx) {
checkIndex(idx);
return false;
}
diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java
index 32a6287d0341..8c820c1bcb6b 100644
--- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java
+++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/LongNullHandling.java
@@ -23,15 +23,15 @@ public LongStorage run(
LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) {
int n = storage.size();
long[] newVals = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i) || arg.isNa(i)) {
- missing.set(i);
+ if (storage.isNothing(i) || arg.isNothing(i)) {
+ isNothing.set(i);
} else {
newVals[i] = doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator);
}
}
- return new LongStorage(newVals, n, missing, IntegerType.INT_64);
+ return new LongStorage(newVals, n, isNothing, IntegerType.INT_64);
}
}
@@ -45,20 +45,20 @@ public LongStorage run(
LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) {
int n = storage.size();
long[] newVals = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i) || arg.isNa(i)) {
- missing.set(i);
+ if (storage.isNothing(i) || arg.isNothing(i)) {
+ isNothing.set(i);
} else {
Long x = doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator);
if (x == null) {
- missing.set(i);
+ isNothing.set(i);
} else {
newVals[i] = x;
}
}
}
- return new LongStorage(newVals, n, missing, IntegerType.INT_64);
+ return new LongStorage(newVals, n, isNothing, IntegerType.INT_64);
}
}
@@ -83,23 +83,23 @@ public LongStorage run(
LongStorage storage, LongStorage arg, MapOperationProblemAggregator problemAggregator) {
int n = storage.size();
long[] newVals = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
NullityReporter nullityReporter = new NullityReporter();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i) || arg.isNa(i)) {
- missing.set(i);
+ if (storage.isNothing(i) || arg.isNothing(i)) {
+ isNothing.set(i);
} else {
long x =
doLong(storage.getItem(i), arg.getItem(i), i, problemAggregator, nullityReporter);
if (nullityReporter.wasLastNull) {
- missing.set(i);
+ isNothing.set(i);
nullityReporter.wasLastNull = false;
} else {
newVals[i] = x;
}
}
}
- return new LongStorage(newVals, n, missing, IntegerType.INT_64);
+ return new LongStorage(newVals, n, isNothing, IntegerType.INT_64);
}
}
diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java
index 21c0397b3b32..1566a9be19e9 100644
--- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java
+++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/MapHelpers.java
@@ -24,7 +24,7 @@ public static StringStorage stringConcatBimap(StringStorage storage1, StringStor
int n = storage1.size();
String[] result = new String[n];
for (int i = 0; i < n; i++) {
- if (!storage1.isNa(i) && !storage2.isNa(i)) {
+ if (!storage1.isNothing(i) && !storage2.isNothing(i)) {
result[i] = storage1.getItem(i) + storage2.getItem(i);
} else {
result[i] = null;
@@ -40,59 +40,59 @@ public static LongStorage longAddBimap(LongStorage storage1, LongStorage storage
int n = storage1.size();
long[] result = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (!storage1.isNa(i) && !storage2.isNa(i)) {
+ if (!storage1.isNothing(i) && !storage2.isNothing(i)) {
result[i] = storage1.getItem(i) + storage2.getItem(i);
} else {
- missing.set(i);
+ isNothing.set(i);
}
}
- return new LongStorage(result, n, missing, IntegerType.INT_64);
+ return new LongStorage(result, n, isNothing, IntegerType.INT_64);
}
public static BoolStorage textEndsWith(StringStorage storage, String suffix) {
int n = storage.size();
BitSet result = new BitSet();
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (storage.isNa(i)) {
- missing.set(i);
+ if (storage.isNothing(i)) {
+ isNothing.set(i);
} else {
if (Text_Utils.ends_with(storage.getItem(i), suffix)) {
result.set(i);
}
}
}
- return new BoolStorage(result, missing, n, false);
+ return new BoolStorage(result, isNothing, n, false);
}
public static LongStorage longAdd(LongStorage storage, long shift) {
int n = storage.size();
long[] result = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
result[i] = storage.getItem(i) + shift;
} else {
- missing.set(i);
+ isNothing.set(i);
}
}
- return new LongStorage(result, n, missing, IntegerType.INT_64);
+ return new LongStorage(result, n, isNothing, IntegerType.INT_64);
}
public static LongStorage getYear(DateStorage storage) {
int n = storage.size();
long[] result = new long[n];
- BitSet missing = new BitSet();
+ BitSet isNothing = new BitSet();
for (int i = 0; i < n; i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
result[i] = storage.getItem(i).getYear();
} else {
- missing.set(i);
+ isNothing.set(i);
}
}
- return new LongStorage(result, n, missing, IntegerType.INT_64);
+ return new LongStorage(result, n, isNothing, IntegerType.INT_64);
}
public static Storage> mapCallback(
@@ -106,7 +106,7 @@ public static Storage> mapCallback(
? new InferredBuilder(n, problemAggregator)
: Builder.getForType(expectedType, n, problemAggregator);
for (int i = 0; i < n; i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
builder.append(fn.apply(storage.getItemBoxed(i)));
} else {
builder.appendNulls(1);
diff --git a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java
index 8c2f2172edbc..ac070cf0a43c 100644
--- a/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java
+++ b/test/Exploratory_Benchmarks/polyglot-sources/exploratory-benchmark-java-helpers/src/main/java/org/enso/exploratory_benchmark_helpers/SimpleStorageAggregateHelpers.java
@@ -10,7 +10,7 @@ public class SimpleStorageAggregateHelpers {
public static long sumLongStorage(LongStorage storage) {
long sum = 0;
for (int i = 0; i < storage.size(); i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
sum += storage.getItem(i);
}
}
@@ -32,7 +32,7 @@ public static String longestText(StringStorage storage) {
String longestText = null;
int n = storage.size();
for (int i = 0; i < n; i++) {
- if (!storage.isNa(i)) {
+ if (!storage.isNothing(i)) {
String text = storage.getItem(i);
long length = Text_Utils.grapheme_length(text);
if (length > longest) {
diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso b/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso
index bb4d24584411..559353f87d2b 100644
--- a/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso
+++ b/test/Exploratory_Benchmarks/src/Table/Column_Aggregate.enso
@@ -62,7 +62,7 @@ type Primitive_Total_Aggregate
n = self.int_column.length
storage = self.int_column.java_column.getStorage
(0.up_to n).fold 0 acc-> ix->
- if storage.isNa ix then acc else
+ if storage.isNothing ix then acc else
acc + storage.getItem ix
verify_correctness self =
diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso b/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso
index 923c27f3dd96..f49b553c53bc 100644
--- a/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso
+++ b/test/Exploratory_Benchmarks/src/Table/Column_Bi_Map.enso
@@ -68,7 +68,7 @@ type Primitive_Bi_Map_Test
storage_1 = self.int_column_1.java_column.getStorage
storage_2 = self.int_column_2.java_column.getStorage
0.up_to n . each i->
- if storage_1.isNa i || storage_2.isNa i then builder.appendNulls 1 else
+ if storage_1.isNothing i || storage_2.isNothing i then builder.appendNulls 1 else
item_1 = storage_1.getItem i
item_2 = storage_2.getItem i
res = item_1 + item_2
diff --git a/test/Exploratory_Benchmarks/src/Table/Column_Map.enso b/test/Exploratory_Benchmarks/src/Table/Column_Map.enso
index 9a88ae2c8fe8..61ab49f1bb9d 100644
--- a/test/Exploratory_Benchmarks/src/Table/Column_Map.enso
+++ b/test/Exploratory_Benchmarks/src/Table/Column_Map.enso
@@ -72,7 +72,7 @@ type Primitive_Map_Test
builder = NumericBuilder.createLongBuilder n
storage = self.int_column.java_column.getStorage
0.up_to n . each i->
- case storage.isNa i of
+ case storage.isNothing i of
True ->
builder.appendNulls 1
False ->
diff --git a/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso b/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso
index e7ac99a7458a..f14501810d1b 100644
--- a/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso
+++ b/test/Exploratory_Benchmarks/src/Table/Enso_Callback.enso
@@ -90,7 +90,7 @@ type Primitive_Enso_Callback_Test
builder = NumericBuilder.createLongBuilder n
storage = self.int_column.java_column.getStorage
0.up_to n . each i->
- case storage.isNa i of
+ case storage.isNothing i of
True ->
builder.appendNulls 1
False ->