diff src/xs_stil.c @ 227:92bad4c7b998

Improved modularization of STIL and song-length database subsystems.
author Matti Hamalainen <ccr@tnsp.org>
date Sun, 19 Dec 2004 16:53:05 +0000
parents df4cb5115322
children 608f31f6c095
line wrap: on
line diff
--- a/src/xs_stil.c	Sun Dec 19 15:25:03 2004 +0000
+++ b/src/xs_stil.c	Sun Dec 19 16:53:05 2004 +0000
@@ -21,34 +21,33 @@
 */
 #include "xs_stil.h"
 #include "xs_support.h"
-#include "xs_config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 
 
-/*
- * Pointer to database in memory
+/* Database handling functions
  */
-static t_xs_stil_node	*xs_stildb = NULL;
-static t_xs_stil_node	**xs_stildbi = NULL;
-static gint		xs_stildbn   = 0;
-
-
-/*
- * Hash-database handling functions
- */
-t_xs_stil_node *xs_stildb_node_new(void)
+static t_xs_stil_node *xs_stildb_node_new(gchar *pcFilename)
 {
  t_xs_stil_node *pResult;
  
  /* Allocate memory for new node */
  pResult = (t_xs_stil_node *) g_malloc0(sizeof(t_xs_stil_node));
+ if (!pResult) return NULL;
+
+ pResult->pcFilename = g_strdup(pcFilename);
+ if (!pResult->pcFilename)
+ 	{
+ 	g_free(pResult);
+ 	return NULL;
+ 	}
+
  return pResult;
 }
 
 
-void xs_stildb_node_free(t_xs_stil_node *pNode)
+static void xs_stildb_node_free(t_xs_stil_node *pNode)
 {
  gint i;
  
@@ -68,34 +67,30 @@
 }
 
 
-/*
- * Insert given node to db linked list
+/* Insert given node to db linked list
  */
-#define LPREV	(pNode->pPrev)
-#define LTHIS	(pNode)
-#define LNEXT	(pNode->pNext)
-
-void xs_stildb_node_insert(t_xs_stil_node *pNode)
+static void xs_stildb_node_insert(t_xs_stildb *db, t_xs_stil_node *pNode)
 {
- if (xs_stildb)
+ assert(db);
+ 
+ if (db->pNodes)
  	{
  	/* The first node's pPrev points to last node */
-	LPREV = xs_stildb->pPrev;		/* New node's prev = Previous last node */
-	xs_stildb->pPrev->pNext = pNode;	/* Previous last node's next = New node */
-	xs_stildb->pPrev = pNode;		/* New last node = New node */
+	LPREV = db->pNodes->pPrev;		/* New node's prev = Previous last node */
+	db->pNodes->pPrev->pNext = pNode;	/* Previous last node's next = New node */
+	db->pNodes->pPrev = pNode;		/* New last node = New node */
 	LNEXT = NULL;				/* But next is NULL! */
  	} else {
- 	xs_stildb = pNode;			/* First node ... */
+ 	db->pNodes = pNode;			/* First node ... */
  	LPREV = pNode;				/* ... it's also last */
  	LNEXT = NULL;				/* But next is NULL! */
  	}
 }
 
 
-/*
- * Read database to memory
+/* Read database (additively) to given db-structure
  */
-gint xs_stildb_read(gchar *dbFilename)
+gint xs_stildb_read(t_xs_stildb *db, gchar *dbFilename)
 {
  FILE *inFile;
  gchar inLine[XS_BUFSIZE + 10];
@@ -103,6 +98,7 @@
  t_xs_stil_node *tmpNode;
  gboolean isError;
  gint subEntry;
+ assert(db);
  
  /* Try to open the file */
  if ((inFile = fopen(dbFilename, "ra")) == NULL)
@@ -137,13 +133,9 @@
  		}
  
  	/* A new node */
