graph3.c revision 1.1
11.1Sjoerg/* $NetBSD: graph3.c,v 1.1 2009/08/15 16:21:05 joerg Exp $ */ 21.1Sjoerg/*- 31.1Sjoerg * Copyright (c) 2009 The NetBSD Foundation, Inc. 41.1Sjoerg * All rights reserved. 51.1Sjoerg * 61.1Sjoerg * This code is derived from software contributed to The NetBSD Foundation 71.1Sjoerg * by Joerg Sonnenberger. 81.1Sjoerg * 91.1Sjoerg * Redistribution and use in source and binary forms, with or without 101.1Sjoerg * modification, are permitted provided that the following conditions 111.1Sjoerg * are met: 121.1Sjoerg * 131.1Sjoerg * 1. Redistributions of source code must retain the above copyright 141.1Sjoerg * notice, this list of conditions and the following disclaimer. 151.1Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 161.1Sjoerg * notice, this list of conditions and the following disclaimer in 171.1Sjoerg * the documentation and/or other materials provided with the 181.1Sjoerg * distribution. 191.1Sjoerg * 201.1Sjoerg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 211.1Sjoerg * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 221.1Sjoerg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 231.1Sjoerg * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 241.1Sjoerg * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 251.1Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 261.1Sjoerg * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 271.1Sjoerg * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 281.1Sjoerg * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 291.1Sjoerg * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 301.1Sjoerg * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311.1Sjoerg * SUCH DAMAGE. 321.1Sjoerg */ 331.1Sjoerg 341.1Sjoerg#include <sys/cdefs.h> 351.1Sjoerg__RCSID("$NetBSD: graph3.c,v 1.1 2009/08/15 16:21:05 joerg Exp $"); 361.1Sjoerg 371.1Sjoerg#include <err.h> 381.1Sjoerg#include <inttypes.h> 391.1Sjoerg#include <stdio.h> 401.1Sjoerg#include <stdlib.h> 411.1Sjoerg 421.1Sjoerg#include "nbperf.h" 431.1Sjoerg#include "graph3.h" 441.1Sjoerg 451.1Sjoergstatic const uint32_t unused = 0xffffffffU; 461.1Sjoerg 471.1Sjoergvoid 481.1Sjoerggraph3_setup(struct graph3 *graph, uint32_t v, uint32_t e) 491.1Sjoerg{ 501.1Sjoerg graph->v = v; 511.1Sjoerg graph->e = e; 521.1Sjoerg 531.1Sjoerg graph->verts = calloc(sizeof(struct vertex3), v); 541.1Sjoerg graph->edges = calloc(sizeof(struct edge3), e); 551.1Sjoerg graph->output_order = calloc(sizeof(uint32_t), e); 561.1Sjoerg 571.1Sjoerg if (graph->verts == NULL || graph->edges == NULL || 581.1Sjoerg graph->output_order == NULL) 591.1Sjoerg err(1, "malloc failed"); 601.1Sjoerg} 611.1Sjoerg 621.1Sjoergvoid 631.1Sjoerggraph3_free(struct graph3 *graph) 641.1Sjoerg{ 651.1Sjoerg free(graph->verts); 661.1Sjoerg free(graph->edges); 671.1Sjoerg free(graph->output_order); 681.1Sjoerg 691.1Sjoerg graph->verts = NULL; 701.1Sjoerg graph->edges = NULL; 711.1Sjoerg graph->output_order = NULL; 721.1Sjoerg} 731.1Sjoerg 741.1Sjoergint 751.1Sjoerggraph3_hash(struct nbperf *nbperf, struct graph3 *graph) 761.1Sjoerg{ 771.1Sjoerg struct vertex3 *v; 781.1Sjoerg uint32_t hashes[nbperf->hash_size]; 791.1Sjoerg size_t i; 801.1Sjoerg 811.1Sjoerg for (i = 0; i < graph->e; ++i) { 821.1Sjoerg (*nbperf->compute_hash)(nbperf, 831.1Sjoerg nbperf->keys[i], nbperf->keylens[i], hashes); 841.1Sjoerg graph->edges[i].left = hashes[0] % graph->v; 851.1Sjoerg graph->edges[i].middle = hashes[1] % graph->v; 861.1Sjoerg graph->edges[i].right = hashes[2] % graph->v; 871.1Sjoerg if (graph->edges[i].left == graph->edges[i].middle) 881.1Sjoerg return -1; 891.1Sjoerg if (graph->edges[i].left == graph->edges[i].right) 901.1Sjoerg return -1; 911.1Sjoerg if (graph->edges[i].middle == graph->edges[i].right) 921.1Sjoerg return -1; 931.1Sjoerg } 941.1Sjoerg 951.1Sjoerg for (i = 0; i < graph->v; ++i) { 961.1Sjoerg graph->verts[i].l_edge = unused; 971.1Sjoerg graph->verts[i].m_edge = unused; 981.1Sjoerg graph->verts[i].r_edge = unused; 991.1Sjoerg } 1001.1Sjoerg 1011.1Sjoerg for (i = 0; i < graph->e; ++i) { 1021.1Sjoerg v = &graph->verts[graph->edges[i].left]; 1031.1Sjoerg if (v->l_edge != unused) 1041.1Sjoerg graph->edges[v->l_edge].l_prev = i; 1051.1Sjoerg graph->edges[i].l_next = v->l_edge; 1061.1Sjoerg graph->edges[i].l_prev = unused; 1071.1Sjoerg v->l_edge = i; 1081.1Sjoerg 1091.1Sjoerg v = &graph->verts[graph->edges[i].middle]; 1101.1Sjoerg if (v->m_edge != unused) 1111.1Sjoerg graph->edges[v->m_edge].m_prev = i; 1121.1Sjoerg graph->edges[i].m_next = v->m_edge; 1131.1Sjoerg graph->edges[i].m_prev = unused; 1141.1Sjoerg v->m_edge = i; 1151.1Sjoerg 1161.1Sjoerg v = &graph->verts[graph->edges[i].right]; 1171.1Sjoerg if (v->r_edge != unused) 1181.1Sjoerg graph->edges[v->r_edge].r_prev = i; 1191.1Sjoerg graph->edges[i].r_next = v->r_edge; 1201.1Sjoerg graph->edges[i].r_prev = unused; 1211.1Sjoerg v->r_edge = i; 1221.1Sjoerg } 1231.1Sjoerg 1241.1Sjoerg return 0; 1251.1Sjoerg} 1261.1Sjoerg 1271.1Sjoergstatic void 1281.1Sjoerggraph3_remove_vertex(struct graph3 *graph, struct vertex3 *v) 1291.1Sjoerg{ 1301.1Sjoerg struct edge3 *e; 1311.1Sjoerg struct vertex3 *vl, *vm, *vr; 1321.1Sjoerg 1331.1Sjoerg if (v->l_edge != unused && v->m_edge != unused) 1341.1Sjoerg return; 1351.1Sjoerg if (v->l_edge != unused && v->r_edge != unused) 1361.1Sjoerg return; 1371.1Sjoerg if (v->m_edge != unused && v->r_edge != unused) 1381.1Sjoerg return; 1391.1Sjoerg if (v->l_edge == unused && v->m_edge == unused && v->r_edge == unused) 1401.1Sjoerg return; 1411.1Sjoerg 1421.1Sjoerg if (v->l_edge != unused) { 1431.1Sjoerg e = &graph->edges[v->l_edge]; 1441.1Sjoerg if (e->l_next != unused) 1451.1Sjoerg return; 1461.1Sjoerg } else if (v->m_edge != unused) { 1471.1Sjoerg e = &graph->edges[v->m_edge]; 1481.1Sjoerg if (e->m_next != unused) 1491.1Sjoerg return; 1501.1Sjoerg } else { 1511.1Sjoerg if (v->r_edge == unused) 1521.1Sjoerg abort(); 1531.1Sjoerg e = &graph->edges[v->r_edge]; 1541.1Sjoerg if (e->r_next != unused) 1551.1Sjoerg return; 1561.1Sjoerg } 1571.1Sjoerg 1581.1Sjoerg graph->output_order[--graph->output_index] = e - graph->edges; 1591.1Sjoerg 1601.1Sjoerg vl = &graph->verts[e->left]; 1611.1Sjoerg vm = &graph->verts[e->middle]; 1621.1Sjoerg vr = &graph->verts[e->right]; 1631.1Sjoerg 1641.1Sjoerg if (e->l_prev == unused) 1651.1Sjoerg vl->l_edge = e->l_next; 1661.1Sjoerg else 1671.1Sjoerg graph->edges[e->l_prev].l_next = e->l_next; 1681.1Sjoerg if (e->l_next != unused) 1691.1Sjoerg graph->edges[e->l_next].l_prev = e->l_prev; 1701.1Sjoerg 1711.1Sjoerg if (e->m_prev == unused) 1721.1Sjoerg vm->m_edge = e->m_next; 1731.1Sjoerg else 1741.1Sjoerg graph->edges[e->m_prev].m_next = e->m_next; 1751.1Sjoerg if (e->m_next != unused) 1761.1Sjoerg graph->edges[e->m_next].m_prev = e->m_prev; 1771.1Sjoerg 1781.1Sjoerg if (e->r_prev == unused) 1791.1Sjoerg vr->r_edge = e->r_next; 1801.1Sjoerg else 1811.1Sjoerg graph->edges[e->r_prev].r_next = e->r_next; 1821.1Sjoerg if (e->r_next != unused) 1831.1Sjoerg graph->edges[e->r_next].r_prev = e->r_prev; 1841.1Sjoerg} 1851.1Sjoerg 1861.1Sjoergint 1871.1Sjoerggraph3_output_order(struct graph3 *graph) 1881.1Sjoerg{ 1891.1Sjoerg struct edge3 *e; 1901.1Sjoerg size_t i; 1911.1Sjoerg 1921.1Sjoerg graph->output_index = graph->e; 1931.1Sjoerg 1941.1Sjoerg for (i = 0; i < graph->v; ++i) 1951.1Sjoerg graph3_remove_vertex(graph, &graph->verts[i]); 1961.1Sjoerg 1971.1Sjoerg for (i = graph->e; i > 0 && i > graph->output_index;) { 1981.1Sjoerg --i; 1991.1Sjoerg e = &graph->edges[graph->output_order[i]]; 2001.1Sjoerg 2011.1Sjoerg graph3_remove_vertex(graph, &graph->verts[e->left]); 2021.1Sjoerg graph3_remove_vertex(graph, &graph->verts[e->middle]); 2031.1Sjoerg graph3_remove_vertex(graph, &graph->verts[e->right]); 2041.1Sjoerg } 2051.1Sjoerg 2061.1Sjoerg if (graph->output_index != 0) 2071.1Sjoerg return -1; 2081.1Sjoerg 2091.1Sjoerg return 0; 2101.1Sjoerg} 211