1 module nxt.address; 2 3 @safe pure nothrow @nogc: 4 5 /** Address as an unsigned integer. 6 * 7 * Used as key, value or element instead of a pointer `OpenHashMap` to 8 * prevent triggering of `gc_addRange` and `gc_removeRange`. 9 * 10 * TODO is `holeValue` suitably chosen? 11 * 12 * See_Also: https://en.wikipedia.org/wiki/Data_structure_alignment 13 */ 14 struct ByteAlignedAddress(uint byteAlignment_) // TODO adjust alignment here 15 { 16 enum byteAlignment = byteAlignment_; ///< Alignment in bytes. 17 18 /// Null value. 19 static immutable typeof(this) nullValue = typeof(this).init; 20 21 /// Hole/Deletion value. Prevent hole bitmap from being used. 22 static immutable typeof(this) holeValue = typeof(this)(_ptrValue.max); 23 24 /** Get hash of `this`, with extra fast computation for the small case. 25 */ 26 @property hash_t toHash() const scope @trusted 27 { 28 version(LDC) pragma(inline, true); 29 // TODO cativate import nxt.hash_functions : lemireHash64; 30 import core.internal.hash : hashOf; 31 static if (byteAlignment == 1) 32 { 33 return _ptrValue; // as is 34 } 35 else static if (byteAlignment == 2) 36 { 37 assert((_ptrValue & 0x1) == 0); // 1 least significant bit cleared 38 return _ptrValue >> 1; 39 } 40 else static if (byteAlignment == 4) 41 { 42 assert((_ptrValue & 0x3) == 0); // 2 least significant bits cleared 43 return _ptrValue >> 2; 44 } 45 else static if (byteAlignment == 8) 46 { 47 assert((_ptrValue & 0x7) == 0); // 3 least significant bits cleared 48 return _ptrValue >> 3; 49 } 50 else 51 { 52 static assert(0, "Unsupported byteAlignment"); 53 } 54 } 55 56 size_t _ptrValue; ///< Actual pointer value. 57 alias _ptrValue this; 58 } 59 alias Address1 = ByteAlignedAddress!(1); 60 alias Address2 = ByteAlignedAddress!(2); 61 alias Address4 = ByteAlignedAddress!(4); 62 alias Address8 = ByteAlignedAddress!(8); 63 64 alias Address = Address1; 65 66 /// 67 @safe pure unittest 68 { 69 import nxt.nullable_traits : hasNullValue, isNullable; 70 import nxt.open_hashmap : OpenHashMap; 71 72 static assert(hasNullValue!Address); 73 static assert(isNullable!Address); 74 75 OpenHashMap!(Address, Address) m; 76 77 static assert(m.sizeof == 3*size_t.sizeof); // assure that hole bitmap is not used 78 79 foreach (const address; 1 .. 0x1000) 80 { 81 const key = address; 82 const value = 2*address; 83 84 assert(Address(key) !in m); 85 86 m[Address(key)] = Address(value); 87 88 assert(m[Address(key)] == Address(value)); 89 assert(Address(key) in m); 90 } 91 }