/// <summary> /// Xors the two bit fields, respecting the upper 32 bits as an ID. /// </summary> /// <param name="bitsA">The most significant bits of Tag A.</param> /// <param name="bitsB">The most significant bits of Tag B.</param> /// <returns>The most significant bits of Tag A XOR Tag B.</returns> internal static ulong TranspileXor(ulong bitsA, ulong bitsB) { ulong result = GetLowerBits(bitsA) ^ GetLowerBits(bitsB); int ubA = GetUpperBits(bitsA), ubB = GetUpperBits(bitsB), ubResult; if (ubA == 0) { ubResult = ubB; } else if (ubB == 0) { ubResult = ubA; } else { // Both nonzero var inst = ExtendedTagBits.Instance; var bitSetA = BitSetPool.Allocate(); bitSetA.SetTo(inst.GetTagBits(ubA)); bitSetA.Xor(inst.GetTagBits(ubB)); ubResult = inst.GetIDWithBits(bitSetA); BitSetPool.Recycle(bitSetA); } return(result | ((ulong)ubResult << 32)); }
private static ulong NotHighBits(ulong bits) { int ubA = GetUpperBits(bits); var inst = ExtendedTagBits.Instance; var notSet = BitSetPool.Allocate(); notSet.SetTo(inst.GetTagBits(ubA)); notSet.Not(MAX_BITS); int id = inst.GetIDWithBits(notSet); BitSetPool.Recycle(notSet); return((ulong)id << 32); }
/// <summary> /// Gets the ID to use for tag bits that have the specified ID cleared. /// </summary> /// <param name="id">The existing ID.</param> /// <param name="extIndex">The tag index to clear.</param> /// <returns>A new or reused ID with that tag bit clear.</returns> public int GetIDWithTagClear(int id, int extIndex) { if (id < INITIAL_TAG_BITS) { // Cleared a tag bit in the initial 1024 id = (id == extIndex + 1) ? 0 : id; } else { var bits = BitSetPool.Allocate(); bits.SetTo(GetTagBits(id)); bits.Set(extIndex, false); id = GetIDWithBits(bits); BitSetPool.Recycle(bits); } return(id); }
/// <summary> /// Gets the ID to use for tag bits that have the specified ID set. /// </summary> /// <param name="id">The existing ID.</param> /// <param name="extIndex">The tag index to set.</param> /// <returns>A new or reused ID with that tag bit set.</returns> public int GetIDWithTagSet(int id, int extIndex) { if ((extIndex >= INITIAL_TAG_BITS || id != 0) && id != extIndex + 1) { var bits = BitSetPool.Allocate(); bits.SetTo(GetTagBits(id)); bits.Set(extIndex, true); id = GetIDWithBits(bits); BitSetPool.Recycle(bits); } else { // All bits are clear, use the optimized route to avoid allocating id = extIndex + 1; } return(id); }