mirror of
https://github.com/owntone/owntone-server.git
synced 2025-01-13 16:03:23 -05:00
Replace AVL tree in DAAP query by a static hash using gperf
This commit is contained in:
parent
fc90acbc17
commit
303a3329eb
2
src/.gitignore
vendored
2
src/.gitignore
vendored
@ -7,3 +7,5 @@ DAAP2SQL.[ch]
|
||||
RSP2SQL.[ch]
|
||||
|
||||
*.u
|
||||
|
||||
daap_query_hash.c
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org>
|
||||
* Copyright (C) 2009-2011 Julien BLACHE <jb@jblache.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -94,7 +94,7 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||
pANTLR3_UINT8 escaped;
|
||||
ANTLR3_UINT8 op;
|
||||
int neg_op;
|
||||
struct dmap_query_field_map *dqfm;
|
||||
const struct dmap_query_field_map *dqfm;
|
||||
char *end;
|
||||
long long llval;
|
||||
|
||||
@ -162,7 +162,7 @@ expr returns [ pANTLR3_STRING result, int valid ]
|
||||
neg_op = 0;
|
||||
|
||||
/* Lookup DMAP field in the query field map */
|
||||
dqfm = daap_query_field_lookup((char *)field);
|
||||
dqfm = daap_query_field_lookup((char *)field, strlen((char *)field));
|
||||
if (!dqfm)
|
||||
{
|
||||
DPRINTF(E_LOG, L_DAAP, "DMAP field '\%s' is not a valid field in queries\n", field);
|
||||
|
@ -21,9 +21,11 @@ if COND_OSS4
|
||||
OSS4SRC=laudio_oss4.c
|
||||
endif
|
||||
|
||||
GPERF_FILES =
|
||||
GPERF_FILES = \
|
||||
daap_query.gperf
|
||||
|
||||
GPERF_PRODUCTS =
|
||||
GPERF_PRODUCTS = \
|
||||
daap_query_hash.c
|
||||
|
||||
ANTLR_GRAMMARS = \
|
||||
RSP.g RSP2SQL.g \
|
||||
|
124
src/daap_query.c
124
src/daap_query.c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org>
|
||||
* Copyright (C) 2009-2011 Julien BLACHE <jb@jblache.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -25,8 +25,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <avl.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "misc.h"
|
||||
#include "daap_query.h"
|
||||
@ -36,72 +34,9 @@
|
||||
#include "DAAP2SQL.h"
|
||||
|
||||
|
||||
static struct dmap_query_field_map dmap_query_fields[] =
|
||||
{
|
||||
{ 0, 0, "dmap.itemname", "title" },
|
||||
{ 0, 1, "dmap.itemid", "id" },
|
||||
{ 0, 0, "daap.songalbum", "album" },
|
||||
{ 0, 1, "daap.songalbumid", "songalbumid" },
|
||||
{ 0, 0, "daap.songartist", "artist" },
|
||||
{ 0, 0, "daap.songalbumartist", "album_artist" },
|
||||
{ 0, 1, "daap.songbitrate", "bitrate" },
|
||||
{ 0, 0, "daap.songcomment", "comment" },
|
||||
{ 0, 1, "daap.songcompilation", "compilation" },
|
||||
{ 0, 0, "daap.songcomposer", "composer" },
|
||||
{ 0, 1, "daap.songdatakind", "data_kind" },
|
||||
{ 0, 0, "daap.songdataurl", "url" },
|
||||
{ 0, 1, "daap.songdateadded", "time_added" },
|
||||
{ 0, 1, "daap.songdatemodified", "time_modified" },
|
||||
{ 0, 0, "daap.songdescription", "description" },
|
||||
{ 0, 1, "daap.songdisccount", "total_discs" },
|
||||
{ 0, 1, "daap.songdiscnumber", "disc" },
|
||||
{ 0, 0, "daap.songformat", "type" },
|
||||
{ 0, 0, "daap.songgenre", "genre" },
|
||||
{ 0, 1, "daap.songsamplerate", "samplerate" },
|
||||
{ 0, 1, "daap.songsize", "file_size" },
|
||||
{ 0, 1, "daap.songstoptime", "song_length" },
|
||||
{ 0, 1, "daap.songtime", "song_length" },
|
||||
{ 0, 1, "daap.songtrackcount", "total_tracks" },
|
||||
{ 0, 1, "daap.songtracknumber", "track" },
|
||||
{ 0, 1, "daap.songyear", "year" },
|
||||
{ 0, 1, "com.apple.itunes.mediakind", "media_kind" },
|
||||
/* gperf static hash, daap_query.gperf */
|
||||
#include "daap_query_hash.c"
|
||||
|
||||
{ -1, -1, NULL, NULL }
|
||||
};
|
||||
|
||||
static avl_tree_t *dmap_query_fields_hash;
|
||||
|
||||
|
||||
static int
|
||||
dmap_query_field_map_compare(const void *aa, const void *bb)
|
||||
{
|
||||
struct dmap_query_field_map *a = (struct dmap_query_field_map *)aa;
|
||||
struct dmap_query_field_map *b = (struct dmap_query_field_map *)bb;
|
||||
|
||||
if (a->hash < b->hash)
|
||||
return -1;
|
||||
|
||||
if (a->hash > b->hash)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct dmap_query_field_map *
|
||||
daap_query_field_lookup(char *field)
|
||||
{
|
||||
struct dmap_query_field_map dqfm;
|
||||
avl_node_t *node;
|
||||
|
||||
dqfm.hash = djb_hash(field, strlen(field));
|
||||
|
||||
node = avl_search(dmap_query_fields_hash, &dqfm);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
return (struct dmap_query_field_map *)node->item;
|
||||
}
|
||||
|
||||
char *
|
||||
daap_query_parse_sql(const char *daap_query)
|
||||
@ -214,56 +149,3 @@ daap_query_parse_sql(const char *daap_query)
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
daap_query_init(void)
|
||||
{
|
||||
avl_node_t *node;
|
||||
struct dmap_query_field_map *dqfm;
|
||||
int i;
|
||||
|
||||
dmap_query_fields_hash = avl_alloc_tree(dmap_query_field_map_compare, NULL);
|
||||
if (!dmap_query_fields_hash)
|
||||
{
|
||||
DPRINTF(E_FATAL, L_DAAP, "DAAP query init could not allocate AVL tree\n");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; dmap_query_fields[i].hash == 0; i++)
|
||||
{
|
||||
dmap_query_fields[i].hash = djb_hash(dmap_query_fields[i].dmap_field, strlen(dmap_query_fields[i].dmap_field));
|
||||
|
||||
node = avl_insert(dmap_query_fields_hash, &dmap_query_fields[i]);
|
||||
if (!node)
|
||||
{
|
||||
if (errno != EEXIST)
|
||||
DPRINTF(E_FATAL, L_DAAP, "DAAP query init failed; AVL insert error: %s\n", strerror(errno));
|
||||
else
|
||||
{
|
||||
node = avl_search(dmap_query_fields_hash, &dmap_query_fields[i]);
|
||||
dqfm = node->item;
|
||||
|
||||
DPRINTF(E_FATAL, L_DAAP, "DAAP query init failed; WARNING: duplicate hash key\n");
|
||||
DPRINTF(E_FATAL, L_DAAP, "Hash %x, string %s\n", dmap_query_fields[i].hash, dmap_query_fields[i].dmap_field);
|
||||
|
||||
DPRINTF(E_FATAL, L_DAAP, "Hash %x, string %s\n", dqfm->hash, dqfm->dmap_field);
|
||||
}
|
||||
|
||||
goto avl_insert_fail;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
avl_insert_fail:
|
||||
avl_free_tree(dmap_query_fields_hash);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
daap_query_deinit(void)
|
||||
{
|
||||
avl_free_tree(dmap_query_fields_hash);
|
||||
}
|
||||
|
39
src/daap_query.gperf
Normal file
39
src/daap_query.gperf
Normal file
@ -0,0 +1,39 @@
|
||||
%language=ANSI-C
|
||||
%readonly-tables
|
||||
%enum
|
||||
%switch=1
|
||||
%compare-lengths
|
||||
%define hash-function-name daap_query_field_hash
|
||||
%define lookup-function-name daap_query_field_lookup
|
||||
%define slot-name dmap_field
|
||||
%struct-type
|
||||
%omit-struct-type
|
||||
struct dmap_query_field_map;
|
||||
%%
|
||||
"dmap.itemname", "title", 0
|
||||
"dmap.itemid", "id", 1
|
||||
"daap.songalbum", "album", 0
|
||||
"daap.songalbumid", "songalbumid", 1
|
||||
"daap.songartist", "artist", 0
|
||||
"daap.songalbumartist", "album_artist", 0
|
||||
"daap.songbitrate", "bitrate", 1
|
||||
"daap.songcomment", "comment", 0
|
||||
"daap.songcompilation", "compilation", 1
|
||||
"daap.songcomposer", "composer", 0
|
||||
"daap.songdatakind", "data_kind", 1
|
||||
"daap.songdataurl", "url", 0
|
||||
"daap.songdateadded", "time_added", 1
|
||||
"daap.songdatemodified", "time_modified", 1
|
||||
"daap.songdescription", "description", 0
|
||||
"daap.songdisccount", "total_discs", 1
|
||||
"daap.songdiscnumber", "disc", 1
|
||||
"daap.songformat", "type", 0
|
||||
"daap.songgenre", "genre", 0
|
||||
"daap.songsamplerate", "samplerate", 1
|
||||
"daap.songsize", "file_size", 1
|
||||
"daap.songstoptime", "song_length", 1
|
||||
"daap.songtime", "song_length", 1
|
||||
"daap.songtrackcount", "total_tracks", 1
|
||||
"daap.songtracknumber", "track", 1
|
||||
"daap.songyear", "year", 1
|
||||
"com.apple.itunes.mediakind", "media_kind", 1
|
@ -2,29 +2,21 @@
|
||||
#ifndef __DAAP_QUERY_H__
|
||||
#define __DAAP_QUERY_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "misc.h"
|
||||
|
||||
struct dmap_query_field_map {
|
||||
uint32_t hash;
|
||||
int as_int;
|
||||
char *dmap_field;
|
||||
char *db_col;
|
||||
int as_int;
|
||||
};
|
||||
|
||||
|
||||
struct dmap_query_field_map *
|
||||
daap_query_field_lookup(char *field);
|
||||
/* Generated by gperf - keep in sync, don't alter */
|
||||
const struct dmap_query_field_map *
|
||||
daap_query_field_lookup (register const char *str, register unsigned int len);
|
||||
|
||||
char *
|
||||
daap_query_parse_sql(const char *daap_query);
|
||||
|
||||
int
|
||||
daap_query_init(void);
|
||||
|
||||
void
|
||||
daap_query_deinit(void);
|
||||
|
||||
#endif /* !__DAAP_QUERY_H__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2009-2010 Julien BLACHE <jb@jblache.org>
|
||||
* Copyright (C) 2009-2011 Julien BLACHE <jb@jblache.org>
|
||||
* Copyright (C) 2010 Kai Elwert <elwertk@googlemail.com>
|
||||
*
|
||||
* Adapted from mt-daapd:
|
||||
@ -3174,10 +3174,6 @@ daap_init(void)
|
||||
next_session_id = 100; /* gotta start somewhere, right? */
|
||||
update_requests = NULL;
|
||||
|
||||
ret = daap_query_init();
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
for (i = 0; daap_handlers[i].handler; i++)
|
||||
{
|
||||
ret = regcomp(&daap_handlers[i].preg, daap_handlers[i].regexp, REG_EXTENDED | REG_NOSUB);
|
||||
@ -3186,7 +3182,7 @@ daap_init(void)
|
||||
regerror(ret, &daap_handlers[i].preg, buf, sizeof(buf));
|
||||
|
||||
DPRINTF(E_FATAL, L_DAAP, "DAAP init failed; regexp error: %s\n", buf);
|
||||
goto regexp_fail;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3239,8 +3235,6 @@ daap_init(void)
|
||||
daap_avl_alloc_fail:
|
||||
for (i = 0; daap_handlers[i].handler; i++)
|
||||
regfree(&daap_handlers[i].preg);
|
||||
regexp_fail:
|
||||
daap_query_deinit();
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -3251,8 +3245,6 @@ daap_deinit(void)
|
||||
struct daap_update_request *ur;
|
||||
int i;
|
||||
|
||||
daap_query_deinit();
|
||||
|
||||
for (i = 0; daap_handlers[i].handler; i++)
|
||||
regfree(&daap_handlers[i].preg);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user