Node struct enlarged to 40 bytes. There is no significant

slowdown and a slight memory usage increase. Fixed a potential
bug in Reader. Tag is now implemented as a zero-terminated
string, removing the need for global state.
Node opIndex now returns a reference.
This commit is contained in:
Ferdinand Majerech 2011-10-26 21:05:56 +02:00
parent 6eda5d9d4a
commit c787531497
7 changed files with 62 additions and 30 deletions

2
cdc.d
View file

@ -226,7 +226,7 @@ void main(string[] args)
case "all": build("debug", "release", "unittest"); break;
default:
writeln("unknown build target: ", target);
writeln("available targets: 'debug', 'release', 'all'");
writeln("available targets: 'debug', 'release', 'profile', 'all'");
}
}

View file

@ -669,9 +669,9 @@ unittest
Node[] pairs;
foreach(long i; 0 .. length)
{
auto pair = (i % 2) ? Pair(Node.rawNode(Node.Value(to!string(i))), Node.rawNode(Node.Value(i)))
: Pair(Node.rawNode(Node.Value(i)), Node.rawNode(Node.Value(to!string(i))));
pairs ~= Node.rawNode(Node.Value([pair]));
auto pair = (i % 2) ? Pair(to!string(i), i)
: Pair(i, to!string(i));
pairs ~= Node([pair]);
}
return pairs;
}
@ -681,8 +681,8 @@ unittest
Node[] pairs;
foreach(long i; 0 .. length)
{
auto pair = Pair(Node.rawNode(Node.Value(to!string(i))), Node.rawNode(Node.Value(i)));
pairs ~= Node.rawNode(Node.Value([pair]));
auto pair = Pair(to!string(i), i);
pairs ~= Node([pair]);
}
return pairs;
}
@ -736,7 +736,7 @@ unittest
Node.Pair[] pairs;
foreach(long i; 0 .. length)
{
pairs ~= Node.Pair(Node.rawNode(Node.Value(to!string(i))), Node.rawNode(Node.Value(YAMLNull())));
pairs ~= Node.Pair(to!string(i), YAMLNull());
}
return pairs;

View file

@ -632,7 +632,7 @@ struct Node
* non-integral index is used with a sequence or the node is
* not a collection.
*/
Node opIndex(T)(T index)
ref Node opIndex(T)(T index)
{
if(isSequence)
{

View file

@ -126,7 +126,8 @@ final class Reader
}
available_ = stream_.available;
bufferReserve(256);
auto ptr = cast(dchar*)core.stdc.stdlib.malloc(dchar.sizeof * 256);
bufferAllocated_ = ptr[0 .. 256];
}
///Destroy the Reader.

View file

@ -146,20 +146,14 @@ struct Serializer
}
anchors_[node] = Anchor(null);
if(node.isSequence)
if(node.isSequence) foreach(ref Node item; node)
{
foreach(ref Node item; node)
{
anchorNode(item);
}
anchorNode(item);
}
else if(node.isMapping)
else if(node.isMapping) foreach(ref Node key, ref Node value; node)
{
foreach(ref Node key, ref Node value; node)
{
anchorNode(key);
anchorNode(value);
}
anchorNode(key);
anchorNode(value);
}
}
@ -205,7 +199,7 @@ struct Serializer
}
if(node.isSequence)
{
auto defaultTag = resolver_.defaultSequenceTag;
const defaultTag = resolver_.defaultSequenceTag;
bool implicit = node.tag_ == defaultTag;
emitter_.emit(sequenceStartEvent(Mark(), Mark(), aliased, node.tag_,
implicit, CollectionStyle.Invalid));

View file

@ -33,9 +33,7 @@ template SharedObject(T, MixedIn)
*
* When this reaches zero, objects_ are cleared. This is not
* the number of shared objects, but rather of objects using this kind
* of shared object. This is used e.g. with Anchor, but not with Tag
* - tags can be stored by the user in Nodes so there is no way to know
* when there are no Tags anymore.
* of shared object.
*/
int referenceCount_ = 0;
@ -124,7 +122,7 @@ template SharedObject(T, MixedIn)
}
///Is this object null (invalid)?
bool isNull() const {return index_ == uint.max;}
@property bool isNull() const {return index_ == uint.max;}
private:
///Add a new object, checking if identical object already exists.

View file

@ -7,24 +7,63 @@
///YAML tag.
module dyaml.tag;
import dyaml.sharedobject;
import core.stdc.string;
///YAML tag (data type) struct. Encapsulates a tag to save memory and speed-up comparison.
struct Tag
{
public:
mixin SharedObject!(string, Tag);
private:
///Zero terminated tag string.
immutable(char)* tag_ = null;
public:
///Construct a tag from a string representation.
this(string tag)
{
if(tag is null || tag == "")
{
index_ = uint.max;
tag_ = null;
return;
}
add(tag);
tag_ = (tag ~ '\0').ptr;
}
///Get the tag string.
@property string get() const
in{assert(!isNull());}
body
{
return cast(string)tag_[0 .. strlen(tag_)];
}
///Test for equality with another tag.
bool opEquals(const ref Tag tag) const
{
return isNull ? tag.isNull :
tag.isNull ? false : (0 == strcmp(tag_, tag.tag_));
}
///Compute a hash.
hash_t toHash() const
in{assert(!isNull);}
body
{
static type = typeid(string);
auto str = get();
return type.getHash(&str);
}
///Compare with another tag.
int opCmp(const ref Tag tag) const
in{assert(!isNull && !tag.isNull);}
body
{
return strcmp(tag_, tag.tag_);
}
///Is this tag null (invalid)?
@property bool isNull() const {return tag_ is null;}
}