- 	tmpNode = xs_stildb_node_new();
- 	if (tmpNode)
- 		{
- 		/* Initialize the node */
- 		tmpNode->pcFilename = g_strdup(inLine);
-	 	subEntry = 0;
-	 	} else
+ 	subEntry = 0;
+ 	tmpNode = xs_stildb_node_new(inLine);
+ 	if (!tmpNode)
  		{
  		/* Allocation failed */
  		XSERR("Could not allocate new STILdb-node for '%s'!\n", inLine);
@@ -182,7 +174,7 @@
  	if (tmpNode)
  		{
  		/* Insert to database */
- 		xs_stildb_node_insert(tmpNode);
+ 		xs_stildb_node_insert(db, tmpNode);
 		tmpNode = NULL;
 		}
  	break;
@@ -230,18 +222,18 @@
 
  /* Check if there is one remaining node */
  if (tmpNode)
-	xs_stildb_node_free(tmpNode);
+	xs_stildb_node_insert(db, tmpNode);
 
  /* Close the file */  
  fclose(inFile);
+
  return 0;
 }
 
 
-/*
- * Compare two nodes' hashes
+/* Compare two nodes
  */
-gint xs_stildb_cmp(const void *pNode1, const void *pNode2)
+static gint xs_stildb_cmp(const void *pNode1, const void *pNode2)
 {
  /* We assume here that we never ever get NULL-pointers or similar */
  return strcmp((*(t_xs_stil_node **) pNode1)->pcFilename,
@@ -249,70 +241,62 @@
 }
 
 
-/*
- * Initialize the song-length system
+/* (Re)create index
  */
-gint xs_stil_init(void)
+gint xs_stildb_index(t_xs_stildb *db)
 {
  t_xs_stil_node *pCurr;
  gint i;
 
-XSDEBUG("stil_init()\n");
+ /* Free old index */
+ if (db->ppIndex)
+ 	{
+ 	g_free(db->ppIndex);
+ 	db->ppIndex = NULL;
+ 	}
  
- /* Read the database */
- if (!xs_cfg.stilDBPath)
- 	return -10;
-
- if (xs_stildb_read(xs_cfg.stilDBPath) < 0)
- 	return -9;
-
-XSDEBUG("indexing...\n");
-
  /* Get size of db */
- pCurr = xs_stildb;
- xs_stildbn = 0;
+ pCurr = db->pNodes;
+ db->n = 0;
  while (pCurr)
  	{
- 	xs_stildbn++;
+ 	db->n++;
  	pCurr = pCurr->pNext;
  	}
 
  /* Check number of nodes */
- if (xs_stildbn > 0)
+ if (db->n > 0)
 	{
 	/* Allocate memory for index-table */
-	xs_stildbi = (t_xs_stil_node **) g_malloc(sizeof(t_xs_stil_node *) * xs_stildbn);
-	if (!xs_stildbi) return -6;
+	db->ppIndex = (t_xs_stil_node **) g_malloc(sizeof(t_xs_stil_node *) * db->n);
+	if (!db->ppIndex) return -1;
 
 	/* Get node-pointers to table */
 	i = 0;
-	pCurr = xs_stildb;
-	while (pCurr)
+	pCurr = db->pNodes;
+	while (pCurr && (i < db->n))
 		{
-		xs_stildbi[i++] = pCurr;
+		db->ppIndex[i++] = pCurr;
 		pCurr = pCurr->pNext;
 		}
 
 	/* Sort the indexes */
-	qsort(xs_stildbi, xs_stildbn, sizeof(t_xs_stil_node *), xs_stildb_cmp);
+	qsort(db->ppIndex, db->n, sizeof(t_xs_stil_node *), xs_stildb_cmp);
 	}
 
- /* OK */
-XSDEBUG("init ok.\n");
  return 0;
 }
 
-
-/*
- * Close song-length system
+/* Free a given STIL database
  */
-void xs_stil_close(void)
+void xs_stildb_free(t_xs_stildb *db)
 {
  t_xs_stil_node *pCurr, *pNext;
  
- /* Free the memory allocated for database */
-XSDEBUG("stildb_close()\n");
- pCurr = xs_stildb;
+ if (!db) return;
+ 
+ /* Free the memory allocated for nodes */
+ pCurr = db->pNodes;
  while (pCurr)
  	{
  	pNext = pCurr->pNext;
@@ -320,56 +304,43 @@
  	pCurr = pNext;
  	}
 
- xs_stildb = NULL;
+ db->pNodes = NULL;
  
- /* Free memory allocated for indexes */
- if (xs_stildbi)
+ /* Free memory allocated for index */
+ if (db->ppIndex)
  	{
- 	g_free(xs_stildbi);
- 	xs_stildbi = NULL;
+ 	g_free(db->ppIndex);
+ 	db->ppIndex = NULL;
  	}
+
+ /* Free structure */
+ db->n = 0;
+ g_free(db);
 }
 
 
-/*
- * Get STIL information from database
+/* Get STIL information node from database
  */
-t_xs_stil_node * xs_stil_get(gchar *pcFilename)
+static t_xs_stil_node * xs_stildb_get_node(t_xs_stildb *db, gchar *pcFilename)
 {
  gint iStartNode, iEndNode, iQNode, r, i;
- gchar *tmpFilename;
  gboolean iFound;
  t_xs_stil_node *pResult;
 
  /* Check the database pointers */
- if (!xs_stildb || !xs_stildbi || !xs_cfg.stilDBEnable || !xs_cfg.hvscPath)
+ if (!db || !db->pNodes || !db->ppIndex)
  	return NULL;
  
- /* Remove postfixed directory separator from HVSC-path */
- tmpFilename = strrchr(xs_cfg.hvscPath, '/');
- if (tmpFilename && (tmpFilename[1] == 0))
-	tmpFilename[0] = 0;
- 
- /* Remove HVSC location-prefix from filename */
- tmpFilename = strstr(pcFilename, xs_cfg.hvscPath);
- if (tmpFilename)
- 	{
-	tmpFilename += strlen(xs_cfg.hvscPath);
-	} else
-	tmpFilename = pcFilename; 
-
- XSDEBUG("'%s', '%s'\n", xs_cfg.hvscPath, tmpFilename);
- 	
  /* Look-up via index using binary search */
  pResult = NULL;
  iStartNode = 0;
- iEndNode = (xs_stildbn - 1);
+ iEndNode = (db->n - 1);
  iQNode = (iEndNode / 2);
  iFound = FALSE;
 
  while ((!iFound) && ((iEndNode - iStartNode) > 128))
  	{
- 	r = strcmp(tmpFilename, xs_stildbi[iQNode]->pcFilename);
+ 	r = strcmp(pcFilename, db->ppIndex[iQNode]->pcFilename);
  	if (r < 0)
  		{
  		/* Hash was in the <- LEFT side */
@@ -393,7 +364,7 @@
 	i = iStartNode;
 	while ((i <= iEndNode) && (!iFound))
 		{
-		if (strcmp(tmpFilename, xs_stildbi[i]->pcFilename) == 0)
+		if (strcmp(pcFilename, db->ppIndex[i]->pcFilename) == 0)
 			iFound = TRUE;
 			else
 			i++;
@@ -401,13 +372,35 @@
 	
 	/* Check the result */
 	if (iFound)
-		pResult = xs_stildbi[i];
+		pResult = db->ppIndex[i];
 
  	} else {
 	/* Found via binary search */
- 	pResult = xs_stildbi[iQNode];
+ 	pResult = db->ppIndex[iQNode];
 	}
 
  return pResult;
 }
 
+
+/* Get from STIL database
+ */
+t_xs_stil_node * xs_stildb_get(t_xs_stildb *db, gchar *hvscPath, gchar *pcFilename)
+{
+ gchar *tmpFilename;
+
+ /* Remove postfixed directory separator from HVSC-path */
+ tmpFilename = xs_strrchr(hvscPath, '/');
+ if (tmpFilename && (tmpFilename[1] == 0))
+	tmpFilename[0] = 0;
+ 
+ /* Remove HVSC location-prefix from filename */
+ tmpFilename = strstr(pcFilename, hvscPath);
+ if (tmpFilename)
+	tmpFilename += strlen(hvscPath);
+	else
+	tmpFilename = pcFilename; 
+
+ return xs_stildb_get_node(db, pcFilename);
+}
+