Skip to content

Commit

Permalink
refactor: Simplify segment memory storage limit configuration and opt…
Browse files Browse the repository at this point in the history
…imize segment memory storage

- Added a new function getAvailableMemoryPercent() to calculate the available memory percentage.
- Updated the generateQueue() function to pass the available memory percentage to QueueUtils.generateQueue().
- Modified the getUsedMemory() function in SegmentMemoryStorage to return the memory limit and memory used.
- Updated the getSegmentPlaybackStatuses() function in utils/stream.ts to calculate the time windows based on the available memory percentage.
  • Loading branch information
DimaDemchenko committed Sep 19, 2024
1 parent b3ce95a commit a3f49a8
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 22 deletions.
10 changes: 10 additions & 0 deletions packages/p2p-media-loader-core/src/hybrid-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -390,12 +390,14 @@ export class HybridLoader {
return;
}

const availableMemoryPercent = this.getAvailableMemoryPercent();
const segmentsToLoad: SegmentWithStream[] = [];
for (const { segment, statuses } of QueueUtils.generateQueue(
this.lastRequestedSegment,
this.playback,
this.config,
this.p2pLoaders.currentLoader,
availableMemoryPercent,
)) {
const swarmId = this.config.swarmId ?? this.streamManifestUrl;
const streamSwarmId = StreamUtils.getStreamSwarmId(
Expand Down Expand Up @@ -490,16 +492,24 @@ export class HybridLoader {
return false;
}

private getAvailableMemoryPercent(): number {
const { memoryLimit, memoryUsed } = this.segmentStorage.getUsedMemory();
return 100 - (memoryUsed / memoryLimit) * 100;
}

private generateQueue() {
const queue: QueueItem[] = [];
const queueSegmentIds = new Set<string>();
let maxPossibleLength = 0;
let alreadyLoadedCount = 0;

const availableMemoryPercent = this.getAvailableMemoryPercent();
for (const item of QueueUtils.generateQueue(
this.lastRequestedSegment,
this.playback,
this.config,
this.p2pLoaders.currentLoader,
availableMemoryPercent,
)) {
maxPossibleLength++;
const { segment } = item;
Expand Down
8 changes: 4 additions & 4 deletions packages/p2p-media-loader-core/src/segment-storage/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ export interface SegmentStorage {
): Promise<ArrayBuffer | undefined>;

/**
* Returns available space in the storage
* Returns used memory information in the storage
*/
getAvailableSpace(): {
limit: number;
used: number;
getUsedMemory(): {
memoryLimit: number;
memoryUsed: number;
};

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,11 +138,11 @@ export class SegmentMemoryStorage implements SegmentStorage {
return dataItem.data;
}

getAvailableSpace() {
getUsedMemory() {
if (!this.lastRequestedSegment) {
return {
limit: this.segmentsMemoryStorageLimit,
used: this.currentMemoryStorageSize,
memoryLimit: this.segmentsMemoryStorageLimit,
memoryUsed: this.currentMemoryStorageSize,
};
}
const { streamId, isLiveStream } = this.lastRequestedSegment;
Expand All @@ -157,8 +157,8 @@ export class SegmentMemoryStorage implements SegmentStorage {
this.currentMemoryStorageSize - potentialFreeSpace / BYTES_PER_MB;

return {
limit: this.segmentsMemoryStorageLimit,
used: usedMemoryInMB,
memoryLimit: this.segmentsMemoryStorageLimit,
memoryUsed: usedMemoryInMB,
};
}

Expand Down
4 changes: 4 additions & 0 deletions packages/p2p-media-loader-core/src/utils/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export function* generateQueue(
playback: Readonly<Playback>,
playbackConfig: PlaybackTimeWindowsConfig,
currentP2PLoader: P2PLoader,
availablePercentMemory: number,
): Generator<QueueItem, void> {
const { runtimeId, stream } = lastRequestedSegment;

Expand All @@ -38,6 +39,7 @@ export function* generateQueue(
playback,
playbackConfig,
currentP2PLoader,
availablePercentMemory,
);
if (isNotActualStatuses(firstStatuses)) {
const next = queueSegments.next();
Expand All @@ -54,6 +56,7 @@ export function* generateQueue(
playback,
playbackConfig,
currentP2PLoader,
availablePercentMemory,
);

if (isNotActualStatuses(secondStatuses)) return;
Expand All @@ -70,6 +73,7 @@ export function* generateQueue(
playback,
playbackConfig,
currentP2PLoader,
availablePercentMemory,
);
if (isNotActualStatuses(statuses)) break;
yield { segment, statuses };
Expand Down
39 changes: 26 additions & 13 deletions packages/p2p-media-loader-core/src/utils/stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,30 +62,44 @@ export function getSegmentAvgDuration(stream: StreamWithSegments) {
return sumDuration / size;
}

export function isSegmentActualInPlayback(
segment: Readonly<SegmentWithStream>,
playback: Playback,
function calculateTimeWindows(
timeWindowsConfig: PlaybackTimeWindowsConfig,
): boolean {
availableMemoryInPercent: number,
) {
const {
isHighDemand = false,
isHttpDownloadable = false,
isP2PDownloadable = false,
} = getSegmentPlaybackStatuses(segment, playback, timeWindowsConfig);
return isHighDemand || isHttpDownloadable || isP2PDownloadable;
highDemandTimeWindow,
httpDownloadTimeWindow,
p2pDownloadTimeWindow,
} = timeWindowsConfig;

const result = {
highDemandTimeWindow,
httpDownloadTimeWindow,
p2pDownloadTimeWindow,
};

if (availableMemoryInPercent <= 5) {
result.httpDownloadTimeWindow = 0;
result.p2pDownloadTimeWindow = 0;
} else if (availableMemoryInPercent <= 10) {
result.p2pDownloadTimeWindow = result.httpDownloadTimeWindow;
}

return result;
}

export function getSegmentPlaybackStatuses(
segment: SegmentWithStream,
playback: Playback,
timeWindowsConfig: PlaybackTimeWindowsConfig,
currentP2PLoader?: P2PLoader,
currentP2PLoader: P2PLoader,
availableMemoryPercent: number,
): SegmentPlaybackStatuses {
const {
highDemandTimeWindow,
httpDownloadTimeWindow,
p2pDownloadTimeWindow,
} = timeWindowsConfig;
} = calculateTimeWindows(timeWindowsConfig, availableMemoryPercent);

return {
isHighDemand: isSegmentInTimeWindow(
Expand All @@ -100,8 +114,7 @@ export function getSegmentPlaybackStatuses(
),
isP2PDownloadable:
isSegmentInTimeWindow(segment, playback, p2pDownloadTimeWindow) &&
(!currentP2PLoader ||
currentP2PLoader.isSegmentLoadingOrLoadedBySomeone(segment)),
currentP2PLoader.isSegmentLoadingOrLoadedBySomeone(segment),
};
}

Expand Down

0 comments on commit a3f49a8

Please sign in to comment.