github.com/git-amp/amp-sdk-go@v0.7.5/stdlib/symbol/api.symbol.go (about) 1 package symbol 2 3 import ( 4 "encoding/binary" 5 "errors" 6 7 "github.com/git-amp/amp-sdk-go/stdlib/generics" 8 ) 9 10 // ID is a persistent integer value associated with an immutable string or buffer value. 11 // ID == 0 always maps to the empty string / buf. 12 type ID uint32 13 14 // Ord returns the ordinal value of this ID (a type recasting to uint32) 15 func (id ID) Ord() uint32 { 16 return uint32(id) 17 } 18 19 // IDSz is the byte size of a symbol.ID (big endian) 20 // The tradeoff is between key bytes idle (wasted) in a massive db and exponentially more IDs available. 21 // 22 // The thinking of a 4 byte ID is that an symbol table exceeding 100 million entries is impractical and inefficient. 23 // If a billion symbol IDs is "not enough" then you are issuing IDs for the wrong purpose. 24 const IDSz = 4 25 26 // DefaultIssuerMin specifies the default minimum ID value for newly issued IDs. 27 // 28 // ID values less than this value are reserved for clients to represent hard-wired or "out of band" meaning. 29 // "Hard-wired" meaning that Table.SetSymbolID() can be called with IDs less than MinIssuedID without risk 30 // of an auto-issued ID contending with it. 31 const DefaultIssuerMin = 600 32 33 type Issuer interface { 34 generics.RefCloser 35 36 // Issues the next sequential unique ID, starting at MinIssuedID. 37 IssueNextID() (ID, error) 38 } 39 40 var ErrIssuerNotOpen = errors.New("issuer not open") 41 42 // Table abstracts value-ID storage and two-way lookup. 43 type Table interface { 44 generics.RefCloser 45 46 // Returns the Issuer being used by this Table (passed via TableOpts.Issuer or auto-created if no TableOpts.Issuer was given) 47 // Note that retained references should make use of generics.RefCloser to ensure proper closure. 48 Issuer() Issuer 49 50 // Returns the symbol ID previously associated with the given string/buffer value. 51 // The given value buffer is never retained. 52 // 53 // If not found and autoIssue == true, a new entry is created and the new ID returned. 54 // Newly issued IDs are always > 0 and use the lower bytes of the returned ID (see type ID comments). 55 // 56 // If not found and autoIssue == false, 0 is returned. 57 GetSymbolID(value []byte, autoIssue bool) ID 58 59 // Associates the given buffer value to the given symbol ID, allowing multiple values to be mapped to a single ID. 60 // If ID == 0, then this is the equivalent to GetSymbolID(value, true). 61 SetSymbolID(value []byte, ID ID) ID 62 63 // Looks up and appends the byte string associated with the given symbol ID to the given buf. 64 // If ID is invalid or not found, nil is returned. 65 GetSymbol(ID ID, io []byte) []byte 66 } 67 68 // Reads a big endian encoded uint32 ID from the given byte slice 69 func ReadID(in []byte) (uint32, []byte) { 70 ID := binary.BigEndian.Uint32(in) 71 return ID, in[IDSz:] 72 } 73 74 // Reads an ID from the given byte slice (reading IDSz=4 bytes) 75 func (id *ID) ReadFrom(in []byte) { 76 *id = ID(binary.BigEndian.Uint32(in)) 77 } 78 79 func AppendID(io []byte, ID uint32) []byte { 80 return append(io, // big endian marshal 81 byte(ID>>24), 82 byte(ID>>16), 83 byte(ID>>8), 84 byte(ID)) 85 } 86 87 func (id ID) AppendTo(io []byte) []byte { 88 return append(io, // big endian marshal 89 byte(uint32(id)>>24), 90 byte(uint32(id)>>16), 91 byte(uint32(id)>>8), 92 byte(id)) 93 }