1 /* key-gen.c --- manufacturing sequential keys for some db tables
3 * ====================================================================
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
20 * ====================================================================
27 #include <apr_network_io.h>
28 #include "private/svn_fs_private.h"
31 /* The Berkeley DB backend uses a key as a transaction name and the
32 maximum key size must be less than the maximum transaction name
34 #if MAX_KEY_SIZE > SVN_FS__TXN_MAX_LEN
35 #error The MAX_KEY_SIZE used for BDB txn names is greater than SVN_FS__TXN_MAX_LEN.
39 /*** Keys for reps and strings. ***/
42 svn_fs_fs__add_keys(const char *key1, const char *key2, char *result)
44 apr_ssize_t i1 = strlen(key1) - 1;
45 apr_ssize_t i2 = strlen(key2) - 1;
49 char buf[MAX_KEY_SIZE + 2];
51 while ((i1 >= 0) || (i2 >= 0) || (carry > 0))
55 val += (key1[i1] <= '9') ? (key1[i1] - '0') : (key1[i1] - 'a' + 10);
58 val += (key2[i2] <= '9') ? (key2[i2] - '0') : (key2[i2] - 'a' + 10);
63 buf[i3++] = (char)((val <= 9) ? (val + '0') : (val - 10 + 'a'));
71 /* Now reverse the resulting string and NULL terminate it. */
72 for (i1 = 0; i1 < i3; i1++)
73 result[i1] = buf[i3 - i1 - 1];
80 svn_fs_fs__next_key(const char *this, apr_size_t *len, char *next)
83 apr_size_t olen = *len; /* remember the first length */
84 char c; /* current char */
85 svn_boolean_t carry = TRUE; /* boolean: do we have a carry or not?
86 We start with a carry, because we're
87 incrementing the number, after all. */
89 /* Leading zeros are not allowed, except for the string "0". */
90 if ((*len > 1) && (this[0] == '0'))
96 for (i = (olen - 1); i >= 0; i--)
100 /* Validate as we go. */
101 if (! (((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'z'))))
125 /* The new length is OLEN, plus 1 if there's a carry out of the
127 *len = olen + (carry ? 1 : 0);
129 /* Ensure that we haven't overrun the (ludicrous) bound on key length.
130 Note that MAX_KEY_SIZE is a bound on the size *including*
131 the trailing null byte. */
132 assert(*len < MAX_KEY_SIZE);
134 /* Now we know it's safe to add the null terminator. */
137 /* Handle any leftover carry. */
140 memmove(next+1, next, olen);
147 svn_fs_fs__key_compare(const char *a, const char *b)
149 apr_size_t a_len = strlen(a);
150 apr_size_t b_len = strlen(b);
158 return (cmp ? (cmp / abs(cmp)) : 0);