简体   繁体   English

BSON ID生成器的C#实现?

[英]C# implementaion of BSON id generator?

Does anyone know if there's an existing c# implementation of a BSON ID generator? 有谁知道BSON ID生成器是否已有c#实现?

I need to generate Mongodb objectIDs on a .NET client, but am not able to use external dlls, so need to do it in code. 我需要在.NET客户端上生成Mongodb objectID,但无法使用外部dll,因此需要在代码中进行。 I couldn't find anything on google, so probably will end up having to write my own, but wanted to check with others first. 我在Google上找不到任何东西,所以最终可能不得不写我自己的东西,但想先与他人核对一下。

Thanks. 谢谢。

You can simply copy the implementation to your codebase if you are not allowed to reference the package. 如果不允许引用该程序包,则可以简单地将实现复制到您的代码库中。 Below is simplified version of it. 下面是它的简化版本。

using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Security;
using System.Threading;

public struct ObjectId
{
    private static readonly ObjectId __emptyInstance = default(ObjectId);
    private static readonly int __staticMachine = (GetMachineHash() + GetAppDomainId()) & 0x00ffffff;
    private static readonly short __staticPid = GetPid();
    private static int __staticIncrement = new Random().Next();
    private static readonly DateTime __unixEpoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);

    private readonly int _a;
    private readonly int _b;
    private readonly int _c;

    private ObjectId(int timestamp, int machine, short pid, int increment)
    {
        _a = timestamp;
        _b = (machine << 8) | ((pid >> 8) & 0xff);
        _c = (pid << 24) | increment;
    }

    public static ObjectId GenerateNewId()
    {
        return GenerateNewId(GetTimestampFromDateTime(DateTime.UtcNow));
    }

    public static ObjectId GenerateNewId(int timestamp)
    {
        var increment = Interlocked.Increment(ref __staticIncrement) & 0x00ffffff; // only use low order 3 bytes
        return new ObjectId(timestamp, __staticMachine, __staticPid, increment);
    }

    private static int GetAppDomainId()
    {
        return AppDomain.CurrentDomain.Id;
    }

    [MethodImpl(MethodImplOptions.NoInlining)]
    private static int GetCurrentProcessId()
    {
        return Process.GetCurrentProcess().Id;
    }

    private static int GetMachineHash()
    {
        var machineName = GetMachineName();
        return 0x00ffffff & machineName.GetHashCode(); // use first 3 bytes of hash
    }

    private static string GetMachineName()
    {
        return Environment.MachineName;
    }

    private static short GetPid()
    {
        try
        {
            return (short) GetCurrentProcessId(); // use low order two bytes only
        }
        catch (SecurityException)
        {
            return 0;
        }
    }

    private static int GetTimestampFromDateTime(DateTime timestamp)
    {
        var secondsSinceEpoch = (long) Math.Floor((ToUniversalTime(timestamp) - __unixEpoch).TotalSeconds);
        if (secondsSinceEpoch < int.MinValue || secondsSinceEpoch > int.MaxValue)
            throw new ArgumentOutOfRangeException("timestamp");
        return (int) secondsSinceEpoch;
    }

    public override string ToString()
    {
        var c = new char[24];
        c[0] = ToHexChar((_a >> 28) & 0x0f);
        c[1] = ToHexChar((_a >> 24) & 0x0f);
        c[2] = ToHexChar((_a >> 20) & 0x0f);
        c[3] = ToHexChar((_a >> 16) & 0x0f);
        c[4] = ToHexChar((_a >> 12) & 0x0f);
        c[5] = ToHexChar((_a >> 8) & 0x0f);
        c[6] = ToHexChar((_a >> 4) & 0x0f);
        c[7] = ToHexChar(_a & 0x0f);
        c[8] = ToHexChar((_b >> 28) & 0x0f);
        c[9] = ToHexChar((_b >> 24) & 0x0f);
        c[10] = ToHexChar((_b >> 20) & 0x0f);
        c[11] = ToHexChar((_b >> 16) & 0x0f);
        c[12] = ToHexChar((_b >> 12) & 0x0f);
        c[13] = ToHexChar((_b >> 8) & 0x0f);
        c[14] = ToHexChar((_b >> 4) & 0x0f);
        c[15] = ToHexChar(_b & 0x0f);
        c[16] = ToHexChar((_c >> 28) & 0x0f);
        c[17] = ToHexChar((_c >> 24) & 0x0f);
        c[18] = ToHexChar((_c >> 20) & 0x0f);
        c[19] = ToHexChar((_c >> 16) & 0x0f);
        c[20] = ToHexChar((_c >> 12) & 0x0f);
        c[21] = ToHexChar((_c >> 8) & 0x0f);
        c[22] = ToHexChar((_c >> 4) & 0x0f);
        c[23] = ToHexChar(_c & 0x0f);
        return new string(c);
    }

    private static char ToHexChar(int value)
    {
        return (char) (value + (value < 10 ? '0' : 'a' - 10));
    }

    private static DateTime ToUniversalTime(DateTime dateTime)
    {
        if (dateTime == DateTime.MinValue)
            return DateTime.SpecifyKind(DateTime.MinValue, DateTimeKind.Utc);
        if (dateTime == DateTime.MaxValue)
            return DateTime.SpecifyKind(DateTime.MaxValue, DateTimeKind.Utc);
        return dateTime.ToUniversalTime();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM