]> granicus.if.org Git - pgbouncer/commitdiff
<usual/aatree.h>
authorMarko Kreen <markokr@gmail.com>
Mon, 11 Jan 2010 05:47:58 +0000 (07:47 +0200)
committerMarko Kreen <markokr@gmail.com>
Tue, 4 May 2010 11:30:49 +0000 (14:30 +0300)
Makefile
include/aatree.h [deleted file]
include/bouncer.h
include/objects.h
src/aatree.c [deleted file]
src/objects.c

index 2ff514a575c5f814da4b4a19b24b4cf551538b35..07a2675201402b6356d71a09dc0dd0d82ff0bee7 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -2,10 +2,10 @@
 # sources
 SRCS = client.c loader.c objects.c pooler.c proto.c sbuf.c server.c util.c \
        admin.c stats.c takeover.c md5.c janitor.c pktbuf.c system.c main.c \
-       varcache.c aatree.c hash.c slab.c
+       varcache.c hash.c slab.c
 HDRS = client.h loader.h objects.h pooler.h proto.h sbuf.h server.h util.h \
        admin.h stats.h takeover.h md5.h janitor.h pktbuf.h system.h bouncer.h \
-       mbuf.h varcache.h aatree.h hash.h slab.h iobuf.h
+       mbuf.h varcache.h hash.h slab.h iobuf.h
 
 # data & dirs to include in tgz
 DOCS = doc/overview.txt doc/usage.txt doc/config.txt doc/todo.txt
diff --git a/include/aatree.h b/include/aatree.h
deleted file mode 100644 (file)
index c040554..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * PgBouncer - Lightweight connection pooler for PostgreSQL.
- * 
- * Copyright (c) 2007-2009  Marko Kreen, Skype Technologies OÜ
- * 
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-typedef struct Node Node;
-typedef struct Tree Tree;
-
-typedef int (*tree_cmp_f)(long, Node *node);
-typedef void (*tree_walker_f)(Node *n, void *arg);
-
-/*
- * Tree header, for storing helper functions.
- */
-struct Tree {
-       Node *root;
-       int count;
-       tree_cmp_f node_cmp;
-       tree_walker_f release_cb;
-};
-
-/*
- * Tree node.
- */
-struct Node {
-       Node *left;     /* smaller values */
-       Node *right;    /* larger values */
-       int level;      /* number of black nodes to leaf */
-};
-
-/*
- * walk order
- */
-enum TreeWalkType {
-       WALK_IN_ORDER = 0, /* left->self->right */
-       WALK_PRE_ORDER = 1, /* self->left->right */
-       WALK_POST_ORDER = 2, /* left->right->self */
-};
-
-void tree_init(Tree *tree, tree_cmp_f cmpfn, tree_walker_f release_cb);
-Node *tree_search(Tree *tree, long value);
-void tree_insert(Tree *tree, long value, Node *node);
-void tree_remove(Tree *tree, long value);
-void tree_walk(Tree *tree, enum TreeWalkType wtype, tree_walker_f walker, void *arg);
-void tree_destroy(Tree *tree);
-
index 86686a9ebc7a866a2755fae531d4fd0a6fb82a4c..f5becd4ac868e607f33a7e2c6077b70dfa563754 100644 (file)
@@ -27,6 +27,7 @@
 #include <usual/statlist.h>
 #include <usual/string.h>
 #include <usual/logging.h>
+#include <usual/aatree.h>
 
 #include <event.h>
 
@@ -74,7 +75,6 @@ typedef struct PktHdr PktHdr;
 
 extern int cf_sbuf_len;
 
-#include "aatree.h"
 #include "hash.h"
 #include "util.h"
 #include "mbuf.h"
