2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2 of the License, or (at your option) any later version.
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
16 * Copyright (C) 2008 Liam Girdwood
19 #define _GNU_SOURCE /* for strtof and NAN */
28 #include <sys/types.h>
33 #include <libastrodb/db.h>
34 #include <libastrodb/table.h>
35 #include <libastrodb/wget.h>
36 #include <libastrodb/gunzip.h>
37 #include <libastrodb/adbstdio.h>
40 #define FLOAT_SIZE '6' /* CDS F string size and below for float else double */
44 int records
; /*!< Number of records in dataset */
45 int ra
, dec
, mag
; /*!< Stride size */
49 * Table containing default dataset 3d tile dimensions
51 static struct _tile_dim tile_dim
[] = {
55 {1000000, 180, 90, 20},
56 {10000000, 360, 180, 20},
59 /*! \fn static int init_table(astrodb_table * table, int ra_stride, int dec_stride, int mag_stride)
60 * \brief Initialise a dataset
62 static int init_table(struct astrodb_table
*table
,
63 int ra_stride
, int dec_stride
, int mag_stride
)
65 struct astrodb_slist
**slist
, **hash_object
;
66 struct astrodb_tile_status
*status
;
69 /* do we use the default tile dimensions */
71 for (; i
< astrodb_size(tile_dim
); i
++) {
72 if (table
->table_size
<= tile_dim
[i
].records
)
75 table
->ra_stride
= tile_dim
[i
].ra
;
76 table
->dec_stride
= tile_dim
[i
].dec
;
77 table
->mag_stride
= tile_dim
[i
].mag
;
79 table
->ra_stride
= ra_stride
;
80 table
->dec_stride
= dec_stride
;
81 table
->mag_stride
= mag_stride
;
84 table
->array_size
= table
->ra_stride
* table
->dec_stride
*
85 table
->mag_stride
* sizeof(struct astrodb_slist
*);
86 table
->status_size
= table
->ra_stride
* table
->dec_stride
*
87 table
->mag_stride
* sizeof(struct astrodb_tile_status
);
88 table
->no_tiles
= table
->ra_stride
* table
->dec_stride
*
91 table
->ra_stride_size
=
92 fabs((table
->db
->ra_max
- table
->db
->ra_min
) / table
->ra_stride
);
93 table
->dec_stride_size
=
94 fabs((table
->db
->dec_max
- table
->db
->dec_min
) / table
->dec_stride
);
95 table
->mag_stride_size
=
96 fabs((table
->db
->mag_bright
- table
->db
->mag_faint
) / table
->mag_stride
);
98 slist
= (struct astrodb_slist
**) calloc(1, table
->array_size
);
103 table
->objects
= slist
;
105 status
= (struct astrodb_tile_status
*) calloc(1, table
->status_size
);
111 table
->status
= status
;
113 for (i
= 0; i
< table
->num_hmaps
; i
++) {
114 hash_object
= (struct astrodb_slist
**) calloc(1, table
->array_size
);
115 if (hash_object
== NULL
) {
119 free(table
->hmaps
[i
-1].hobjects
);
124 table
->hmaps
[i
].hobjects
= hash_object
;
130 /*! \fn static astrodb_table* create_table(astrodb_db*db, astrodb_dlist* desc, astrodb_dlist* files)
131 * \brief Create a object dataset and populate fields
133 static struct astrodb_table
*create_table(struct astrodb_db
*db
,
134 struct astrodb_dlist
*desc
, struct astrodb_dlist
*files
)
136 struct astrodb_table
*table
;
138 table
= calloc(1, sizeof(struct astrodb_table
));
142 bzero(table
, sizeof(struct astrodb_table
));
143 table
->byte_description
=
144 ((struct astrodb_table_info
*) files
->data
)->byte_description
;
145 table
->file
= ((struct astrodb_table_info
*) files
->data
)->name
;
146 table
->table_size
= ((struct astrodb_table_info
*) files
->data
)->records
;
147 table
->record_size
= ((struct astrodb_table_info
*) files
->data
)->length
;
155 /*! \fn astrodb_table *astrodb_table_create(astrodb_db *db, char *table_name, unsigned int flags)
157 * \param table_name Dataset name (dataset file name in ReadMe)
158 * \param flags Dataset creation flags.
159 * \return A astrodb_table* for success or NULL on error
161 * Creates a dataset object.
163 struct astrodb_table
*astrodb_table_create(struct astrodb_db
*db
,
164 char *table_name
, unsigned int flags
)
166 struct astrodb_dlist
*files
= db
->info
->files
;
167 struct astrodb_table
*table
= NULL
;
168 astrodb_info("Scanning for key fields in table: %s\n", table_name
);
171 struct astrodb_table_info
*table_info
=
172 (struct astrodb_table_info
*) files
->data
;
173 struct astrodb_dlist
*byte_desc
= table_info
->byte_description
;
175 /* create a tile array per file for files that have a byte desc */
177 !strncmp(table_name
, table_info
->name
, strlen(table_name
))) {
179 table
= create_table(db
, byte_desc
, files
);
180 table
->init_flags
= flags
;
181 astrodb_info(" scan: %s\n", table_info
->name
);
183 db
->tables
= astrodb_dlist_append(db
->tables
,
193 /*! \fn int astrodb_table_open(astrodb_table * table, astrodb_progress progress, int ra, int dec, int mag)
194 * \param table dataset
195 * \param progress Progress callback
196 * \param ra RA stride
197 * \param dec Dec stride
198 * \param mag Magnitude stride
200 * Initialise a dataset. This will download and import the raw data if necessary.
202 int insert_posn_mag(void *d
, void *object
);
204 int astrodb_table_open(struct astrodb_table
*table
, int ra
, int dec
, int mag
)
206 struct stat stat_info
;
211 sprintf(pstr
, "Initialising table %s", table
->file
);
213 /* do we have to delete existing dataset */
214 //if (flags & ADB_REFRESH)
215 // delete_table(astrodb_table* table);
217 //table_get_object_insert(table);
218 table
->object_insert
= &insert_posn_mag
;
219 ret
= init_table(table
, ra
, dec
, mag
);
221 astrodb_error("failed to initialise table %d\n", ret
);
225 /* check for local binary copy */
226 sprintf(file
, "%s%s%s", table
->db
->local_path
, table
->file
, ".idx");
227 ret
= stat(file
, &stat_info
);
229 ret
= table_load_hdr(table
);
231 astrodb_error("failed to load binary header %s %d\n",
235 ret
= table_uncache_tiles(table
);
237 astrodb_error("failed to uncache table tiles %d\n",
242 /* check for local ASCII copy */
243 sprintf(file
, "%s%s", table
->db
->local_path
, table
->file
);
244 ret
= stat(file
, &stat_info
);
248 /* check for local */
250 /* local binary or ASCII not available, so download ASCII */
251 if (!(strncmp("http://", table
->db
->lib
->remote
, 7)) ||
252 !(strncmp("ftp://", table
->db
->lib
->remote
, 6))) {
253 ret
= table_get_remote_dataset(table
);
255 astrodb_error("failed to get remote table %d\n", ret
);
260 if (table
->init_flags
& ADB_MEM
) {
261 ret
= table_import(table
, file
);
263 astrodb_error("failed to import table %s %d\n", file
,
268 if (table
->init_flags
& ADB_FILE
) {
269 ret
= table_save_hdr(table
);
271 astrodb_error("failed to save table schema %d\n", ret
);
274 ret
= table_cache_tiles(table
);
279 /*! \fn void astrodb_table_close(astrodb_table* table)
280 * \param table dataset
282 * Free dataset resources
284 void astrodb_table_close(struct astrodb_table
*table
)
287 struct astrodb_db
*db
= table
->db
;
290 for (i
= 0; i
< table
->num_hmaps
; i
++) {
291 for (j
= 0; j
< table
->no_tiles
; j
++) {
293 struct astrodb_slist
*slist
, *slist_
;
294 slist_
= *(table
->hmaps
[i
].hobjects
+ j
);
298 slist_
= slist_
->tail
;
303 free(table
->hmaps
[i
].hobjects
);
306 if (table
->objects
) {
307 /* free objects in array */
308 for (i
= 0; i
< table
->no_tiles
; i
++)
309 astrodb_slist_foreach_free(*(table
->objects
+ i
), NULL
, 0);
311 free(table
->objects
);
317 db
->tables
= astrodb_dlist_free_object(db
->tables
, table
);
320 /*! \fn int astrodb_table_add_custom_field(astrodb_table* table, char* field)
321 * \param table dataset
322 * \param field Field name to add
323 * \return 0 on success
325 * Add a custom field to a dataset for import.
327 int astrodb_table_add_custom_field(struct astrodb_table
*table
, char *field
)
329 struct astrodb_table_column_info
*byte
= NULL
;
330 struct astrodb_schema_object
*idx
= NULL
;
331 struct astrodb_dlist
*desc
= table
->byte_description
;
334 /* do we add all the fields */
335 if (!strncmp(field
, "*", 1))
338 while (desc
!= NULL
) {
340 byte
= (struct astrodb_table_column_info
*) desc
->data
;
341 idx
= &table
->idx
[table
->object_fields
];
343 if ((!strncmp(field
, byte
->label
, strlen(byte
->label
)) || full
) &&
344 !table_is_field(table
, byte
->label
)) {
346 idx
->s_offset
= table
->object_size
;
347 idx
->l_offset
= byte
->start
;
348 idx
->l_size
= byte
->end
- byte
->start
+ 1;
349 strncpy(idx
->name
, byte
->explanation
, 32);
350 strncpy(idx
->units
, byte
->units
, 16);
351 strncpy(idx
->symbol
, byte
->label
, 8);
352 idx
->type
= table_get_ctype(byte
->type
);
353 idx
->s_size
= table_get_csize(byte
->type
);
355 if (table
->idx
[table
->object_fields
].insert
== NULL
)
356 table
->idx
[table
->object_fields
].insert
=
357 table_get_custom_insert(byte
->type
);
359 table
->object_fields
++;
360 table
->object_size
+= idx
->s_size
;
370 astrodb_error("failed to add custom field %s\n", field
);
375 /*! \fn void astrodb_table_put_objects(astrodb_slist *results)
376 * \param results Results from astrodb_table_get_objects()
378 * Releases resources held by the results from astrodb_table_get_objects().
380 void astrodb_table_put_objects(struct astrodb_slist
*results
)
382 struct astrodb_slist
*slist
;
386 results
= results
->tail
;
391 /*! \fn int astrodb_table_alt_column(astrodb_table* table, char* field, char* alt, int flags)
392 * \param table dataset
393 * \param field Primary field
394 * \param alt Alternative field
397 * Set an alternative import field if the primary field is blank.
399 int astrodb_table_alt_column(struct astrodb_table
*table
, char *field
,
400 char *alt
, int flags
)
404 if (table
->alt_fields
>= TABLE_MAX_AIDX
) {
405 astrodb_error("too many alt fields %s\n", field
);
409 idx
= table_find_field(table
, field
);
411 astrodb_error("field not found %s\n", field
);
415 err
= table_add_alt_field(table
, alt
, idx
);
417 astrodb_error("failed to add field %s at idx %d\n", field
, idx
);
424 /*! \fn void astrodb_table_clip_on_position (astrodb_table* table, double min_ra, double min_dec, double max_ra, double max_dec, double faint_mag,double bright_mag)
425 * \param table dataset
426 * \param min_ra Min RA
427 * \param min_dec Min Dec
428 * \param max_ra Max RA
429 * \param max_dec Max Dec
430 * \param faint_mag Faint Magnitude
431 * \param bright_mag Bright Magnitude
433 * Clips the dataset to the within the given position range. Note: Clipping
434 * boundaries are not exact and depend on the granularity of the
435 * dataset position strides.
437 void astrodb_table_clip_on_position(struct astrodb_table
*table
,
438 double min_ra
, double min_dec
,
439 double max_ra
, double max_dec
,
440 double faint_mag
, double bright_mag
)
442 /* check ra,deg & mag boundaries */
443 if (min_ra
< table
->db
->ra_min
)
444 min_ra
= table
->db
->ra_min
;
445 if (max_ra
> table
->db
->ra_max
)
446 max_ra
= table
->db
->ra_max
;
447 if (min_dec
< table
->db
->dec_min
)
448 min_dec
= table
->db
->dec_min
;
449 if (max_dec
> table
->db
->dec_max
)
450 max_dec
= table
->db
->dec_max
;
451 if (faint_mag
> table
->db
->mag_faint
)
452 faint_mag
= table
->db
->mag_faint
;
453 if (bright_mag
< table
->db
->mag_bright
)
454 bright_mag
= table
->db
->mag_bright
;
456 /* normalise boundaries */
457 min_ra
-= table
->db
->ra_min
;
458 max_ra
-= table
->db
->ra_min
;
459 min_dec
-= table
->db
->dec_min
;
460 max_dec
-= table
->db
->dec_min
;
461 faint_mag
-= table
->db
->mag_bright
;
462 bright_mag
-= table
->db
->mag_bright
;
466 /* convert to stride boundaries */
467 table
->clip_min_ra
= floor(min_ra
/ table
->ra_stride_size
);
468 table
->clip_max_ra
= floor(max_ra
/ table
->ra_stride_size
);
469 table
->clip_min_dec
= floor(min_dec
/ table
->dec_stride_size
);
470 table
->clip_max_dec
= floor(max_dec
/ table
->dec_stride_size
);
472 table
->clip_bright_mag
= floor(bright_mag
/ table
->mag_stride_size
);
473 table
->clip_faint_mag
= floor(faint_mag
/ table
->mag_stride_size
);
476 /*! \fn void astrodb_table_clip_on_distance (astrodb_table* table, double min_AU, double max_AU)
477 * \param table dataset
478 * \param min_AU Min AU
479 * \param max_AU Max AU
481 * Clips the dataset to the within the given distance range. Note: Clipping
482 * boundaries are not exact and depend on the granularity of the
483 * dataset distance stride.
485 void astrodb_table_clip_on_distance(struct astrodb_table
*table
,
486 double min_AU
, double max_AU
)
488 /* check AU boundaries */
489 if (min_AU
< table
->db
->ra_min
)
490 min_AU
= table
->db
->ra_min
;
491 if (max_AU
> table
->db
->ra_max
)
492 max_AU
= table
->db
->ra_max
;
494 /* normalise boundaries */
495 min_AU
-= table
->db
->ra_min
;
496 max_AU
-= table
->db
->ra_min
;
500 /* convert to stride boundaries */
501 table
->clip_min_ra
= (int) min_AU
/ table
->ra_stride_size
;
502 table
->clip_max_ra
= ((int) max_AU
/ table
->ra_stride_size
) + 1;
505 /*! \fn void astrodb_table_clip_on_fov (astrodb_table* table, double ra, double dec, double radius,
506 double faint_mag, double bright_mag);
507 * \brief Set dataset clipping area based on field of view
510 void astrodb_table_clip_on_fov (struct astrodb_table
*table
,
511 double ra
, double dec
, double fov
,
512 double faint_mag
, double bright_mag
)
514 /* check boundaries */
516 if (ra
< table
->db
->ra_min
)
517 ra
= table
->db
->ra_min
;
518 if (ra
> table
->db
->ra_max
)
519 ra
= table
->db
->ra_max
;
520 if (dec
< table
->db
->dec_min
)
521 dec
= table
->db
->dec_min
;
522 if (dec
> table
->db
->dec_max
)
523 dec
= table
->db
->dec_max
;
524 if (faint_mag
> table
->db
->mag_faint
)
525 faint_mag
= table
->db
->mag_faint
;
526 if (bright_mag
< table
->db
->mag_bright
)
527 bright_mag
= table
->db
->mag_bright
;
529 table
->clip_centre_ra
= ra
;
530 table
->clip_centre_dec
= dec
;
532 /* normalise boundaries */
533 faint_mag
-= table
->db
->mag_bright
;
534 bright_mag
-= table
->db
->mag_bright
;
536 /* convert to stride boundaries */
537 table
->clip_bright_mag
= (int) bright_mag
/ table
->mag_stride_size
;
538 table
->clip_faint_mag
= ((int) faint_mag
/ table
->mag_stride_size
) + 1;
541 /*! \fn void astrodb_table_unclip (astrodb_table* table)
542 * \param table dataset
544 * Unclip the dataset to it's full boundaries
546 void astrodb_table_unclip(struct astrodb_table
*table
)
551 table
->clip_min_ra
= 0;
552 table
->clip_min_dec
= 0;
553 table
->clip_max_ra
= table
->ra_stride
- 1;
554 table
->clip_max_dec
= table
->dec_stride
- 1;
555 table
->clip_faint_mag
= table
->mag_stride
- 1;
556 table
->clip_bright_mag
= 0;
559 for (i
= 0; i
<= table
->clip_max_ra
; i
++) {
560 for (j
= 0; j
<= table
->clip_max_dec
; j
++) {
561 for (k
= 0; k
<= table
->clip_faint_mag
; k
++) {
562 offset
= table_calc_deep_offset(table
, i
, j
, k
);
563 (table
->status
+ offset
)->flags
&= ~ADB_SUSED
;
569 /*! int astrodb_table_get_objects (astrodb_table* table, astrodb_progress progress, astrodb_slist **result, unsigned int src)
570 * \param table dataset
571 * \param progress Progress callback
572 * \param results dataset objects
573 * \param src Get objects flags
574 * \return number of objects, or negative for failed
576 * Get objects from dataset based on clipping area. Results must be released
577 * with astrodb_table_put_objects() after use.
579 int astrodb_table_get_objects(struct astrodb_table
*table
,
580 struct astrodb_slist
**result
,
586 return table_get_objects_memc(table
, result
);
588 return table_get_objects_cachec(table
, result
);
590 return table_get_objects_rawc(table
, result
);
592 return table_get_objects_onlinec(table
, result
);
599 return table_get_objects_mem(table
, result
);
601 return table_get_objects_cache(table
, result
);
603 return table_get_objects_raw(table
, result
);
605 return table_get_objects_online(table
, result
);
612 /*! \fn int astrodb_table_prune(astrodb_table* table)
613 * \param table dataset
614 * \return bytes free'd
616 * Free's oldest unused object tiles.
618 int astrodb_table_prune(struct astrodb_table
*table
)
623 /*! \fn int astrodb_table_get_size(astrodb_table* table)
624 * \param table dataset
625 * \return size in bytes
627 * Get dataset memory usage.
629 int astrodb_table_get_size(struct astrodb_table
*table
)
631 return table
->object_size
* table
->db
->db_size
;
634 /*! \fn void astrodb_table_set_status_posn (astrodb_table* table, double min_ra, double min_dec, double max_ra, double max_dec, double faint_mag,double bright_mag, unsigned int status)
635 * \param table dataset
636 * \param min_ra Min RA
637 * \param min_dec Min Dec
638 * \param max_ra Max RA
639 * \param max_dec Max Dec
640 * \param faint_mag Faint Magnitude
641 * \param bright_mag Bright Magnitude
642 * \param status Object status
644 * Set the status of objects within a given position range.
646 void astrodb_table_set_status_posn(struct astrodb_table
*table
,
647 double min_ra
, double min_dec
,
648 double max_ra
, double max_dec
,
649 double faint_mag
, double bright_mag
,
653 int clip_min_ra
, clip_max_ra
, clip_min_dec
, clip_max_dec
,
654 clip_bright_mag
, clip_faint_mag
;
656 clip_min_ra
= table
->clip_min_ra
;
657 clip_max_ra
= table
->clip_max_ra
;
658 clip_min_dec
= table
->clip_min_dec
;
659 clip_max_dec
= table
->clip_max_dec
;
660 clip_bright_mag
= table
->clip_bright_mag
;
661 clip_faint_mag
= table
->clip_faint_mag
;
663 astrodb_table_clip_on_position(table
, min_ra
, min_dec
,
664 max_ra
, max_dec
, bright_mag
, faint_mag
);
666 for (i
= table
->clip_min_ra
; i
< table
->clip_max_ra
; i
++) {
667 for (j
= table
->clip_min_dec
; j
< table
->clip_max_dec
; j
++) {
668 for (k
= table
->clip_bright_mag
;
669 k
< table
->clip_faint_mag
; k
++) {
676 /*! \fn void astrodb_table_set_status_dist (astrodb_table* table, double min_AU, double max_AU, unsigned int status)
677 * \param table Dataset
678 * \param min_AU Minimum distance in AU
679 * \param max_AU Maximum distance in AU
680 * \param status Status flags to set
682 * Set the status of objects within a given distance range.
684 void astrodb_table_set_status_dist(struct astrodb_table
*table
,
685 double min_AU
, double max_AU
,
688 int min_offset
= (min_AU
- table
->db
->ra_min
) / table
->ra_stride_size
;
689 int max_offset
= (max_AU
- table
->db
->ra_min
) / table
->ra_stride_size
;
691 for (; min_offset
< max_offset
; min_offset
++) {
692 ((struct astrodb_tile_status
*)
693 (table
->status
+ min_offset
))->flags
= status
;
697 /*! \fn astrodb_tile_status astrodb_table_get_status_posn (astrodb_table* table, double ra, double dec, double mag)
698 * \param table Dataset
699 * \param ra RA in degrees
700 * \param dec DEC in dergrees
701 * \param mag Magnitude
703 * Get the status of objects within a tile at a give (ra,dec,mag) offset.
705 struct astrodb_tile_status
706 astrodb_table_get_status_posn(struct astrodb_table
*table
,
707 double ra
, double dec
, double mag
)
711 x
= floor((ra
- table
->db
->ra_min
) / table
->ra_stride_size
);
712 y
= floor((dec
- table
->db
->dec_min
) / table
->dec_stride_size
);
713 z
= floor((mag
- table
->db
->mag_bright
) / table
->mag_stride_size
);
714 offset
= table_calc_deep_offset(table
, x
, y
, z
);
716 return *(table
->status
+ offset
);
719 /*! \fn astrodb_tile_status astrodb_table_get_status_dist (astrodb_table* table, double AU)
720 * \param table Dataset
721 * \param AU Distance in AU
724 * Get the status of objects within a tile at a give distance offset.
726 struct astrodb_tile_status
727 astrodb_table_get_status_dist(struct astrodb_table
*table
, double AU
)
729 int offset
= floor((AU
- table
->db
->ra_min
) / table
->ra_stride_size
);
730 return *(table
->status
+ offset
);
733 /*! \fn astrodb_ctype astrodb_table_get_column_type(astrodb_table* table, char* field)
734 * \param table Dataset
735 * \param field Dataset field name
738 * Get the C type for a field within a dataset.
740 astrodb_ctype
astrodb_table_get_column_type(struct astrodb_table
*table
,
745 for (i
= 0; i
< table
->object_fields
; i
++) {
746 if (!strcmp(table
->idx
[i
].symbol
, field
))
747 return table
->idx
[i
].type
;
753 /*! \fn int astrodb_table_get_column_offset(astrodb_table* table, char* field)
754 * \param table Dataset
755 * \param field Dataset field name
756 * \return Field offset in bytes
758 * Gets the offset in bytes for a field within a dataset.
760 int astrodb_table_get_column_offset(struct astrodb_table
*table
, char *field
)
764 /* check custom fields */
765 for (i
= 0; i
< table
->object_fields
; i
++) {
766 if (!strcmp(table
->idx
[i
].symbol
, field
)) {
767 return table
->idx
[i
].s_offset
;
771 astrodb_error("failed to find field %s\n", field
);
775 /*! \fn int astrodb_table_for_search_results_do(astrodb_slist* res, void(*func)(void* object, void* data), void* data)
776 * \param res Results from get_objects
777 * \param func Function to call per object in res
778 * \param data Pointer to pass to func
779 * \return 0 for success, negative for error
781 * Calls func for every object in res.
784 int astrodb_table_for_search_results_do(struct astrodb_slist
*results
,
785 void (*func
) (void *object
, void *data
),
792 struct astrodb_slist
*slist
= results
->data
;
794 func(slist
->data
, data
);
797 results
= results
->tail
;
804 /*! \fn int astrodb_table_get_row_size(astrodb_table* table);
806 int astrodb_table_get_row_size(struct astrodb_table
*table
)
808 return table
->object_size
;
812 /*! \fn void* astrodb_table_get_object (astrodb_table* table, char* id, char* field);
813 * \param table dataset
814 * \param id object id
815 * \param field dataset field
816 * \return object or NULL if not found
818 * Get an object based on it' ID
820 void* astrodb_table_get_object (struct astrodb_table
*table
, char *id
,
823 struct astrodb_slist
*slist
= NULL
;
826 for (i
= 0; i
< table
->num_hmaps
; i
++) {
827 if (!strncmp(field
, table
->hmaps
[i
].field
,
828 strlen(table
->hmaps
[i
].field
))) {
832 astrodb_error("failed to find field %s\n", field
);
836 offset
= table_calc_hash(id
, strlen(id
), table
->no_tiles
);
837 slist
= *(table
->hmaps
[i
].hobjects
+ offset
);
840 char* object_id
= slist
->data
+ table
->hmaps
[i
].offset
;
841 if (!strstr(object_id
, id
))
846 astrodb_error("failed to find id %s\n", id
);
850 /*! \fn int astrodb_table_hash_key(astrodb_table* table, char* field)
851 * \param table dataset
852 * \param field Field to be hashed.
853 * \return 0 on success
855 * Add a field to be hashed for fast lookups.
857 int astrodb_table_hash_key(struct astrodb_table
* table
, char* key
)
859 if (table
->num_hmaps
== HASH_MAPS
) {
860 astrodb_error("too many hashed keys %s\n", key
);
864 table
->hmaps
[table
->num_hmaps
].offset
=
865 astrodb_table_get_column_offset(table
, key
);
866 if (table
->hmaps
[table
->num_hmaps
].offset
< 0) {
867 astrodb_error("invalid column offset %s\n", key
);
871 strncpy(table
->hmaps
[table
->num_hmaps
].field
, key
, 8);
876 /*! \fn int astrodb_table_register_schema(astrodb_table* table, astrodb_schema_object* idx, int idx_size);
877 * \param table dataset
878 * \param idx Object field index
879 * \param idx_size Number of fields in index
880 * \return 0 on success
882 * Register a new custom object type
884 int astrodb_table_register_schema(struct astrodb_table
*table
,
885 struct astrodb_schema_object
*idx
,
886 int idx_size
, int object_size
)
890 for (i
= 0, n
= 0; i
< idx_size
; i
++) {
891 if (!table_add_custom_struct_field(table
, &idx
[i
]))
894 table
->object_size
= object_size
;