IndexSorter.c

Go to the documentation of this file.
00001 /**
00002  *  IndexSorter.c
00003  *  
00004  * @file IndexSorter.c
00005  * 
00006  * Part of the CCNx C Library.
00007  *
00008  * Copyright (C) 2011 Palo Alto Research Center, Inc.
00009  *
00010  * This library is free software; you can redistribute it and/or modify it
00011  * under the terms of the GNU Lesser General Public License version 2.1
00012  * as published by the Free Software Foundation.
00013  * This library is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * Lesser General Public License for more details. You should have received
00017  * a copy of the GNU Lesser General Public License along with this library;
00018  * if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
00019  * Fifth Floor, Boston, MA 02110-1301 USA.
00020  */
00021 
00022 #include <stdlib.h>
00023 #include <string.h>
00024 #include "IndexSorter.h"
00025 
00026 extern IndexSorter_Base
00027 IndexSorter_New(IndexSorter_Index lim, IndexSorter_Index empty) {
00028     IndexSorter_Base base = calloc(1, sizeof(struct IndexSorter_Struct));
00029     if (lim < 4) lim = 4;
00030     base->indexes = calloc(lim, sizeof(IndexSorter_Index));
00031     base->lim = lim;
00032     base->empty = empty;
00033     return base;
00034 }
00035 
00036 extern void
00037 IndexSorter_Add(IndexSorter_Base base, IndexSorter_Index x) {
00038     if (base->sorter == NULL) return;
00039     IndexSorter_Index len = base->len;
00040     IndexSorter_Index *vec = base->indexes;
00041     if (len >= base->lim) {
00042         // need to expand 
00043         IndexSorter_Index nLim = len + len/2 + 4;
00044         IndexSorter_Index *old = vec;
00045         vec = calloc(nLim, sizeof(IndexSorter_Index));
00046         base->indexes = vec;
00047         if (len > 0) memcpy(vec, old, len*sizeof(IndexSorter_Index));
00048         free(old);
00049         base->lim = nLim;
00050     }
00051     IndexSorter_Index son = len;
00052     if (base->sorter != NULL) {
00053         while (son > 0) {
00054             IndexSorter_Index dad = (son-1) / 2;
00055             IndexSorter_Index dx = vec[dad];
00056             if (base->sorter(base, dx, x) <= 0) break;
00057             vec[son] = dx;
00058             son = dad;
00059         }
00060     }
00061     vec[son] = x;
00062     base->len = len+1;
00063 }
00064 
00065 extern IndexSorter_Index
00066 IndexSorter_Rem(IndexSorter_Base base) {
00067     IndexSorter_Index len = base->len;
00068     IndexSorter_Index ret = base->empty;
00069     if (len > 0) {
00070         IndexSorter_Index *vec = base->indexes;
00071         if (base->sorter != NULL) {
00072             // sorter present
00073             len = len - 1;
00074             ret = vec[0];
00075             IndexSorter_Index dad = 0;
00076             IndexSorter_Index dx = vec[len];
00077             for (;;) {
00078                 IndexSorter_Index son = dad+dad+1;
00079                 if (son >= len) break;
00080                 IndexSorter_Index sx = vec[son];
00081                 IndexSorter_Index nson = son+1;
00082                 if (nson < len) {
00083                     IndexSorter_Index sy = vec[nson];
00084                     if (base->sorter(base, sx, sy) > 0) {
00085                         sx = sy;
00086                         son = nson;
00087                     }
00088                 }
00089                 if (base->sorter(base, dx, sx) <= 0) break;
00090                 vec[dad] = sx;
00091                 dad = son;
00092             }
00093             vec[dad] = dx;
00094         } else {
00095             // no sorter, so just pop it
00096             len = len - 1;
00097             ret = vec[len];
00098         }
00099         base->len = len;
00100     }
00101     return ret;
00102 }
00103 
00104 extern IndexSorter_Index
00105 IndexSorter_Best(IndexSorter_Base base) {
00106     if (base->len > 0) return base->indexes[0];
00107     return base->empty;
00108 }
00109 
00110 extern void
00111 IndexSorter_Reset(IndexSorter_Base base) {
00112     base->len = 0;
00113 }
00114 
00115 extern void
00116 IndexSorter_Free(IndexSorter_Base *basePtr) {
00117     if (basePtr != NULL) {
00118         IndexSorter_Base base = *basePtr;
00119         if (base != NULL) {
00120             void *indexes = base->indexes;
00121             if (indexes != NULL) free(indexes);
00122             free(base);
00123         }
00124     }
00125 }
00126 

Generated on Thu Feb 16 00:44:01 2012 for Content-Centric Networking in C by  doxygen 1.5.6