// 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;
}
}
}