Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System;
Expand Down Expand Up @@ -240,7 +240,7 @@ public bool OnStart(Guid checkpointToken, long currentVersion, long targetVersio
public bool Reader<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, RecordMetadata recordMetadata, long numberOfRecords)
where TSourceLogRecord : ISourceLogRecord
{
return srcLogRecord.Info.ValueIsObject
return srcLogRecord.DataHeader.ValueIsObject
? snapshotIteratorManager.ObjectReader(in srcLogRecord, recordMetadata, numberOfRecords)
: snapshotIteratorManager.StringReader(in srcLogRecord, recordMetadata, numberOfRecords);
}
Expand Down
4 changes: 2 additions & 2 deletions libs/cluster/Session/MigrateCommand.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System;
Expand All @@ -16,7 +16,7 @@ internal sealed unsafe partial class ClusterSession : IClusterSession
{
public static bool Expired<TSourceLogRecord>(in TSourceLogRecord logRecord)
where TSourceLogRecord : ISourceLogRecord
=> logRecord.Info.HasExpiration && logRecord.Expiration < DateTimeOffset.UtcNow.Ticks;
=> logRecord.DataHeader.HasExpiration && logRecord.Expiration < DateTimeOffset.UtcNow.Ticks;

internal enum MigrateCmdParseState : byte
{
Expand Down
4 changes: 2 additions & 2 deletions libs/server/Databases/DatabaseManagerBase.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System;
Expand Down Expand Up @@ -551,7 +551,7 @@ private async Task InitiateCheckpointAsync(GarnetDatabase db, bool full, Checkpo
using var iter1 = db.Store.Log.Scan(db.Store.Log.ReadOnlyAddress, db.Store.Log.TailAddress, DiskScanBufferingMode.SinglePageBuffering, includeClosedRecords: true);
while (iter1.GetNext())
{
if (!iter1.Info.ValueIsObject)
if (!iter1.DataHeader.ValueIsObject)
continue;

var valueObject = iter1.ValueObject;
Expand Down
12 changes: 7 additions & 5 deletions libs/server/Servers/GarnetServerOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -820,18 +820,20 @@ public int MemorySizeBits(string memorySize)

/// <summary>
/// Parse and validate <see cref="ValueOverflowThreshold"/> as a byte count.
/// Tsavorite requires this to be at least 64 bytes (1 &lt;&lt; LogSettings.kLowestMaxInlineSizeBits)
/// and at most 256 MB (1 &lt;&lt; (LogSettings.kMaxStringSizeBits - 1)). The value will be rounded down to the previous power of 2.
/// Additionally, the effective (power-of-2) value must be strictly less than the effective PageSize
/// Tsavorite requires this to be at least 64 bytes and at most 0xFFFFFE (the RecordDataHeader value-length field's
/// inline limit; see <c>LogSettings.MaxInlineValueSizeLimit</c> — this value MUST be kept in sync because LogSettings
/// is internal to Tsavorite.core and not visible from Garnet.server).
/// The value will be used directly.
/// Additionally, the effective value must be strictly less than the effective PageSize
/// so that a value of this size, plus per-record overhead, can be allocated within a single page;
/// if not, it is clamped down to the largest valid value (with a warning).
/// </summary>
/// <returns>The byte value used for <c>KVSettings.MaxInlineValueSize</c>.</returns>
/// <exception cref="Exception">Thrown when the value cannot be parsed or is outside the allowed byte range.</exception>
public int ValueOverflowThresholdBytes()
{
const long MinBytes = 64L; // 1 << LogSettings.kLowestMaxInlineSizeBits
const long MaxBytes = 1L << 28; // 1 << (LogSettings.kMaxStringSizeBits - 1)
const long MinBytes = 64L; // LogSettings.MinMaxInlineSize
const long MaxBytes = 0xFFFFFE; // LogSettings.MaxInlineValueSizeLimit (= (1 << kValueLengthBits) - 2)

if (string.IsNullOrEmpty(ValueOverflowThreshold))
throw new Exception($"{nameof(ValueOverflowThreshold)} must be specified");
Expand Down
32 changes: 16 additions & 16 deletions libs/server/Storage/Functions/GarnetRecordTriggers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ public GarnetRecordTriggers(CacheSizeTracker cacheSizeTracker, RangeIndexManager
/// <inheritdoc/>
public void OnDispose(ref LogRecord logRecord, DisposeReason reason)
{
if (!logRecord.Info.ValueIsObject)
if (!logRecord.DataHeader.ValueIsObject)
{
// Free BfTree and delete data files on key deletion.
if (reason is DisposeReason.Deleted or DisposeReason.Expired && logRecord.RecordDataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
if (reason is DisposeReason.Deleted or DisposeReason.Expired && logRecord.DataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
{
rangeIndexManager?.DisposeTreeUnderLock(logRecord.Key, logRecord.ValueSpan, deleteFiles: true);
}

// Request Vector Set cleanup when the index key is deleted.
if (reason is DisposeReason.Deleted or DisposeReason.Expired && logRecord.RecordDataHeader.RecordType == VectorManager.RecordType)
if (reason is DisposeReason.Deleted or DisposeReason.Expired && logRecord.DataHeader.RecordType == VectorManager.RecordType)
{
vectorManager?.RequestDeletion(logRecord.ValueSpan);
}
Expand All @@ -86,8 +86,8 @@ public void OnDispose(ref LogRecord logRecord, DisposeReason reason)
public readonly void OnFlush(ref LogRecord logRecord, long logicalAddress)
{
if (rangeIndexManager is null
|| logRecord.Info.ValueIsObject
|| logRecord.RecordDataHeader.RecordType != RangeIndexManager.RangeIndexRecordType)
|| logRecord.DataHeader.ValueIsObject
|| logRecord.DataHeader.RecordType != RangeIndexManager.RangeIndexRecordType)
return;

rangeIndexManager.SnapshotTreeForFlush(logRecord.Key, logRecord.ValueSpan, logicalAddress);
Expand All @@ -96,16 +96,16 @@ public readonly void OnFlush(ref LogRecord logRecord, long logicalAddress)
/// <inheritdoc/>
public readonly void OnEvict(ref LogRecord logRecord, EvictionSource source)
{
if (!logRecord.Info.ValueIsObject)
if (!logRecord.DataHeader.ValueIsObject)
{
// Free BfTree on page eviction under exclusive lock.
if (logRecord.RecordDataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
if (logRecord.DataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
{
rangeIndexManager?.DisposeTreeUnderLock(logRecord.Key, logRecord.ValueSpan, deleteFiles: false);
}

// Drop DiskANN side of index
if (logRecord.RecordDataHeader.RecordType == VectorManager.RecordType)
if (logRecord.DataHeader.RecordType == VectorManager.RecordType)
{
vectorManager?.DropInMemoryIndex(logRecord.ValueSpan);
}
Expand All @@ -115,17 +115,17 @@ public readonly void OnEvict(ref LogRecord logRecord, EvictionSource source)
/// <inheritdoc/>
public readonly void OnDiskRead(ref LogRecord logRecord)
{
if (!logRecord.Info.ValueIsObject)
if (!logRecord.DataHeader.ValueIsObject)
{
// Invalidate stale TreeHandle bytes on records loaded from disk.
// RIPROMOTE PostCopyUpdater handles file pre-staging when this stub is later promoted.
if (logRecord.RecordDataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
if (logRecord.DataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
{
RangeIndexManager.InvalidateStub(logRecord.ValueSpan);
}

// Clear DiskANN index pointer so we'll recreate it on first touch
if (logRecord.RecordDataHeader.RecordType == VectorManager.RecordType)
if (logRecord.DataHeader.RecordType == VectorManager.RecordType)
{
VectorManager.ClearIndexPointer(logRecord.ValueSpan);
}
Expand All @@ -141,19 +141,19 @@ public readonly void OnRecovery(Guid checkpointToken)
/// <inheritdoc/>
public readonly void OnRecoverySnapshotRead(ref LogRecord logRecord)
{
if (!logRecord.Info.ValueIsObject)
if (!logRecord.DataHeader.ValueIsObject)
{
// Above-FUA-at-checkpoint stubs: pre-stage data.bftree from the checkpoint snapshot
// file DURING recovery (snapshot files may be deleted post-recovery). Below-FUA
// stubs are handled lazily by RIPROMOTE PostCopyUpdater on first access.
if (rangeIndexManager is not null && logRecord.RecordDataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
if (rangeIndexManager is not null && logRecord.DataHeader.RecordType == RangeIndexManager.RangeIndexRecordType)
{
RangeIndexManager.MarkRecoveredFromCheckpoint(logRecord.ValueSpan);
rangeIndexManager.RebuildFromSnapshotIfPending(logRecord.Key);
}

// If we're recovering we might have a context marked as deleting, but the record itself isn't deleted
if (vectorManager is not null && !logRecord.Info.Tombstone && logRecord.RecordDataHeader.RecordType == VectorManager.RecordType)
if (vectorManager is not null && !logRecord.Info.Tombstone && logRecord.DataHeader.RecordType == VectorManager.RecordType)
{
vectorManager.RecoveredVectorSetIndexKey(ref logRecord);
}
Expand Down Expand Up @@ -199,14 +199,14 @@ public readonly void PostCopyToTail<TSourceLogRecord>(in TSourceLogRecord srcLog
// before the next Read-with-RangeIndex-cmd can pass the type-mismatch guard in
// ReadMethods.CheckRecordTypeMismatch.
if (rangeIndexManager is null
|| dstLogRecord.Info.ValueIsObject
|| dstLogRecord.DataHeader.ValueIsObject
|| srcLogRecord.RecordType != RangeIndexManager.RangeIndexRecordType)
return;

// Propagate RecordType from src onto dst (CTT does not do this for us).
// RecordDataHeader is a wrapper struct over the header pointer, so the setter
// writes through to the underlying memory even on this struct value.
var dstHeader = dstLogRecord.RecordDataHeader;
var dstHeader = dstLogRecord.DataHeader;
dstHeader.RecordType = RangeIndexManager.RangeIndexRecordType;

var srcSpan = srcLogRecord.ValueSpan;
Expand Down
4 changes: 2 additions & 2 deletions libs/server/Storage/Functions/LogRecordUtils.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using System;
Expand All @@ -17,6 +17,6 @@ public static class LogRecordUtils
/// <returns>True if the log record has expired; otherwise, false.</returns>
internal static bool CheckExpiry<TSourceLogRecord>(in TSourceLogRecord srcLogRecord)
where TSourceLogRecord : ISourceLogRecord
=> srcLogRecord.Info.HasExpiration && srcLogRecord.Expiration < DateTimeOffset.UtcNow.Ticks;
=> srcLogRecord.DataHeader.HasExpiration && srcLogRecord.Expiration < DateTimeOffset.UtcNow.Ticks;
}
}
3 changes: 1 addition & 2 deletions libs/server/Storage/Functions/MainStore/DeleteMethods.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation.
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

using Tsavorite.core;
Expand All @@ -13,7 +13,6 @@ namespace Garnet.server
/// <inheritdoc />
public bool InitialDeleter(ref LogRecord logRecord, ref DeleteInfo deleteInfo)
{
logRecord.InfoRef.ClearHasETag();
functionsState.watchVersionMap.IncrementVersion(deleteInfo.KeyHash);
return true;
}
Expand Down
12 changes: 6 additions & 6 deletions libs/server/Storage/Functions/MainStore/PrivateMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,12 @@ void CopyRespToWithInput<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref
return;

case RespCommand.TTL:
var ttlValue = ConvertUtils.SecondsFromDiffUtcNowTicks(srcLogRecord.Info.HasExpiration ? srcLogRecord.Expiration : -1);
var ttlValue = ConvertUtils.SecondsFromDiffUtcNowTicks(srcLogRecord.DataHeader.HasExpiration ? srcLogRecord.Expiration : -1);
functionsState.CopyRespNumber(ttlValue, ref output.SpanByteAndMemory);
return;

case RespCommand.PTTL:
var pttlValue = ConvertUtils.MillisecondsFromDiffUtcNowTicks(srcLogRecord.Info.HasExpiration ? srcLogRecord.Expiration : -1);
var pttlValue = ConvertUtils.MillisecondsFromDiffUtcNowTicks(srcLogRecord.DataHeader.HasExpiration ? srcLogRecord.Expiration : -1);
functionsState.CopyRespNumber(pttlValue, ref output.SpanByteAndMemory);
return;

Expand All @@ -310,12 +310,12 @@ void CopyRespToWithInput<TSourceLogRecord>(in TSourceLogRecord srcLogRecord, ref
CopyRespTo(value, ref output, start, end);
return;
case RespCommand.EXPIRETIME:
var expireTime = ConvertUtils.UnixTimeInSecondsFromTicks(srcLogRecord.Info.HasExpiration ? srcLogRecord.Expiration : -1);
var expireTime = ConvertUtils.UnixTimeInSecondsFromTicks(srcLogRecord.DataHeader.HasExpiration ? srcLogRecord.Expiration : -1);
functionsState.CopyRespNumber(expireTime, ref output.SpanByteAndMemory);
return;

case RespCommand.PEXPIRETIME:
var pexpireTime = ConvertUtils.UnixTimeInMillisecondsFromTicks(srcLogRecord.Info.HasExpiration ? srcLogRecord.Expiration : -1);
var pexpireTime = ConvertUtils.UnixTimeInMillisecondsFromTicks(srcLogRecord.DataHeader.HasExpiration ? srcLogRecord.Expiration : -1);
functionsState.CopyRespNumber(pexpireTime, ref output.SpanByteAndMemory);
return;

Expand All @@ -329,7 +329,7 @@ IPUResult EvaluateExpireInPlace(ref LogRecord logRecord, ExpireOption optionType
ref var result = ref output.AsRef<int>();
result = 0;

if (!EvaluateExpire(ref logRecord, optionType, newExpiry, logRecord.Info.HasExpiration, logErrorOnFail: false, functionsState.logger, out var expirationChanged))
if (!EvaluateExpire(ref logRecord, optionType, newExpiry, logRecord.DataHeader.HasExpiration, logErrorOnFail: false, functionsState.logger, out var expirationChanged))
return IPUResult.Failed;

if (!expirationChanged)
Expand All @@ -341,7 +341,7 @@ IPUResult EvaluateExpireInPlace(ref LogRecord logRecord, ExpireOption optionType

bool EvaluateExpireCopyUpdate(ref LogRecord logRecord, in RecordSizeInfo sizeInfo, ExpireOption optionType, long newExpiry, ReadOnlySpan<byte> newValue, ref StringOutput output)
{
var hasExpiration = logRecord.Info.HasExpiration;
var hasExpiration = logRecord.DataHeader.HasExpiration;

ref var result = ref output.AsRef<int>();
result = 0;
Expand Down
Loading
Loading