Signed-off-by: Jeremy Kerr <j...@ozlabs.org>

---
 src/backend/utils/adt/varchar.c |   24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 5f3c658..6889dff 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -624,16 +624,34 @@ varchartypmodout(PG_FUNCTION_ARGS)
 static int
 bcTruelen(BpChar *arg)
 {
+       const unsigned int spaces = 0x20202020;
+       const int       wordsize = sizeof(spaces);
        char       *s = VARDATA_ANY(arg);
        int                     i;
-       int                     len;
 
-       len = VARSIZE_ANY_EXHDR(arg);
-       for (i = len - 1; i >= 0; i--)
+       i = VARSIZE_ANY_EXHDR(arg) - 1;
+
+       /* compare down to an aligned boundary */
+       for (; i >= 0 && i % wordsize != wordsize - 1; i--)
        {
                if (s[i] != ' ')
+                       return i + 1;
+       }
+
+       /* now that we're aligned, compare word at a time */
+       for (; i >= wordsize - 1; i -= wordsize)
+       {
+               if (*(unsigned int *)(s + i - (wordsize - 1)) != spaces)
                        break;
        }
+
+       /* check within the last non-matching word */
+       for (; i >= 0; i--)
+       {
+               if (s[i] != ' ')
+                       break;
+       }
+
        return i + 1;
 }
 

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to