@@ -217,7 +217,7 @@ struct PgPool {
 struct PgUser {
        struct List head;               /* used to attach user to list */
        struct List pool_list;          /* list of pools where pool->user == this user */
-       Node tree_node;         /* used to attach user to tree */
+       struct AANode tree_node;        /* used to attach user to tree */
        char name[MAX_USERNAME];
        char passwd[MAX_PASSWORD];
 };
index e9d98a8893dd091cd19372ac8fa325329b2ce5b1..2d7ae80dd6a02f91f058eb6536c7e9560a17df99 100644 (file)
@@ -17,7 +17,7 @@
  */
 
 extern struct StatList user_list;
-extern Tree user_tree;
+extern struct AATree user_tree;
 extern struct StatList pool_list;
 extern struct StatList database_list;
 extern struct StatList autodatabase_idle_list;
diff --git a/src/aatree.c b/src/aatree.c
deleted file mode 100644 (file)
index 051d38b..0000000
+++ /dev/null
@@ -1,310 +0,0 @@
-/*
- * PgBouncer - Lightweight connection pooler for PostgreSQL.
- * 
- * Copyright (c) 2007-2009  Marko Kreen, Skype Technologies OÜ
- * 
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- * 
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-/*
- * Self-balancing binary tree.
- *
- * Here is an implementation of AA-tree (Arne Andersson tree)
- * which is simplification of Red-Black tree.
- *
- * Red-black tree has following properties that must be kept:
- * 1. A node is either red or black.
- * 2. The root is black.
- * 3. All leaves (NIL nodes) are black.
- * 4. Both childen of red node are black.
- * 5. Every path from root to leaf contains same number of black nodes.
- *
- * AA-tree adds additional property:
- * 6. Red node can exist only as a right node.
- *
- * Red-black tree properties quarantee that the longest path is max 2x longer
- * than shortest path (B-R-B-R-B-R-B vs. B-B-B-B) thus the tree will be roughly
- * balanced.  Also it has good worst-case guarantees for insertion and deletion,
- * which makes it good tool for real-time applications.
- *
- * AA-tree removes most special cases from RB-tree, thus making resulting
- * code lot simpler.  It requires slightly more rotations when inserting
- * and deleting but also keeps the tree more balanced.
- */
-
-#include <stddef.h>   /* for NULL */
-
-#include "aatree.h"
-
-/*
- * NIL node
- */
-#define NIL (&_nil)
-static struct Node _nil = { &_nil, &_nil, 0 };
-
-/*
- * Rebalancing.  AA-tree needs only 2 operations
- * to keep the tree balanced.
- */
-
-/*
- * Fix red on left.
- *
- *     X          Y
- *    /     -->    \
- *   Y              X
- *    \            /
- *     a          a
- */
-static inline Node * skew(Node *x)
-{
-       Node *y = x->left;
-       if (x->level == y->level && x != NIL) {
-               x->left = y->right;
-               y->right = x;
-               return y;
-       }
-       return x;
-}
-
-/*
- * Fix 2 reds on right.
- *
- *    X                Y
- *     \              / \
- *      Y      -->   X   Z
- *     / \            \
- *    a   Z            a
- */
-static inline Node * split(Node *x)
-{
-       Node *y = x->right;
-       if (x->level == y->right->level && x != NIL) {
-               x->right = y->left;
-               y->left = x;
-               y->level++;
-               return y;
-       }
-       return x;
-}
-
-/* insert is easy */
-static Node *rebalance_on_insert(Node *current)
-{
-       return split(skew(current));
-}
-
-/* remove is bit more tricky */
-static Node *rebalance_on_remove(Node *current)
-{
-       /*
-        * Removal can create a gap in levels,
-        * fix it by lowering current->level.
-        */
-       if (current->left->level < current->level - 1
-           || current->right->level < current->level - 1)
-       {
-               current->level--;
-
-               /* if ->right is red, change it's level too */
-               if (current->right->level > current->level)
-                       current->right->level = current->level;
-
-               /* reshape, ask Arne about those */
-               current = skew(current);
-               current->right = skew(current->right);
-               current->right->right = skew(current->right->right);
-               current = split(current);
-               current->right = split(current->right);
-       }
-       return current;
-}
-
-/*
- * Recursive insertion
- */
-
-static Node * insert_sub(Tree *tree, Node *current, long value, Node *node)
-{
-       int cmp;
-
-       if (current == NIL) {
-               /*
-                * Init node as late as possible, to avoid corrupting
-                * the tree in case it is already added.
-                */
-               node->left = node->right = NIL;
-               node->level = 1;
-
-               tree->count++;
-               return node;
-       }
-
-       /* recursive insert */
-       cmp = tree->node_cmp(value, current);
-       if (cmp > 0)
-               current->right = insert_sub(tree, current->right, value, node);
-       else if (cmp < 0)
-               current->left = insert_sub(tree, current->left, value, node);
-       else
-               /* already exists? */
-               return current;
-
-       return rebalance_on_insert(current);
-}
-
-void tree_insert(Tree *tree, long value, Node *node)
-{
-       tree->root = insert_sub(tree, tree->root, value, node);
-}
-
-/*
- * Recursive removal
- */
-
-/* remove_sub could be used for that, but want to avoid comparisions */
-static Node *steal_leftmost(Tree *tree, Node *current, Node **save_p)
-{
-       if (current->left == NIL) {
-               *save_p = current;
-               return current->right;
-       }
-
-       current->left = steal_leftmost(tree, current->left, save_p);
-       return rebalance_on_remove(current);
-}
-
-/* drop this node from tree */
-static Node *drop_this_node(Tree *tree, Node *old)
-{
-       Node *new = NIL;
-
-       if (old->left == NIL)
-               new = old->right;
-       else if (old->right == NIL)
-               new = old->left;
-       else {
-               /*
-                * Picking nearest from right is better than from left,
-                * due to asymmetry of the AA-tree.  It will result in
-                * less tree operations in the long run,
-                */
-               old->right = steal_leftmost(tree, old->right, &new);
-
-               /* take old node's place */
-               *new = *old;
-       }
-
-       /* cleanup for old node */
-       tree->release_cb(old, tree);
-       tree->count--;
-
-       return new;
-}
-
-static Node *remove_sub(Tree *tree, Node *current, long value)
-{
-       int cmp;
-
-       /* not found? */
-       if (current == NIL)
-               return current;
-
-       cmp = tree->node_cmp(value, current);
-       if (cmp > 0)
-               current->right = remove_sub(tree, current->right, value);
-       else if (cmp < 0)
-               current->left = remove_sub(tree, current->left, value);
-       else
-               current = drop_this_node(tree, current);
-       return rebalance_on_remove(current);
-}
-
-void tree_remove(Tree *tree, long value)
-{
-       tree->root = remove_sub(tree, tree->root, value);
-}
-
-/*
- * Walking all nodes
- */
-
-static void walk_sub(Node *current, enum TreeWalkType wtype,
-                    tree_walker_f walker, void *arg)
-{
-       if (current == NIL)
-               return;
-
-       switch (wtype) {
-       case WALK_IN_ORDER:
-               walk_sub(current->left, wtype, walker, arg);
-               walker(current, arg);
-               walk_sub(current->right, wtype, walker, arg);
-               break;
-       case WALK_POST_ORDER:
-               walk_sub(current->left, wtype, walker, arg);
-               walk_sub(current->right, wtype, walker, arg);
-               walker(current, arg);
-               break;
-       case WALK_PRE_ORDER:
-               walker(current, arg);
-               walk_sub(current->left, wtype, walker, arg);
-               walk_sub(current->right, wtype, walker, arg);
-               break;
-       }
-}
-
-/* walk tree in correct order */
-void tree_walk(Tree *tree, enum TreeWalkType wtype, tree_walker_f walker, void *arg)
-{
-       walk_sub(tree->root, wtype, walker, arg);
-}
-
-/* walk tree in bottom-up order, so that walker can destroy the nodes */
-void tree_destroy(Tree *tree)
-{
-       walk_sub(tree->root, WALK_POST_ORDER, tree->release_cb, tree);
-
-       /* reset tree */
-       tree->root = NIL;
-       tree->count = 0;
-}
-
-/* prepare tree */
-void tree_init(Tree *tree, tree_cmp_f cmpfn, tree_walker_f release_cb)
-{
-       tree->root = NIL;
-       tree->count = 0;
-       tree->node_cmp = cmpfn;
-       tree->release_cb = release_cb;
-}
-
-/*
- * search function
- */
-Node *tree_search(Tree *tree, long value)
-{
-       Node *current = tree->root;
-       while (current != NIL) {
-               int cmp = tree->node_cmp(value, current);
-               if (cmp > 0)
-                       current = current->right;
-               else if (cmp < 0)
-                       current = current->left;
-               else
-                       return current;
-       }
-       return NULL;
-}
-
index 41930ffee0ccaa01b0094fbc23bf54ae5a48ae5b..9eff2ed8e3a2ecef945c554e1f2ec89b8273c2c0 100644 (file)
@@ -27,7 +27,7 @@ STATLIST(user_list);
 STATLIST(database_list);
 STATLIST(pool_list);
 
-Tree user_tree;
+struct AATree user_tree;
 
 /*
  * client and server objects will be pre-allocated
@@ -87,7 +87,7 @@ static void construct_server(void *obj)
 }
 
 /* compare string with PgUser->name, for usage with btree */
-static int user_node_cmp(long userptr, Node *node)
+static int user_node_cmp(long userptr, struct AANode *node)
 {
        const char *name = (const char *)userptr;
        PgUser *user = container_of(node, PgUser, tree_node);
@@ -97,7 +97,7 @@ static int user_node_cmp(long userptr, Node *node)
 /* initialization before config loading */
 void init_objects(void)
 {
-       tree_init(&user_tree, user_node_cmp, NULL);
+       aatree_init(&user_tree, user_node_cmp, NULL);
        user_cache = objcache_create("user_cache", sizeof(PgUser), 0, NULL);
        db_cache = objcache_create("db_cache", sizeof(PgDatabase), 0, NULL);
        pool_cache = objcache_create("pool_cache", sizeof(PgPool), 0, NULL);
@@ -354,7 +354,7 @@ PgUser *add_user(const char *name, const char *passwd)
                safe_strcpy(user->name, name, sizeof(user->name));
                put_in_order(&user->head, &user_list, cmp_user);
 
-               tree_insert(&user_tree, (long)user->name, &user->tree_node);
+               aatree_insert(&user_tree, (long)user->name, &user->tree_node);
        }
        safe_strcpy(user->passwd, passwd, sizeof(user->passwd));
        return user;
@@ -404,9 +404,9 @@ PgDatabase *find_database(const char *name)
 PgUser *find_user(const char *name)
 {
        PgUser *user = NULL;
-       Node *node;
+       struct AANode *node;
 
-       node = tree_search(&user_tree, (long)name);
+       node = aatree_search(&user_tree, (long)name);
        user = node ? container_of(node, PgUser, tree_node) : NULL;
        return user;
 }