root/platform/mysql/top-n-sort/top-n-sort.c @ 26567

Revision 26567, 3.0 kB (checked in by kazuho, 5 years ago)

does not work yet

Line 
1#include <mysql.h>
2#include <assert.h>
3#include <fcntl.h>
4#include <pthread.h>
5#include <stdio.h>
6#include <stdint.h>
7#include <string.h>
8#include <sys/mman.h>
9#include <sys/stat.h>
10#include <unistd.h>
11
12#ifndef MAX_ITEMS
13# define MAX_ITEMS 200
14#endif
15
16extern void _init(void) __attribute__ ((constructor));
17extern void _fini(void) __attribute__ ((destructor));
18
19extern my_bool topn_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
20extern my_bool topn_set_deinit(UDF_INIT *initid);
21extern long long topn_set(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
22                          char *error);
23extern my_bool topn_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message);
24extern my_bool topn_get_deinit(UDF_INIT *initid);
25extern long long topn_get(UDF_INIT *initid, UDF_ARGS *args, char *is_null,
26                          char *error);
27
28typedef struct _topn_item {
29  long long id;
30  long long value;
31} topn_item;
32
33typedef struct _topn_info {
34  size_t refcnt;
35  size_t count;
36  topn_item items[MAX_ITEMS];
37} topn_info;
38
39static pthread_key pkey_;
40
41void _init(void)
42{
43  pthread_key_create(&pkey_, NULL);
44}
45
46void _fini(void)
47{
48  pthread_key_delete(&pkey_);
49}
50
51__inline topn_info *get_info(void)
52{
53  return pthread_getspecific(pkey_);
54}
55
56static topn_info *acquire_info(void)
57{
58  topn_info *info;
59 
60  if ((info = get_info()) != NULL) {
61    info->refcnt++;
62    return info;
63  }
64 
65  if ((info = malloc(sizeof(*info))) == NULL) {
66    return NULL;
67  }
68 
69  info->refcnt = 1;
70  info->count = 0;
71  pthread_setspecific(pkey_, info);
72  return info;
73}
74
75static void release_info(topn_info *info)
76{
77  if (--info->refcnt == 0) {
78    free(info);
79    pthread_setspecific(pkey_, NULL);
80  }
81}
82
83#define SETUP_ARG(i, t, n)   \
84  do {                       \
85    args->arg_type[i] = t;   \
86    args->maybe_null[i] = n; \
87  } while (0)
88
89my_bool topn_set_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
90{
91  if (args->arg_count != 3) {
92    strcpy(message, "topn_set_init(max_items,id,value): invalid arguments");
93    return 1;
94  }
95  if ((initid->ptr = acquire_info()) == NULL) {
96    strcpy(message, "no memory");
97    return 1;
98  }
99 
100  initid->maybe_null = 0;
101  SETUP_ARG(0, INT_RESULT, 0);
102  SETUP_ARG(1, INT_RESULT, 0);
103  SETUP_ARG(2, INT_RESULT, 0);
104  return 0;
105}
106
107my_bool topn_set_deinit(UDF_INIT *initid)
108{
109  release_info(initid->ptr);
110  return 0;
111}
112
113long long topn_set(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
114{
115  // TODO
116  return 0;
117}
118
119my_bool topn_get_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
120{
121  if (args->arg_count != 1) {
122    strcpy(message, "topn_get(index): invalid arguments");
123    return 1;
124  }
125  if ((initid->ptr = acquire_info()) == NULL) {
126    strcpy(message, "no memory");
127    return 1;
128  }
129 
130  initid->maybe_null = 0;
131  SETUP_ARG(0, INT_RESULT, 0);
132  return 0;
133}
134
135my_bool topn_get_deinit(UDF_INIT *initid)
136{
137  release_info(initid->ptr);
138}
139
140long long topn_get(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
141{
142  topn_info *info = initid->ptr;
143  size_t idx = (size_t)*(long long*)args->args[0];
144 
145  return idx < info->count ? info->items[idx].id : 0;
146}
Note: See TracBrowser for help on using the browser.