Skip to content

Commit

Permalink
provide generalized functions to walk linked list cache looking for c…
Browse files Browse the repository at this point in the history
…ondition
  • Loading branch information
interim17 committed Sep 11, 2024
1 parent 23b800a commit fd88894
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 53 deletions.
5 changes: 0 additions & 5 deletions src/simularium/VisData.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { noop } from "lodash";

import { nullCachedFrame } from "../util";
import { TimeData } from "../viewport";

import * as util from "./ThreadUtil";
import { VisDataMessage, CachedFrame } from "./types";
Expand Down Expand Up @@ -100,10 +99,6 @@ class VisData {
return this.currentFrameNumber >= this.frameCache.getLastFrameNumber();
}

public get currentVisDataFrameNumber(): number {
return this.currentFrameNumber;
}

public gotoNextFrame(): void {
if (!this.atLatestFrame()) {
this.currentFrameNumber += 1;
Expand Down
97 changes: 49 additions & 48 deletions src/simularium/VisDataCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,49 +60,42 @@ class VisDataCache {
return this.numFrames > 0 && this.head !== null;
}

public containsTime(time: number): boolean {
let currentNode = this.head;
if (time < this.getFirstFrameTime() || time > this.getLastFrameTime()) {
return false;
}
/**
* Walks the cache looking for node that satisfies condition
* returns the node if found, otherwise returns null,
* starts at head if firstNode is not provided.
*/
private walkLinkedList(
condition: (data: LinkedListNode) => boolean,
firstNode?: LinkedListNode
): LinkedListNode | null {
let currentNode = firstNode || this.head;
while (currentNode) {
if (currentNode.data.time === time) {
return true;
if (condition(currentNode)) {
return currentNode;
}
currentNode = currentNode.next;
}
return false;
return null;
}

public containsFrameAtFrameNumber(frameNumber: number): boolean {
let currentNode = this.head;
if (currentNode?.data.frameNumber === frameNumber) {
return true;
public containsTime(time: number): boolean {
if (time < this.getFirstFrameTime() || time > this.getLastFrameTime()) {
return false;
}
return !!this.walkLinkedList((node) => node.data.time === time);
}

public containsFrameAtFrameNumber(frameNumber: number): boolean {
if (
frameNumber < this.getFirstFrameNumber() ||
frameNumber > this.getLastFrameNumber()
) {
return false;
}
while (currentNode) {
if (currentNode.data.frameNumber === frameNumber) {
return true;
}
currentNode = currentNode.next;
}
return false;
}

public getFrameAtTime(time: number): CachedFrame | null {
let currentNode = this.head;
while (currentNode) {
if (currentNode.data.time === time) {
return currentNode.data;
}
currentNode = currentNode.next;
}
return null;
return !!this.walkLinkedList(
(node) => node.data.frameNumber === frameNumber
);
}

public getFirstFrame(): CachedFrame {
Expand All @@ -120,24 +113,6 @@ class VisDataCache {
return this.head ? this.head.data.time : -1;
}

public getFrameAtFrameNumber(frameNumber: number): CachedFrame {
let currentNode = this.head;
if (!this.head) {
throw this.frameAccessError("No data in cache.");
}
while (currentNode) {
if (currentNode.data.frameNumber !== undefined) {
if (currentNode.data.frameNumber == frameNumber) {
return currentNode.data;
}
}
currentNode = currentNode.next;
}
throw this.frameAccessError(
`Frame not found at provided frame number. Attempting to access frame ${frameNumber}.`
);
}

public getLastFrame(): CachedFrame {
if (!this.tail) {
throw this.frameAccessError(" No data in cache.");
Expand All @@ -153,6 +128,32 @@ class VisDataCache {
return this.tail?.data.time || -1;
}

private getFrameAtTimeOrFrameNumber(
condition: "time" | "frameNumber",
value: number
): CachedFrame {
if (!this.head) {
throw this.frameAccessError("No data in cache.");
}
const frame = this.walkLinkedList(
(node) => node.data[condition] === value
);
if (frame) {
return frame.data;
}
throw this.frameAccessError(
`Frame not found at provided ${condition}. Attempting to access frame ${value}.`
);
}

public getFrameAtTime(time: number): CachedFrame {
return this.getFrameAtTimeOrFrameNumber("time", time);
}

public getFrameAtFrameNumber(frameNumber: number): CachedFrame {
return this.getFrameAtTimeOrFrameNumber("frameNumber", frameNumber);
}

public assignSingleFrameToCache(data: CachedFrame): void {
const newNode: LinkedListNode = {
data,
Expand Down

0 comments on commit fd88894

Please sign in to comment.