// Copyright Epic Games, Inc. All Rights Reserved. using EpicGames.Core; using HordeServer.Api; using HordeServer.Services; using HordeServer.Utilities; using MongoDB.Bson; using MongoDB.Bson.Serialization.Attributes; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Threading.Tasks; namespace HordeServer.Models { /// /// Information about a log file chunk /// public interface ILogChunk { /// /// Offset of the chunk within the log /// long Offset { get; } /// /// Length of this chunk. If zero, the chunk is still being written to. /// int Length { get; } /// /// Index of the first line within this chunk. If a line straddles two chunks, this is the index of the split line. /// int LineIndex { get; } /// /// If the chunk has yet to be pushed to persistent storage, includes the name of the server that is currently storing it. /// string? Server { get; } } /// /// Information about a log file /// public interface ILogFile { /// /// Identifier for the LogFile. Randomly generated. /// public ObjectId Id { get; } /// /// Unique id of the job containing this log /// public ObjectId JobId { get; } /// /// The session allowed to write to this log /// public ObjectId? SessionId { get; } /// /// Maximum line index in the file /// public int? MaxLineIndex { get; } /// /// Length of the file which is indexed /// public long? IndexLength { get; } /// /// Type of data stored in this log /// public LogType Type { get; } /// /// Chunks within this file /// public IReadOnlyList Chunks { get; } } /// /// Extension methods for log files /// public static class LogFileExtensions { /// /// Gets the chunk index containing the given offset. /// /// The chunks to search /// The offset to search for /// The chunk index containing the given offset public static int GetChunkForOffset(this IReadOnlyList Chunks, long Offset) { int ChunkIndex = Chunks.BinarySearch(x => x.Offset, Offset); if (ChunkIndex < 0) { ChunkIndex = ~ChunkIndex - 1; } return ChunkIndex; } /// /// Gets the starting chunk index for the given line /// /// The chunks to search /// Index of the line to query /// Index of the chunk to fetch public static int GetChunkForLine(this IReadOnlyList Chunks, int LineIndex) { int ChunkIndex = Chunks.BinarySearch(x => x.LineIndex, LineIndex); if(ChunkIndex < 0) { ChunkIndex = ~ChunkIndex - 1; } return ChunkIndex; } } }