blob: 8dc370d1efa1ff1265b1f3d738678adc832d768e [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
namespace Org.Apache.Rocketmq
{
/**
* MessageId generate rules refer: https://yuque.antfin-inc.com/aone709911/ca1edg/af2t6o
*/
public class MessageIdGenerator
{
public static readonly string version = "01";
private static readonly MessageIdGenerator Instance = new();
private readonly string _prefix;
private readonly long _secondsSinceCustomEpoch;
private readonly Stopwatch _stopwatch;
private int _sequence;
private MessageIdGenerator()
{
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
var macAddress = Utilities.GetMacAddress();
writer.Write(macAddress, 0, 6);
int processId = Utilities.GetProcessId();
byte[] processIdBytes = BitConverter.GetBytes(processId);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(processIdBytes);
}
writer.Write(processIdBytes, 2, 2);
var array = stream.ToArray();
_prefix = version + Utilities.ByteArrayToHexString(array);
DateTime epoch = new DateTime(2021, 1, 1,
0, 0, 0, 0, DateTimeKind.Utc);
var now = DateTime.Now;
_secondsSinceCustomEpoch = Convert.ToInt64(now.ToUniversalTime().Subtract(epoch).TotalSeconds);
_stopwatch = Stopwatch.StartNew();
_sequence = 0;
}
public String Next()
{
long deltaSeconds = _secondsSinceCustomEpoch + _stopwatch.ElapsedMilliseconds / 1_000;
MemoryStream stream = new MemoryStream();
BinaryWriter writer = new BinaryWriter(stream);
byte[] deltaSecondsBytes = BitConverter.GetBytes(deltaSeconds);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(deltaSecondsBytes);
}
writer.Write(deltaSecondsBytes, 4, 4);
int no = Interlocked.Increment(ref _sequence);
byte[] noBytes = BitConverter.GetBytes(no);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(noBytes);
}
writer.Write(noBytes);
var suffixBytes = stream.ToArray();
return _prefix + Utilities.ByteArrayToHexString(suffixBytes);
}
public static MessageIdGenerator GetInstance()
{
return Instance;
}
}
}