ndr: Use ndr_steal to avoid long lists
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Tue, 1 Mar 2016 01:18:52 +0000 (14:18 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 22 Mar 2016 07:00:31 +0000 (08:00 +0100)
When pulling complex structures like nt-acls, a long list of tokens may
be produced. By removing tokens along the way with ndr_token_steal,
future calls to retrieve from the token list are not as expensive.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm

index c53ec4a8690d631b1177733bc3ae6eba0cc510af..29cdfa9123bb1b00d30c389c91b904ea72bede6f 100644 (file)
@@ -2093,7 +2093,7 @@ sub ParseUnionPull($$$$)
 {
        my ($self,$e,$ndr,$varname) = @_;
        my $switch_type = $e->{SWITCH_TYPE};
-
+        my $needs_deferred_switch = is_deferred_switch_non_empty($e);
        $self->pidl("uint32_t level;");
        if (defined($switch_type)) {
                if (Parse::Pidl::Typelist::typeIs($switch_type, "ENUM")) {
@@ -2117,18 +2117,24 @@ sub ParseUnionPull($$$$)
        $self->pidl("NDR_PULL_CHECK_FLAGS(ndr, ndr_flags);");
        $self->pidl("if (ndr_flags & NDR_SCALARS) {");
        $self->indent;
-        $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);");
+       if (! $needs_deferred_switch) {
+               $self->pidl("/* This token is not used again */");
+               $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
+       } else {
+               $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);");
+       }
        $self->ParseUnionPullPrimitives($e,$ndr,$varname,$switch_type);
        $self->deindent;
        $self->pidl("}");
-        if (is_deferred_switch_non_empty($e)) {
-                $self->pidl("if (ndr_flags & NDR_BUFFERS) {");
-                $self->indent;
-                $self->pidl("level = ndr_pull_get_switch_value($ndr, $varname);");
-                $self->ParseUnionPullDeferred($e,$ndr,$varname);
-                $self->deindent;
-                $self->pidl("}");
-        }
+       if ($needs_deferred_switch) {
+               $self->pidl("if (ndr_flags & NDR_BUFFERS) {");
+               $self->indent;
+               $self->pidl("/* The token is not needed after this. */");
+               $self->pidl("level = ndr_pull_steal_switch_value($ndr, $varname);");
+               $self->ParseUnionPullDeferred($e,$ndr,$varname);
+               $self->deindent;
+               $self->pidl("}");
+       }
        $self->add_deferred();
 
        $self->end_flags($e, $ndr);