-/** The columns of the id table. */
-enum user_table_columns {
- /** The numer of the directory. */
- UT_DIR_NUM,
- /** The number of bytes of all regular files in this dir owned by this id. */
- UT_BYTES,
- /** The number of files in this dir owned by this id. */
- UT_FILES,
- /** Number of columns in this table. */
- NUM_UT_COLUMNS
-};
-
-static struct osl_column_description user_table_cols[] = {
- [UT_DIR_NUM] = {
- .storage_type = OSL_MAPPED_STORAGE,
- .storage_flags = OSL_RBTREE | OSL_FIXED_SIZE | OSL_UNIQUE,
- .name = "dir_num",
- .compare_function = uint64_compare,
- .data_size = sizeof(uint64_t)
- },
- [UT_BYTES] = {
- .storage_type = OSL_MAPPED_STORAGE,
- .storage_flags = OSL_RBTREE | OSL_FIXED_SIZE,
- .compare_function = size_compare,
- .name = "num_bytes",
- .data_size = sizeof(uint64_t)
- },
- [UT_FILES] = {
- .storage_type = OSL_MAPPED_STORAGE,
- .storage_flags = OSL_RBTREE | OSL_FIXED_SIZE,
- .compare_function = size_compare,
- .name = "num_files",
- .data_size = sizeof(uint64_t)
- },
-};
-
-static struct osl_table *dir_table;
-
-static int add_directory(char *dirname, uint64_t dir_num, uint64_t *dir_size,
- uint64_t *dir_files)
-{
- struct osl_object dir_objects[NUM_DT_COLUMNS];
-
- INFO_LOG("adding #%llu: %s\n", (long long unsigned)dir_num, dirname);
- dir_objects[DT_NAME].data = dirname;
- dir_objects[DT_NAME].size = strlen(dirname) + 1;
- dir_objects[DT_NUM].data = &dir_num;
- dir_objects[DT_NUM].size = sizeof(dir_num);
- dir_objects[DT_BYTES].data = dir_size;
- dir_objects[DT_BYTES].size = sizeof(*dir_size);
- dir_objects[DT_FILES].data = dir_files;
- dir_objects[DT_FILES].size = sizeof(*dir_files);
-
- return osl_add_row(dir_table, dir_objects);
-}
-
-static uint32_t num_uids;
-
-static int open_user_table(struct user_info *ui, int create)
-{
- int ret;
-
- ui->desc = para_malloc(sizeof(*ui->desc));
- ui->desc->num_columns = NUM_UT_COLUMNS;
- ui->desc->flags = 0;
- ui->desc->column_descriptions = user_table_cols;
- ui->desc->dir = para_strdup(conf.database_dir_arg);
- ui->desc->name = make_message("%u", (unsigned)ui->uid);
- INFO_LOG(".............................uid #%u: %u\n",
- (unsigned)num_uids, (unsigned)ui->uid);
- if (create) {
- ret = osl_create_table(ui->desc);
- if (ret < 0)
- goto err;
- num_uids++;
- }
- ret = osl_open_table(ui->desc, &ui->table);
- if (ret < 0)
- goto err;
- return 1;
-err:
- free((char *)ui->desc->name);
- free((char *)ui->desc->dir);
- free(ui->desc);
- ui->desc->name = NULL;
- ui->desc->dir = NULL;
- ui->desc = NULL;
- ui->table = NULL;
- return ret;
-}
-
-#define uid_hash_bits 8
-static uint32_t uid_hash_table_size = 1 << uid_hash_bits;
-#define PRIME1 0x811c9dc5
-#define PRIME2 0x01000193
-
-static void create_hash_table(void)
-{
- uid_hash_table = para_calloc(uid_hash_table_size
- * sizeof(struct user_info));
-}
-
-static void free_hash_table(void)
-{
- free(uid_hash_table);
- uid_hash_table = NULL;
-}
-
-static int create_tables(void)
-{
- int ret;
-
- dir_table_desc.dir = para_strdup(conf.database_dir_arg);
- ret = osl_create_table(&dir_table_desc);
- if (ret < 0)
- return ret;
- create_hash_table();
- return 1;
-}
-
-/*
- * We use a hash table of size s=2^uid_hash_bits to map the uids into the
- * interval [0..s]. Hash collisions are treated by open addressing, i.e.
- * unused slots in the table are used to store different uids that hash to the
- * same slot.