Improve error handling for string interning
This commit is contained in:
parent
f3d422ecab
commit
3a10d4bb72
35
stdx/lexer.d
35
stdx/lexer.d
|
@ -799,21 +799,26 @@ public:
|
||||||
*/
|
*/
|
||||||
string intern(const(ubyte)[] str) pure nothrow @safe
|
string intern(const(ubyte)[] str) pure nothrow @safe
|
||||||
{
|
{
|
||||||
|
if (str is null || str.length == 0)
|
||||||
|
return "";
|
||||||
immutable uint hash = hashBytes(str);
|
immutable uint hash = hashBytes(str);
|
||||||
return intern(str, hash);
|
return intern(str, hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ditto
|
||||||
|
*/
|
||||||
|
string intern(string str) pure nothrow @trusted
|
||||||
|
{
|
||||||
|
return intern(cast(ubyte[]) str);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caches a string as above, but uses the given hash code instead of
|
* Caches a string as above, but uses the given hash code instead of
|
||||||
* calculating one itself. Use this alongside $(LREF hashStep)() can reduce the
|
* calculating one itself. Use this alongside $(LREF hashStep)() can reduce the
|
||||||
* amount of work necessary when lexing dynamic tokens.
|
* amount of work necessary when lexing dynamic tokens.
|
||||||
*/
|
*/
|
||||||
string intern(const(ubyte)[] str, uint hash) pure nothrow @safe
|
string intern(const(ubyte)[] str, uint hash) pure nothrow @safe
|
||||||
in
|
|
||||||
{
|
|
||||||
assert (str.length > 0);
|
|
||||||
}
|
|
||||||
body
|
|
||||||
{
|
{
|
||||||
return _intern(str, hash);
|
return _intern(str, hash);
|
||||||
}
|
}
|
||||||
|
@ -835,10 +840,14 @@ public:
|
||||||
*/
|
*/
|
||||||
static enum defaultBucketCount = 2048;
|
static enum defaultBucketCount = 2048;
|
||||||
|
|
||||||
|
size_t allocated;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
string _intern(const(ubyte)[] bytes, uint hash) pure nothrow @trusted
|
string _intern(const(ubyte)[] bytes, uint hash) pure nothrow @trusted
|
||||||
{
|
{
|
||||||
|
if (bytes is null || bytes.length == 0)
|
||||||
|
return "";
|
||||||
import core.atomic;
|
import core.atomic;
|
||||||
import core.memory;
|
import core.memory;
|
||||||
shared ubyte[] mem;
|
shared ubyte[] mem;
|
||||||
|
@ -852,6 +861,7 @@ private:
|
||||||
return cast(string) s.str;
|
return cast(string) s.str;
|
||||||
if (mem.length == 0)
|
if (mem.length == 0)
|
||||||
{
|
{
|
||||||
|
atomicOp!"+="(allocated, bytes.length);
|
||||||
mem = allocate(bytes.length);
|
mem = allocate(bytes.length);
|
||||||
mem[] = bytes[];
|
mem[] = bytes[];
|
||||||
}
|
}
|
||||||
|
@ -872,7 +882,7 @@ private:
|
||||||
shared(Node)* node = buckets[index];
|
shared(Node)* node = buckets[index];
|
||||||
while (node !is null)
|
while (node !is null)
|
||||||
{
|
{
|
||||||
if (node.hash >= hash && bytes.equal(cast(ubyte[]) node.str))
|
if (node.hash >= hash && bytes == cast(ubyte[]) node.str)
|
||||||
{
|
{
|
||||||
found = true;
|
found = true;
|
||||||
return node;
|
return node;
|
||||||
|
@ -883,9 +893,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint hashBytes(const(ubyte)[] data) pure nothrow @trusted
|
static uint hashBytes(const(ubyte)[] data) pure nothrow @trusted
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assert (data !is null);
|
||||||
|
assert (data.length > 0);
|
||||||
|
}
|
||||||
|
body
|
||||||
{
|
{
|
||||||
uint hash = 0;
|
uint hash = 0;
|
||||||
foreach (b; data)
|
foreach (ubyte b; data)
|
||||||
{
|
{
|
||||||
hash ^= sbox[b];
|
hash ^= sbox[b];
|
||||||
hash *= 3;
|
hash *= 3;
|
||||||
|
@ -898,6 +914,10 @@ private:
|
||||||
{
|
{
|
||||||
assert (numBytes != 0);
|
assert (numBytes != 0);
|
||||||
}
|
}
|
||||||
|
out (result)
|
||||||
|
{
|
||||||
|
assert (result.length == numBytes);
|
||||||
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
import core.atomic;
|
import core.atomic;
|
||||||
|
@ -933,6 +953,7 @@ private:
|
||||||
return b.bytes[0 .. numBytes];
|
return b.bytes[0 .. numBytes];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static shared struct Node
|
static shared struct Node
|
||||||
|
|
Loading…
Reference in New Issue