Cleared out earlier iterations of iterators.
authorNot Zed <notzed@gmail.com>
Sat, 19 Jun 2021 07:34:32 +0000 (17:04 +0930)
committerNot Zed <notzed@gmail.com>
Sat, 19 Jun 2021 07:34:32 +0000 (17:04 +0930)
Expanded validate for more checks.
Fixed some small bugs.

dbindex.c
dbindex.h
disk-indexer.c
disk-monitor.c
index-util.c
music-player.c

index c2876a0..d022a05 100644 (file)
--- a/dbindex.c
+++ b/dbindex.c
@@ -220,7 +220,7 @@ dbindex *dbindex_open(const char *ipath) {
 
                        list.name = (char *)names[i];
                        list.desc = (char *)descs[i];
-                       if (tmp = dblist_add(tx, db, &list)) {
+                       if ((tmp = dblist_add(tx, db, &list))) {
                                if (tmp == MDB_KEYEXIST)
                                        db->listid = find_next_id(tx, db->list);
                                else {
@@ -263,7 +263,7 @@ dbindex *dbindex_open(const char *ipath) {
                db = NULL;
        }
 
-       printf("index open: disk.id=%d list.id=%d file.id=%d\n", db->diskid, db->listid, db->fileid);
+       printf("index open: '%s' disk.id=%d list.id=%d file.id=%d\n", path, db->diskid, db->listid, db->fileid);
        free(dpath);
 
        return db;
@@ -445,7 +445,7 @@ static int secondary_list_all(dbtxn *tx, MDB_dbi secondary, ez_array *array) {
        MDB_val key, data;
        int res;
 
-       if (res = mdb_cursor_open(tx, secondary, &cursor))
+       if ((res = mdb_cursor_open(tx, secondary, &cursor)))
                return res;
 
        int op = MDB_FIRST;
@@ -468,16 +468,16 @@ static int secondary_list_all(dbtxn *tx, MDB_dbi secondary, ez_array *array) {
        return res;
 }
 
-static int secondary_list_key(dbtxn *tx, MDB_dbi secondary, MDB_val key, ez_array *array) {
+static int secondary_list_key(dbtxn *tx, MDB_dbi secondary, MDB_val *key, ez_array *array) {
        MDB_cursor *cursor;
        MDB_val data;
        int res;
 
-       if (res = mdb_cursor_open(tx, secondary, &cursor))
+       if ((res = mdb_cursor_open(tx, secondary, &cursor)))
                return res;
 
        int op = MDB_SET_KEY;
-       while ((res = mdb_cursor_get(cursor, &key, &data, op)) == 0) {
+       while ((res = mdb_cursor_get(cursor, key, &data, op)) == 0) {
                if (!ez_array_add(array, data.mv_data, data.mv_size)) {
                        res = ENOMEM;
                        break;
@@ -490,69 +490,37 @@ static int secondary_list_key(dbtxn *tx, MDB_dbi secondary, MDB_val key, ez_arra
                ez_array_clear(array);
        }
 
-       printf("secondary list all: %s\n", mdb_strerror(res));
+       printf("secondary list key: %s\n", mdb_strerror(res));
 
        mdb_cursor_close(cursor);
        return res;
 }
 
-
-// merge/replace with above?
-static uint32_t *scan_all(dbscan *scan, ssize_t *sizep) {
-       int fid;
-       int fids_size = 4096;
-       int count = 0;
-       uint32_t *fids = malloc(sizeof(*fids) * fids_size);
-
-       if (!fids)
-               goto fail;
-
-       while ((fid = dbfile_scan_next(scan)) != ~0) {
-               if (count >= fids_size) {
-                       uint32_t *tmp;
-
-                       fids_size *= 2;
-                       tmp = realloc(fids, sizeof(*fids) * fids_size);
-                       if (!tmp)
-                               goto fail;
-                       fids = tmp;
-               }
-               fids[count++] = fid;
-       }
-
-       *sizep = count;
-       return fids;
-fail:
-       free(fids);
-       *sizep = -1;
-       return NULL;
-}
-
 int dbdisk_del(dbtxn *tx, dbindex *db, dbdisk *disk) {
-       dbscan *scan = dbfile_scan_disk(tx, db, disk->id);
-       uint32_t *fids = NULL;
-       ssize_t count;
+       MDB_val key;
+       ez_array array = { 0 };
        int res = 0;
 
-       fids = scan_all(scan, &count);
-       if (count == -1) {
-               res = ENOMEM;
+       key.mv_data = &disk->id;
+       key.mv_size = sizeof(disk->id);
+       if ((res = secondary_list_key(tx, db->file_by_disk, &key, &array)))
                goto fail;
-       }
+
+       dbid_t *fids = array.ea_data;
+       size_t count = array.ea_size / sizeof(*fids);
 
        for (int i=0;i<count;i++) {
                printf(" file %d\n", fids[i]);
-               if (res = dbfile_del_id(tx, db, fids[i]))
+               if ((res = dbfile_del_id(tx, db, fids[i])))
                        goto fail;
        }
 
        // secondary keys
-       MDB_val key;
 
        // -- by uuid
        key.mv_data = disk->uuid;
        key.mv_size = strlen(disk->uuid);
-       if (res = mdb_del(tx, db->disk_by_uuid, &key, NULL))
+       if ((res = mdb_del(tx, db->disk_by_uuid, &key, NULL)))
                goto fail;
 
        // Remove disk
@@ -561,7 +529,7 @@ int dbdisk_del(dbtxn *tx, dbindex *db, dbdisk *disk) {
        res = mdb_del(tx, db->disk, &key, NULL);
 
 fail:
-       free(fids);
+       ez_array_clear(&array);
        return res;
 }
 
@@ -593,7 +561,7 @@ char *dbfile_full_path(dbtxn *tx, dbindex *db, dbfile *file) {
        if (!file->full_path) {
                dbdisk *disk = dbdisk_get(tx, db, file->diskid);
 
-               if (file->full_path = malloc(strlen(disk->mount) + strlen(file->path) + 1))
+               if ((file->full_path = malloc(strlen(disk->mount) + strlen(file->path) + 1)))
                        sprintf(file->full_path, "%s%s", disk->mount, file->path);
 
                dbdisk_free(disk);
@@ -612,7 +580,7 @@ int dbfile_inlist(dbtxn *tx, dbindex *db, dbid_t fileid, dbid_t listid) {
        if ((db->res = mdb_cursor_open(tx, db->list_by_file, &cursor)))
                goto fail1;
 
-       if (db->res = mdb_cursor_get(cursor, &key, &dat, MDB_GET_BOTH_RANGE))
+       if ((db->res = mdb_cursor_get(cursor, &key, &dat, MDB_GET_BOTH_RANGE)))
                goto fail;
 
        is = ((struct dblistfile *)dat.mv_data)->listid == listid;
@@ -768,7 +736,7 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
 
        key.mv_data = dpath;
        key.mv_size = strlen(dpath);
-       if (res = mdb_del(tx, db->file_by_path, &key, NULL))
+       if ((res = mdb_del(tx, db->file_by_path, &key, &dat)))
                goto fail;
 
        // - by disk+dir
@@ -778,36 +746,46 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
                goto fail;
        }
        key.mv_size = tmp - dpath;
-       if (res = mdb_del(tx, db->file_by_dir, &key, NULL))
+       if ((res = mdb_del(tx, db->file_by_dir, &key, &dat))) {
+               printf("fail: file_by_dir\n");
                goto fail;
+       }
 
        // - by diskid
        key.mv_data = &f->diskid;
        key.mv_size = sizeof(f->diskid);
-       if (res = mdb_del(tx, db->file_by_disk, &key, &dat))
+       if ((res = mdb_del(tx, db->file_by_disk, &key, &dat))) {
+               printf("fail: file_by_disk\n");
                goto fail;
+       }
 
        // - by title
        if (f->title) {
                key.mv_data = f->title;
                key.mv_size = strlen(f->title);
-               if (res = mdb_del(tx, db->file_by_title, &key, &dat))
+               if ((res = mdb_del(tx, db->file_by_title, &key, &dat))) {
+                       printf("fail: file_by_title\n");
                        goto fail;
+               }
        }
 
        // - by artist
        if (f->artist) {
                key.mv_data = f->artist;
                key.mv_size = strlen(f->artist);
-               if (res = mdb_del(tx, db->file_by_artist, &key, &dat))
+               if ((res = mdb_del(tx, db->file_by_artist, &key, &dat))) {
+                       printf("fail: file_by_artist\n");
                        goto fail;
+               }
        }
 
        // Remove file
        key.mv_data = &f->id;
        key.mv_size = sizeof(f->id);
-       if (res = mdb_del(tx, db->file, &key, NULL))
+       if ((res = mdb_del(tx, db->file, &key, NULL))) {
+               printf("fail: file\n");
                goto fail;
+       }
 
        // check lists, FIXME: cleanup
        {
@@ -819,20 +797,24 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
                        goto fail1;
 
                res = mdb_cursor_get(cursor, &key, &dat, MDB_SET);
+               if (res == MDB_NOTFOUND) {
+                       res = 0;
+                       goto fail2;
+               }
                while (res == 0) {
                        if (ez_array_add(&array, dat.mv_data, dat.mv_size))
                                res = mdb_cursor_get(cursor, &key, &dat, MDB_NEXT_DUP);
                        else
                                res = ENOMEM;
                }
-               printf("get list contents: res=%d\n", res);
+               printf("get list contents: res=%s\n", mdb_strerror(res));
                mdb_cursor_close(cursor);
                if (res != MDB_NOTFOUND)
-                       goto fail1;
+                       goto fail2;
 
                // delete the entry we just read
-               if (res = mdb_del(tx, db->list_by_file, &key, NULL))
-                       goto fail1;
+               if ((res = mdb_del(tx, db->list_by_file, &key, NULL)))
+                       goto fail2;
 
                struct dblistfile *files = array.ea_data;
                int count = array.ea_size / sizeof(*files);
@@ -849,8 +831,8 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
                        key.mv_size = sizeof(files[i].listid);
                        dat.mv_data = &fdata;
                        dat.mv_size = sizeof(fdata);
-                       if (res = mdb_del(tx, db->file_by_list, &key, &dat))
-                               goto fail1;
+                       if ((res = mdb_del(tx, db->file_by_list, &key, &dat)))
+                               goto fail2;
                }
 
                // update all the list counts
@@ -859,9 +841,9 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
                        struct hist_node hk = { .key = files[i].listid };
                        struct hist_node *hn;
 
-                       if (hn = ez_set_get(&counts, &hk))
+                       if ((hn = ez_set_get(&counts, &hk)))
                                hn->count += 1;
-                       else if (hn = malloc(sizeof(*hn))) {
+                       else if ((hn = malloc(sizeof(*hn)))) {
                                hn->key = hk.key;
                                hn->count = 1;
                                ez_set_put(&counts, hn);
@@ -886,7 +868,7 @@ int dbfile_del(dbtxn *tx, dbindex *db, dbfile *f) {
 
                ez_set_clear(&counts);
        fail2:
-
+               mdb_cursor_close(cursor);
        fail1:
                ez_array_clear(&array);
        }
@@ -924,14 +906,14 @@ int dbfile_update(dbtxn *tx, dbindex *db, dbfile *o, dbfile *f) {
                if (o->artist) {
                        key.mv_data = o->artist;
                        key.mv_size = strlen(o->artist);
-                       if (res = mdb_del(tx, db->file_by_artist, &key, &data))
+                       if ((res = mdb_del(tx, db->file_by_artist, &key, &data)))
                                goto fail;
                }
 
                if (f->artist) {
                        key.mv_data = f->artist;
                        key.mv_size = strlen(f->artist);
-                       if (res = mdb_put(tx, db->file_by_artist, &key, &data, 0))
+                       if ((res = mdb_put(tx, db->file_by_artist, &key, &data, 0)))
                                goto fail;
                }
        }
@@ -940,14 +922,14 @@ int dbfile_update(dbtxn *tx, dbindex *db, dbfile *o, dbfile *f) {
                if (o->title) {
                        key.mv_data = o->title;
                        key.mv_size = strlen(o->title);
-                       if (res = mdb_del(tx, db->file_by_title, &key, &data))
+                       if ((res = mdb_del(tx, db->file_by_title, &key, &data)))
                                goto fail;
                }
 
                if (f->title) {
                        key.mv_data = f->title;
                        key.mv_size = strlen(f->title);
-                       if (res = mdb_put(tx, db->file_by_title, &key, &data, 0))
+                       if ((res = mdb_put(tx, db->file_by_title, &key, &data, 0)))
                                goto fail;
                }
        }
@@ -957,7 +939,7 @@ int dbfile_update(dbtxn *tx, dbindex *db, dbfile *o, dbfile *f) {
        key.mv_size = sizeof(f->id);
 
        data.mv_size = ez_basic_size(DBFILE_DESC, f);
-       if (res = mdb_put(tx, db->file, &key, &data, MDB_RESERVE))
+       if ((res = mdb_put(tx, db->file, &key, &data, MDB_RESERVE)))
                goto fail;
 
        ez_basic_encode_raw(DBFILE_DESC, f, (ez_blob *)&data);
@@ -999,7 +981,7 @@ int dbfile_add(MDB_txn *tx, dbindex *db, dbfile *f) {
        dpath = dbfile_path(f);
        key.mv_data = dpath;
        key.mv_size = strlen(dpath);
-       if (res = mdb_put(tx, db->file_by_path, &key, &data, MDB_NOOVERWRITE)) {
+       if ((res = mdb_put(tx, db->file_by_path, &key, &data, MDB_NOOVERWRITE))) {
                fprintf(stderr, "UNIQUE: path on this disk exists\n");
                goto fail;
        }
@@ -1012,7 +994,7 @@ int dbfile_add(MDB_txn *tx, dbindex *db, dbfile *f) {
                goto fail;
        }
        key.mv_size = tmp - dpath;
-       if (res = mdb_put(tx, db->file_by_dir, &key, &data, MDB_NODUPDATA)) {
+       if ((res = mdb_put(tx, db->file_by_dir, &key, &data, MDB_NODUPDATA))) {
                fprintf(stderr, "UNIQUE: file on this path exists\n");
                goto fail;
        }
@@ -1020,14 +1002,14 @@ int dbfile_add(MDB_txn *tx, dbindex *db, dbfile *f) {
        // - by diskid
        key.mv_data = &f->diskid;
        key.mv_size = sizeof(f->diskid);
-       if (res = mdb_put(tx, db->file_by_disk, &key, &data, 0))
+       if ((res = mdb_put(tx, db->file_by_disk, &key, &data, 0)))
                goto fail;
 
        // - by title
        if (f->title) {
                key.mv_data = f->title;
                key.mv_size = strlen(f->title);
-               if (res = mdb_put(tx, db->file_by_title, &key, &data, 0))
+               if ((res = mdb_put(tx, db->file_by_title, &key, &data, 0)))
                        goto fail;
        }
 
@@ -1035,7 +1017,7 @@ int dbfile_add(MDB_txn *tx, dbindex *db, dbfile *f) {
        if (f->artist) {
                key.mv_data = f->artist;
                key.mv_size = strlen(f->artist);
-               if (res = mdb_put(tx, db->file_by_artist, &key, &data, 0))
+               if ((res = mdb_put(tx, db->file_by_artist, &key, &data, 0)))
                        goto fail;
        }
 
@@ -1241,7 +1223,7 @@ static int dblist_put(dbtxn *tx, dbindex *db, dblist *list, unsigned int flags)
        MDB_val dat = { .mv_data = NULL, .mv_size = ez_basic_size(DBLIST_DESC, list) };
        int res;
 
-       if (res = mdb_put(tx, db->list, &key, &dat, flags | MDB_RESERVE))
+       if ((res = mdb_put(tx, db->list, &key, &dat, flags | MDB_RESERVE)))
                return res;
 
        ez_basic_encode_raw(DBLIST_DESC, list, (ez_blob *)&dat);
@@ -1290,7 +1272,7 @@ int dblist_add(MDB_txn *txn, dbindex *db, dblist *list) {
 
        // Store record
        list->id = list_next_id(db);
-       if (res = dblist_put(tx, db, list, MDB_NOOVERWRITE))
+       if ((res = dblist_put(tx, db, list, MDB_NOOVERWRITE)))
                goto fail;
 
        // secondary keys
@@ -1300,7 +1282,7 @@ int dblist_add(MDB_txn *txn, dbindex *db, dblist *list) {
        // - by name
        key.mv_data = list->name;
        key.mv_size = strlen(list->name);
-       if (res = mdb_put(tx, db->list_by_name, &key, &dat, MDB_NOOVERWRITE))
+       if ((res = mdb_put(tx, db->list_by_name, &key, &dat, MDB_NOOVERWRITE)))
                goto fail;
 
        return mdb_txn_commit(tx);
@@ -1320,7 +1302,7 @@ int dblist_clear(dbtxn *tx, dbindex *db, int listid) {
        key.mv_data = &listid;
        key.mv_size = sizeof(listid);
 
-       res = secondary_list_key(tx, db->file_by_list, key, &array);
+       res = secondary_list_key(tx, db->file_by_list, &key, &array);
        list = array.ea_data;
        count = array.ea_size / sizeof(*list);
        if (count) {
@@ -1328,7 +1310,7 @@ int dblist_clear(dbtxn *tx, dbindex *db, int listid) {
                // delete list values
                key.mv_data = &listid;
                key.mv_size = sizeof(listid);
-               if (res = mdb_del(tx, db->file_by_list, &key, NULL)) {
+               if ((res = mdb_del(tx, db->file_by_list, &key, NULL))) {
                        printf(" delete list fail\n");
                        goto fail;
                }
@@ -1345,7 +1327,7 @@ int dblist_clear(dbtxn *tx, dbindex *db, int listid) {
 
                        entry.seq = list[i].seq;
 
-                       if (res = mdb_del(tx, db->list_by_file, &key, &data)) {
+                       if ((res = mdb_del(tx, db->list_by_file, &key, &data))) {
                                printf(" delete fail fid=%d  -> list=%d seq=%d\n", list[i].fileid, entry.listid, entry.seq);
                                if (res == MDB_NOTFOUND) {
                                        printf(" db inconsistent, continuing\n");
@@ -1375,10 +1357,10 @@ int dblist_del(dbtxn *txn, dbindex *db, int listid) {
 
        key.mv_data = &listid;
        key.mv_size = sizeof(listid);
-       if (res = mdb_del(tx, db->list, &key, NULL))
+       if ((res = mdb_del(tx, db->list, &key, NULL)))
                goto fail;
 
-       if (res = mdb_del(tx, db->file_by_list, &key, NULL))
+       if ((res = mdb_del(tx, db->file_by_list, &key, NULL)))
                goto fail;
 
        res = mdb_cursor_open(tx, db->list_by_file, &cursor);
@@ -1391,7 +1373,7 @@ int dblist_del(dbtxn *txn, dbindex *db, int listid) {
 
                if (value->listid == listid) {
                        printf("delete\n");
-                       if (res = mdb_cursor_del(cursor, 0))
+                       if ((res = mdb_cursor_del(cursor, 0)))
                                goto fail;
                        res = mdb_cursor_get(cursor, &key, &data, MDB_GET_CURRENT);
                } else {
@@ -1553,7 +1535,7 @@ int dblist_init_system(dbtxn *tx, dbindex *db) {
 
                list.name = (char *)names[i];
                list.desc = (char *)descs[i];
-               if (tmp = dblist_add(tx, db, &list)) {
+               if ((tmp = dblist_add(tx, db, &list))) {
                        if (tmp == MDB_KEYEXIST)
                                db->listid = find_next_id(tx, db->list);
                        else
@@ -1587,14 +1569,14 @@ int dblist_update_all(dbtxn *tx, dbindex *db) {
        dbid_t *fids = NULL;
        ez_array array = { 0 };
 
-       if (res = secondary_list_all(tx, db->file_by_path, &array))
+       if ((res = secondary_list_all(tx, db->file_by_path, &array)))
                goto fail;
 
        fids = array.ea_data;
        count = array.ea_size / sizeof(*fids);
 
        // Create the all list
-       if (res = dblist_update(tx, db, "all", fids, count))
+       if ((res = dblist_update(tx, db, "all", fids, count)))
                goto fail;
 
        // Create the all shuffled list
@@ -1666,7 +1648,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
 
        printf("list_del_file: lid=%4d seq=%4d fid=%4d\n", list->listid, list->seq, list->fileid);
 
-       if (res = mdb_txn_begin(db->env, txn, 0, &tx))
+       if ((res = mdb_txn_begin(db->env, txn, 0, &tx)))
                goto fail0;
 
        int delcursor = 0;
@@ -1675,7 +1657,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
 
        if (list->seq == 0) {
                // No sequence, lookup (first) fileid for the list
-               if (res = mdb_cursor_open(tx, db->list_by_file, &cursor))
+               if ((res = mdb_cursor_open(tx, db->list_by_file, &cursor)))
                        goto fail;
 
                key.mv_data = &list->fileid;
@@ -1683,7 +1665,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
                data.mv_data = &rvalue;
                data.mv_size = sizeof(rvalue);
 
-               if (res = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH_RANGE))
+               if ((res = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH_RANGE)))
                        goto fail;
 
                fvalue.seq = list->seq = ((struct dblistfile *)data.mv_data)->seq;
@@ -1694,7 +1676,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
                delfile = 1;
        } else if (list->fileid == 0) {
                // Lookup fileid for list[seq]
-               if (res = mdb_cursor_open(tx, db->file_by_list, &cursor))
+               if ((res = mdb_cursor_open(tx, db->file_by_list, &cursor)))
                        goto fail;
 
                key.mv_data = &list->listid;
@@ -1702,7 +1684,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
                data.mv_data = &fvalue;
                data.mv_size = sizeof(fvalue);
 
-               if (res = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH))
+               if ((res = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH)))
                        goto fail;
 
                list->fileid = ((struct dbfilelist *)data.mv_data)->fileid;
@@ -1726,7 +1708,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
                data.mv_data = &fvalue;
                data.mv_size = sizeof(fvalue);
 
-               if (res = mdb_del(tx, db->file_by_list, &key, &data))
+               if ((res = mdb_del(tx, db->file_by_list, &key, &data)))
                        goto fail;
        }
 
@@ -1736,7 +1718,7 @@ int dblist_del_file(MDB_txn *txn, dbindex *db, struct dblistcursor *list) {
                data.mv_data = &rvalue;
                data.mv_size = sizeof(rvalue);
 
-               if (res = mdb_del(tx, db->list_by_file, &key, &data))
+               if ((res = mdb_del(tx, db->list_by_file, &key, &data)))
                        goto fail;
        }
 
@@ -1958,237 +1940,116 @@ void dbindex_dump(dbindex *db) {
        }
 }
 
+/* new dbscan version for for loops*/
+// for (foo = dbscan_foo(); foo; foo = dbscan_foo_next()) {
+// }
+// dbscan_free();
 
+static void *dbscan_decode(dbscan *scan) {
+       void *memory = calloc(scan->DESC->bd_offset, 1);
 
-
-
-/* scan tables with int keys */
-// TBD
-static dbscan *dbscan_secondary(dbtxn *tx, dbindex *db, MDB_dbi table, int diskid) {
-       dbscan *scan = calloc(1, sizeof(*scan));
-       int res;
-
-       scan->db = db;
-       scan->table = table;
-
-       scan->cursor = NULL;
-
-       scan->keyval = diskid;
-       scan->key.mv_data = &scan->keyval;
-       scan->key.mv_size = sizeof(scan->keyval);
-
-       if ((res = mdb_cursor_open(tx, table, &scan->cursor)))
-               goto fail;
-
-       if (diskid != -1)
-               res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_SET);
-       else
-               res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_FIRST);
-
-       if (res) {
-               if (res == MDB_NOTFOUND) {
-                       scan->count = 0;
-                       scan->index = 0;
-                       return scan;
-               }
-               goto fail;
+       if (memory) {
+               scan->decode_raw((const ez_blob *)&scan->dat, memory);
+               *(dbid_t *)memory = *(dbid_t *)scan->key.mv_data;
+       } else {
+               scan->res = ENOMEM;
        }
 
-       if ((res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_GET_MULTIPLE)))
-               goto fail;
-
-       scan->count = scan->data.mv_size / sizeof(int);
-       scan->index = 0;
-
-       return scan;
-
- fail:
-       fprintf(stderr, "db scan open fail: %s\n", mdb_strerror(res));
-       dbfile_scan_close(scan);
-       return NULL;
+       return memory;
 }
 
-// TBD
-static uint32_t dbscan_secondary_next(dbscan *scan) {
-       int res = 0;
-
-       while (scan->count > 0) {
-               if (scan->index < scan->count)
-                       return ((uint32_t *)scan->data.mv_data)[scan->index++];
-
-               if (res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_NEXT_MULTIPLE)) {
-                       if (res == MDB_NOTFOUND && scan->keyval == -1) {
-                               res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_NEXT);
-                               if (res == 0)
-                                       res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_GET_MULTIPLE);
-                       }
-                       if (res)
-                               goto fail;
-               }
-
-               scan->count = scan->data.mv_size / sizeof(uint32_t);
-               scan->index = 0;
-       }
-
-       return ~0;
- fail:
-       if (res != MDB_NOTFOUND)
-               fprintf(stderr, "db scan fail: %s\n", mdb_strerror(res));
-       return ~0;
+void dbscan_free(dbscan *scan) {
+       if (scan->cursor)
+               mdb_cursor_close(scan->cursor);
+       memset(scan, 0, sizeof(*scan));
 }
 
-static dbscan *dbscan_primary(dbtxn *tx, dbindex *db, MDB_dbi table, int diskid) {
-       dbscan *scan = calloc(1, sizeof(*scan));
-       int res;
-
-       scan->db = db;
-       scan->table = table;
-
-       scan->keyval = diskid;
-       scan->key.mv_data = &scan->keyval;
-       scan->key.mv_size = sizeof(scan->keyval);
+static void *dbscan_primary_first(dbtxn *tx, dbscan *scan, dbindex *db, MDB_dbi primary, ez_blob_desc *desc, void (*decode_raw)(const ez_blob *blob, void *p), MDB_cursor_op first) {
+       scan->tx = tx;
+       scan->primary = primary;
+       scan->DESC = desc;
+       scan->decode_raw = decode_raw;
+       scan->mode = 0;
 
-       if ((res = mdb_cursor_open(tx, table, &scan->cursor))) {
-               printf("cursor open failed for table %d\n", table);
+       if ((scan->res = mdb_cursor_open(tx, primary, &scan->cursor)))
                goto fail;
-       }
-
-       if (diskid != -1)
-               res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_SET);
-       else
-               res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_FIRST);
-
-       if (res) {
-               if (res == MDB_NOTFOUND) {
-                       scan->count = 0;
-                       scan->index = 0;
-                       return scan;
-               }
+       if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->dat, first)))
                goto fail;
-       }
-
-       scan->count = 1;
-       scan->index = 0;
-
-       return scan;
 
- fail:
-       fprintf(stderr, "dbscan_primary fail: %s\n", mdb_strerror(res));
-       dbfile_scan_close(scan);
+       return dbscan_decode(scan);
+fail:
        return NULL;
 }
 
-// return 1 if there's a value
-static int dbscan_primary_next(dbscan *scan) {
-       int res = 0;
-
-       while (scan->count > 0) {
-               if (scan->index == 0) {
-                       scan->index += 1;
-                       return 1;
-               }
-
-               if (res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_NEXT))
-                       goto fail;
-
-               scan->count = 1;
-               scan->index = 0;
-       }
-
-       return 0;
- fail:
-       if (res != MDB_NOTFOUND)
-               fprintf(stderr, "db scan fail: %s\n", mdb_strerror(res));
-       return 0;
-}
-
-void dbscan_close(dbscan *scan) {
-       if (scan->cursor)
-               mdb_cursor_close(scan->cursor);
-       free(scan);
-}
-
-
-/* new dbscan version */
-/* copy libeze mode, return on init, next/prev calls */
-
-static __inline__ int dbscan_init(dbtxn *tx, dbscan *scan, dbindex *db, MDB_dbi primary, ez_blob_desc *desc, void (*decode_raw)(const ez_blob *blob, void *p)) {
-       scan->db = db;
-       scan->primary = primary;
+static void *dbscan_secondary_first(dbtxn *tx, dbscan *scan, dbindex *db, MDB_dbi primary, MDB_dbi secondary, ez_blob_desc *desc, void (*decode_raw)(const ez_blob *blob, void *p), MDB_cursor_op first) {
        scan->tx = tx;
+       scan->primary = primary;
        scan->DESC = desc;
        scan->decode_raw = decode_raw;
+       scan->mode = 1;
 
-       scan->res = mdb_cursor_open(tx, primary, &scan->cursor);
-
-       return scan->res;
-}
-
-static __inline__ void dbscan_init_key(dbscan *scan, dbid_t keyid) {
-       scan->keyid = keyid;
-       scan->key.mv_data = &scan->keyid;
-       scan->key.mv_size = sizeof(scan->keyid);
-}
-
-static void *dbscan_decode(dbscan *scan) {
-       void *memory = calloc(scan->DESC->bd_offset, 1);
-
-       if (memory) {
-               scan->decode_raw((const ez_blob *)&scan->data, memory);
-               *(dbid_t *)memory = *(dbid_t *)scan->key.mv_data;
-       }
-       return memory;
-}
-
-static void dbscan_close2(dbscan *scan) {
-       if (scan->cursor)
-               mdb_cursor_close(scan->cursor);
-       memset(scan, 0, sizeof(*scan));
-}
-
-void dbscan_free(dbscan *scan) {
-       dbscan_close2(scan);
-}
+       if ((scan->res = mdb_cursor_open(tx, secondary, &scan->cursor)))
+               goto fail;
+       if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->dat, first)))
+               goto fail;
+       scan->key = scan->dat;
+       if ((scan->res = mdb_get(tx, primary, &scan->key, &scan->dat)))
+               goto fail;
 
-static void *dbscan_primary2(dbtxn *tx, dbscan *scan, dbindex *db, MDB_dbi primary, ez_blob_desc *desc, void (*decode_raw)(const ez_blob *blob, void *p), dbid_t keyid, MDB_cursor_op op) {
-       if (dbscan_init(tx, scan, db, primary, desc, decode_raw) == 0) {
-               dbscan_init_key(scan, keyid);
-               if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, op)) == 0)
-                       return dbscan_decode(scan);
-               dbscan_close2(scan);
-       }
+       return dbscan_decode(scan);
+fail:
        return NULL;
 }
 
-static void *dbscan_primary2_next(dbscan *scan) {
-       if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_NEXT)) == 0)
-               return dbscan_decode(scan);
+static void *dbscan_table_next(dbscan *scan) {
+       if (scan->mode == 0) {
+               if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->dat, MDB_NEXT)))
+                       goto fail;
+       } else {
+               if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->dat, MDB_NEXT_DUP)))
+                       goto fail;
+               scan->key = scan->dat;
+               if ((scan->res = mdb_get(scan->tx, scan->primary, &scan->key, &scan->dat)))
+                       goto fail;
+       }
 
+       return dbscan_decode(scan);
+fail:
        return NULL;
 }
 
 dbdisk *dbscan_disk(dbtxn *tx, dbscan *scan, dbindex *db, dbid_t diskid) {
-       return dbscan_primary2(tx, scan, db, db->disk, DBDISK_DESC, dbdisk_decode_raw, diskid, diskid == 0 ? MDB_FIRST : MDB_SET_RANGE);
+       scan->key.mv_data = &diskid;
+       scan->key.mv_size = sizeof(diskid);
+       return dbscan_primary_first(tx, scan, db, db->disk, DBDISK_DESC, dbdisk_decode_raw, diskid == 0 ? MDB_FIRST : MDB_SET_RANGE);
 }
 
 dbdisk *dbscan_disk_next(dbscan *scan) {
-       return dbscan_primary2_next(scan);
+       return dbscan_table_next(scan);
 }
 
 dbfile *dbscan_file(dbtxn *tx, dbscan *scan, dbindex *db, dbid_t fileid) {
-       return dbscan_primary2(tx, scan, db, db->file, DBFILE_DESC, dbfile_decode_raw, fileid, fileid == 0 ? MDB_FIRST : MDB_SET_RANGE);
+       scan->key.mv_data = &fileid;
+       scan->key.mv_size = sizeof(fileid);
+       return dbscan_primary_first(tx, scan, db, db->file, DBFILE_DESC, dbfile_decode_raw, fileid == 0 ? MDB_FIRST : MDB_SET_RANGE);
+}
+
+dbfile *dbscan_file_by_disk(dbtxn *tx, dbscan *scan, dbindex *db, dbid_t diskid) {
+       scan->key.mv_data = &diskid;
+       scan->key.mv_size = sizeof(diskid);
+       return dbscan_secondary_first(tx, scan, db, db->file, db->file_by_disk, DBFILE_DESC, dbfile_decode_raw, MDB_SET);
 }
 
 dbfile *dbscan_file_next(dbscan *scan) {
-       return dbscan_primary2_next(scan);
+       return dbscan_table_next(scan);
 }
 
 dblist *dbscan_list(dbtxn *tx, dbscan *scan, dbindex *db, dbid_t listid) {
-       return dbscan_primary2(tx, scan, db, db->list, DBLIST_DESC, dblist_decode_raw, listid, listid == 0 ? MDB_FIRST : MDB_SET_RANGE);
+       return dbscan_primary_first(tx, scan, db, db->list, DBLIST_DESC, dblist_decode_raw, listid == 0 ? MDB_FIRST : MDB_SET_RANGE);
 }
 
 dblist *dbscan_list_next(dbscan *scan) {
-       return dbscan_primary2_next(scan);
+       return dbscan_table_next(scan);
 }
 
 /**
@@ -2203,79 +2064,92 @@ dbfile *dbscan_list_entry(dbtxn *tx, dbscan *scan, dbindex *db, dblistcursor *in
        uint32_t seq = info->seq;
        dbid_t fileid = info->fileid;
 
+       scan->tx = tx;
+       scan->DESC = DBFILE_DESC;
+       scan->decode_raw = dbfile_decode_raw;
+       scan->primary = db->file;
+       scan->mode = 2;
        scan->list_entry = *info;
 
-       if (dbscan_init(tx, scan, db, db->file_by_list, DBFILE_DESC, dbfile_decode_raw) == 0) {
-               // TODO: perhaps if seq is non-zero and fileid is non-zero, lookup next entry of file
-               if (seq == 0 && fileid != 0) {
-                       struct dblistfile thing = { .listid = listid, .seq = seq };
-                       MDB_cursor *cursor;
+       if ((scan->res = mdb_cursor_open(tx, db->file_by_list, &scan->cursor)))
+               goto fail;
 
-                       dbscan_init_key(scan, fileid);
-                       scan->data.mv_data = &thing;
-                       scan->data.mv_size = sizeof(thing);
+       // TODO: perhaps if seq is non-zero and fileid is non-zero, lookup next entry of file
+       if (seq == 0 && fileid != 0) {
+               struct dblistfile thing = { .listid = listid, .seq = seq };
+               MDB_cursor *cursor;
 
-                       scan->res = mdb_cursor_open(tx, db->list_by_file, &cursor);
-                       if ((scan->res = mdb_cursor_get(cursor, &scan->key, &scan->data, MDB_GET_BOTH_RANGE)) == 0)
-                               seq = ((struct dblistfile *)scan->data.mv_data)->seq;
-                       else
-                               seq = -1;
+               scan->key = (MDB_val){ sizeof(fileid), &fileid };
+               scan->dat.mv_data = &thing;
+               scan->dat.mv_size = sizeof(thing);
+
+               if ((scan->res = mdb_cursor_open(tx, db->list_by_file, &cursor)))
+                       goto fail;
+               if ((scan->res = mdb_cursor_get(cursor, &scan->key, &scan->dat, MDB_GET_BOTH_RANGE)) == 0)
+                       seq = ((struct dblistfile *)scan->dat.mv_data)->seq;
+               else {
                        mdb_cursor_close(cursor);
+                       goto fail;
                }
+               mdb_cursor_close(cursor);
+       }
 
-               if (seq != -1) {
-                       struct dbfilelist thing = { .seq = seq };
+       struct dbfilelist thing = { .seq = seq };
 
-                       dbscan_init_key(scan, listid);
+       scan->key = (MDB_val){ sizeof(listid), &listid };
+       scan->dat.mv_data = &thing;
+       scan->dat.mv_size = sizeof(thing);
 
-                       scan->data.mv_data = &thing;
-                       scan->data.mv_size = sizeof(thing);
+       if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->dat, MDB_GET_BOTH_RANGE)))
+               goto fail;
 
-                       if ((scan->res = mdb_cursor_get(scan->cursor, &scan->key, &scan->data, MDB_GET_BOTH_RANGE)) == 0) {
-                               struct dbfilelist *value = scan->data.mv_data;
+       struct dbfilelist *value = scan->dat.mv_data;
 
-                               scan->list_entry.seq = value->seq;
-                               scan->list_entry.fileid = value->fileid;
+       scan->list_entry.seq = value->seq;
+       scan->list_entry.fileid = value->fileid;
 
-                               scan->key.mv_data = &scan->list_entry.fileid;
-                               scan->key.mv_size = sizeof(scan->list_entry.fileid);
+       scan->key.mv_data = &scan->list_entry.fileid;
+       scan->key.mv_size = sizeof(scan->list_entry.fileid);
 
-                               if ((scan->res = mdb_get(tx, db->file, &scan->key, &scan->data)) == 0) {
-                                       dbfile *file = dbscan_decode(scan);
+       if ((scan->res = mdb_get(tx, db->file, &scan->key, &scan->dat)))
+               goto fail;
 
-                                       if (file) {
-                                               info->seq = scan->list_entry.seq;
-                                               info->fileid = scan->list_entry.fileid;
-                                               return file;
-                                       }
-                               }
-                       }
-               }
+       dbfile *file = dbscan_decode(scan);
+
+       if (file) {
+               info->seq = scan->list_entry.seq;
+               info->fileid = scan->list_entry.fileid;
+               return file;
        }
+fail:
        return NULL;
 }
 
 static dbfile *scan_list_entry_next(dbscan *scan, dblistcursor *info, MDB_cursor_op next0, MDB_cursor_op next1) {
-       dbfile *file;
-       MDB_val key, data;
+       MDB_val key, dat;
 
-       if ((scan->res = mdb_cursor_get(scan->cursor, &key, &data, next1)) == 0) {
-               struct dbfilelist *value = data.mv_data;
+       if ((scan->res = mdb_cursor_get(scan->cursor, &key, &dat, next1)))
+               goto fail;
 
-               scan->list_entry.seq = value->seq;
-               scan->list_entry.fileid = value->fileid;
+       struct dbfilelist *value = dat.mv_data;
 
-               scan->key.mv_data = &scan->list_entry.fileid;
-               scan->key.mv_size = sizeof(scan->list_entry.fileid);
+       scan->list_entry.seq = value->seq;
+       scan->list_entry.fileid = value->fileid;
 
-               if ((scan->res = mdb_get(scan->tx, scan->db->file, &scan->key, &scan->data)) == 0
-                       && (file = dbscan_decode(scan))) {
-                       info->seq = scan->list_entry.seq;
-                       info->fileid = scan->list_entry.fileid;
-                       return file;
-               }
-       }
+       scan->key.mv_data = &scan->list_entry.fileid;
+       scan->key.mv_size = sizeof(scan->list_entry.fileid);
 
+       if ((scan->res = mdb_get(scan->tx, scan->primary, &scan->key, &scan->dat)))
+               goto fail;
+
+       dbfile *file = dbscan_decode(scan);
+
+       if (file) {
+               info->seq = scan->list_entry.seq;
+               info->fileid = scan->list_entry.fileid;
+               return file;
+       }
+fail:
        return NULL;
 }
 
@@ -2287,39 +2161,6 @@ dbfile *dbscan_list_entry_prev(dbscan *scan, dblistcursor *info) {
        return scan_list_entry_next(scan, info, MDB_PREV, MDB_PREV_DUP);
 }
 
-
-/* legacy */
-
-
-dbscan *dbfile_scan_disk(dbtxn *tx, dbindex *db, int diskid) {
-       return dbscan_secondary(tx, db, db->file_by_disk, diskid);
-}
-
-uint32_t dbfile_scan_next(dbscan *scan) {
-       return dbscan_secondary_next(scan);
-}
-
-// TBD
-void dbfile_scan_close(dbscan *scan) {
-       dbscan_close(scan);
-}
-
-dbscan *dbdisk_scan(dbtxn *tx, dbindex *db, int diskid) {
-       return dbscan_primary(tx, db, db->disk, diskid);
-}
-
-dbdisk *dbdisk_next(dbscan *scan) {
-       dbdisk *disk = NULL;
-
-       if (dbscan_primary_next(scan)) {
-               disk = ez_basic_decode(DBDISK_DESC, (ez_blob *)&scan->data);
-               if (disk)
-                       disk->id = *(int *)scan->key.mv_data;
-       }
-
-       return disk;
-}
-
 // prototyping
 int dbfile_clear_suffix(MDB_txn *tx, dbindex *db) {
        return mdb_drop(tx, db->file_by_suffix, 0);
@@ -2390,31 +2231,57 @@ static int cmp_fid(const void *ap, const void *bp) {
        return *(const int32_t *)ap - *(const int32_t *)bp;
 }
 
+
 /* protoyping */
-void dbindex_validate(dbindex *db) {
+
+static int check_path(const dbfile *file, const MDB_val *key) {
+       char tmp[16];
+       sprintf(tmp, "%08x", file->diskid);
+       return key->mv_size == strlen(file->path) + 8
+               && memcmp(tmp, key->mv_data, 8) == 0
+               && memcmp(file->path, key->mv_data + 8, key->mv_size - 8) == 0;
+}
+static int check_diskid(const dbfile *file, const MDB_val *key) {
+       return key->mv_size == sizeof(dbid_t)
+               && *(dbid_t*)key->mv_data == file->diskid;
+}
+static int check_title(const dbfile *file, const MDB_val *key) {
+       return key->mv_size == strlen(file->title)
+               && memcmp(file->title, key->mv_data, key->mv_size) == 0;
+}
+static int check_artist(const dbfile *file, const MDB_val *key) {
+       return key->mv_size == strlen(file->artist)
+               && memcmp(file->artist, key->mv_data, key->mv_size) == 0;
+}
+static int check_dir(const dbfile *file, const MDB_val *key) {
+       char *slash = strrchr(file->path, '/');
+       char tmp[16];
+       sprintf(tmp, "%08x", file->diskid);
+       return slash != NULL
+               && key->mv_size == (slash - file->path) + 8
+               && memcmp(tmp, key->mv_data, 8) == 0
+               && memcmp(file->path, key->mv_data + 8, (slash - file->path)) == 0;
+}
+
+int dbindex_validate(dbindex *db) {
        MDB_txn *tx;
        MDB_val key, data;
        MDB_cursor *cursor;
        int res;
+       int ok = 1;
 
        mdb_txn_begin(db->env, NULL, MDB_RDONLY, &tx);
 
-       size_t alloc = 4096;
-       uint32_t *fids = malloc(sizeof(*fids) * alloc);
-       size_t fids_size = 0;
-
+       ez_array array = { 0 };
        // All files
        mdb_cursor_open(tx, db->file, &cursor);
-       int next = MDB_FIRST;
-       while ((res = mdb_cursor_get(cursor, &key, &data, next)) == 0) {
-               if (fids_size >= alloc) {
-                       alloc *= 2;
-                       fids = realloc(fids, sizeof(*fids) * alloc);
-               }
-               fids[fids_size++] = *(uint32_t *)key.mv_data;
-               next = MDB_NEXT;
-       }
+       for (int next = MDB_FIRST; (res = mdb_cursor_get(cursor, &key, &data, next)) == 0; next = MDB_NEXT)
+               ez_array_add(&array, key.mv_data, key.mv_size);
        mdb_cursor_close(cursor);
+
+       uint32_t *fids = array.ea_data;
+       size_t fids_size = array.ea_size / sizeof(*fids);
+
        printf("read %zd files\n", fids_size);
        qsort(fids, fids_size, sizeof(*fids), cmp_fid);
 
@@ -2424,11 +2291,19 @@ void dbindex_validate(dbindex *db) {
                db->file_by_disk,
                db->file_by_title,
                db->file_by_artist,
+               db->file_by_dir,
+       };
+       int (*checks[])(const dbfile *file, const MDB_val *key) = {
+               check_path,
+               check_diskid,
+               check_title,
+               check_artist,
+               check_dir
        };
 
        for (int i=0;i<4;i++) {
                size_t count = 0;
-               printf("table %d\n", i);
+               //printf("table %d\n", i);
                mdb_cursor_open(tx, tables[i], &cursor);
                res = mdb_cursor_get(cursor, &key, &data, MDB_FIRST);
                while (res == 0) {
@@ -2438,18 +2313,34 @@ void dbindex_validate(dbindex *db) {
 
                        if (!bsearch(&fid, fids, fids_size, sizeof(*fids), cmp_fid)) {
                                printf("table %d references missing file\n", i);
+                               ok = 0;
+                       }
+                       {
+                               dbfile *file = dbfile_get(tx, db, fid);
+                               if (file) {
+                                       if (!checks[i](file, &key)) {
+                                               printf("failed field check %d\n", i);
+                                               ok = 0;
+                                       }
+                               } else {
+                                       ok = 0;
+                               }
+                               dbfile_free(file);
                        }
-
                        res = mdb_cursor_get(cursor, &key, &data, MDB_NEXT_DUP);
                        if (res == MDB_NOTFOUND)
                                res = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
                }
                mdb_cursor_close(cursor);
 
-               if (i == 0 && count != fids_size) {
-                       printf("file by path miscount %zd != %zd\n", count, fids_size);
+               if (i <= 1 && count != fids_size) {
+                       printf("file by [thing] miscount %zd != %zd\n", count, fids_size);
+                       ok = 0;
                }
        }
 //fail:
+       ez_array_clear(&array);
        dbindex_abort(tx);
+
+       return ok;
 }
index 835c7f0..b13e12c 100644 (file)
--- a/dbindex.h
+++ b/dbindex.h
@@ -145,11 +145,6 @@ int dbfile_inlist(dbtxn *tx, dbindex *db, dbid_t fileid, dbid_t listid);
 void dbfile_node_free(struct dbfile_node *p);
 int dbfile_node_scan_path(dbtxn *tx, dbindex *db, dbid_t diskid, const char *path, ez_tree *tree);
 
-// TBD?  seems not
-dbscan *dbfile_scan_disk(dbtxn *tx, dbindex *db, int diskid);
-uint32_t dbfile_scan_next(dbscan *scan);
-void dbfile_scan_close(dbscan *scan);
-
 extern ez_blob_desc DBDISK_DESC[];
 extern ez_blob_desc DBFILE_DESC[];
 extern ez_blob_desc DBLIST_DESC[];
@@ -158,11 +153,6 @@ extern ez_blob_desc DBLIST_DESC[];
 int dbfile_next(dbindex *db, dbfile **f, char **fpath);
 int dbfile_prev(dbindex *db, dbfile **f, char **fpath);
 
-//void dbshuffle_init(dbindex *db);
-
-//int dbfile_next_shuffle(dbindex *db, dbfile **f, char **fpath);
-//int dbfile_prev_shuffle(dbindex *db, dbfile **f, char **fpath);
-
 dblist *dblist_get(dbtxn *tx, dbindex *db, int id);
 dblist *dblist_get_name(dbtxn *tx, dbindex *db, const char *name);
 void dblist_free(dblist *f);
@@ -180,51 +170,25 @@ int dblist_update_all(dbtxn *tx, dbindex *db);
 // delete all lists and run update_all
 int dblist_reset_all(dbtxn *tx, dbindex *db);
 
-
-//int dbfile_next_list(dbindex *db, int listid, dbfile **fp);
-//int dbfile_prev_list(dbindex *db, int listid, dbfile **fp);
-
 int dbfile_search(dbindex *db, const char *pattern, dbfile **results, int maxlen);
 
-// scanning routines, to be expanded for other search routines?
-//dbscan *dbdisk_scan(dbtxn *tx, dbindex *db, int diskid);
-//dbdisk *dbdisk_next(dbscan *scan);
-
-//dbscan *dblist_scan(dbtxn *tx, dbindex *db, int listid);
-//const dblist *dblist_next(dbscan *scan);
-void dbscan_close(dbscan *scan);
-
 // prototyping
 int dbfile_put_suffix(dbtxn *tx, dbindex *db, const char *suffix, uint32_t fileid);
 size_t dbfile_search_substring(dbtxn *tx, dbindex *db, const char *sub);
 
-//int dblist_iterate(dbtxn *txn, dbindex *db, struct dblistcursor *pos);
-
-// another attempt ...
-//dbscan *dblist_file_scan(dbtxn *tx, dbindex *db, int listid, int seq, int fileid);
-//const dbfile *dblist_file_next(dbscan *scan, int *seq);
-
-
 /* re-usable scan code try two! */
 struct dbscan {
-       dbindex *db;
+       MDB_txn *tx;
        MDB_dbi primary;
-       MDB_dbi secondary; // ?
-       MDB_dbi table; // TBD
-       MDB_cursor *cursor;
-       MDB_val key, data;
-       int keyval; // TBD
-       int index;
-       int count;
+       const ez_blob_desc *DESC;
+       void (*decode_raw)(const ez_blob *blob, void *p);
 
-       MDB_txn *tx;
+       MDB_cursor *cursor;
+       MDB_val key, dat;
 
-       dbid_t keyid;
+       int mode;
        int res;
 
-       const ez_blob_desc *DESC;
-       void (*decode_raw)(const ez_blob *blob, void *p);
-
        union {
                struct dblistcursor list_entry;
        };
@@ -244,8 +208,5 @@ dblist *dbscan_list_next(dbscan *scan);
 dbfile *dbscan_list_entry(dbtxn *tx, dbscan *scan, dbindex *db, dblistcursor *cursor);
 dbfile *dbscan_list_entry_next(dbscan *scan, dblistcursor *info);
 dbfile *dbscan_list_entry_prev(dbscan *scan, dblistcursor *info);
-// these two TBD, its in the cursor now
-//int     dbscan_list_entry_seq(dbscan *scan);
-//dbid_t  dbscan_list_entry_listid(dbscan *scan);
 
 #define MAIN_INDEX NULL
index ff0f804..e2d8f0e 100644 (file)
@@ -54,7 +54,6 @@ struct indexer {
        int isnew;
 
        ez_list queue;
-       struct dirent *entry;
 
        // files to care about
        regex_t match;
@@ -93,9 +92,8 @@ static dbfile *scan_info(AVFormatContext *ic) {
 
        for (int i=0;!audio && i<ic->nb_streams;i++) {
                AVStream *s = ic->streams[i];
-               AVCodecContext *c = s->codec;
 
-               if (c->codec_type == AVMEDIA_TYPE_AUDIO) {
+               if (s->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
                        //printf("    audio: %s %dHz x%d %ld b/s\n",
                        //     avcodec_get_name(c->codec_id),
                        //     c->sample_rate,
@@ -193,12 +191,6 @@ int indexer_init(struct indexer *ix, dbindex *db, const char *path, const char *
        ez_list_init(&ix->queue);
        ez_list_addtail(&ix->queue, dir_new(path));
 
-       // find out how big dirent needs to be
-       int name_max = pathconf(path, _PC_NAME_MAX);
-
-       name_max = name_max == -1 ? 256 : name_max;
-       ix->entry = malloc(sizeof(struct dirent) - sizeof(ix->entry->d_name) + name_max + 1);
-
        ix->root = strdup(path);
 
        res = regcomp(&ix->match, "\\.(mp3|avi|mpeg|mp2|mpg|mp4|mov)$", REG_ICASE | REG_NOSUB | REG_EXTENDED);
@@ -251,7 +243,6 @@ void indexer_destroy(struct indexer *ix) {
        while ((scan = ez_list_remhead(&ix->queue)))
                dir_free(scan);
 
-       free(ix->entry);
        free(ix->root);
        regfree(&ix->match);
 }
@@ -375,12 +366,12 @@ int indexer_scan(struct indexer *ix) {
                        goto fail;
                printf("existing: %d\n", ez_tree_size(&files));
 
-               DIR *d = opendir(scan->path);
-               if (d) {
+               DIR *dir = opendir(scan->path);
+               if (dir) {
                        struct dirent *ep;
                        int dots = 0;
 
-                       while (readdir_r(d, ix->entry, &ep) == 0 && ep) {
+                       while ((ep = readdir(dir))) {
                                if (strcmp(ep->d_name, ".") == 0
                                    || strcmp(ep->d_name, "..") == 0) {
                                        // Hack: remove a usb disk while scanning can cause this to loop
@@ -400,14 +391,14 @@ int indexer_scan(struct indexer *ix) {
                                printf(" %s\n", name);
 
 #ifdef HAVE_FSTATAT
-                               res = fstatat(dirfd(d), ep->d_name, &st, AT_SYMLINK_NOFOLLOW);
+                               res = fstatat(dirfd(dir), ep->d_name, &st, AT_SYMLINK_NOFOLLOW);
 #else
                                res = lstat(name, &st);
 #endif
                                if (res == 0) {
                                        if (S_ISREG(st.st_mode)) {
                                                if (regexec(&ix->match, ep->d_name, 0, NULL, 0) == 0) {
-                                                       if (res = indexer_add_file(ix, &st, name, name + strlen(ix->root), &files))
+                                                       if ((res = indexer_add_file(ix, &st, name, name + strlen(ix->root), &files)))
                                                                goto fail;
                                                        count++;
                                                        if ((count % 1000) == 0)
@@ -424,7 +415,7 @@ int indexer_scan(struct indexer *ix) {
                                                goto fail;
                                }
                        }
-                       closedir(d);
+                       closedir(dir);
                } else {
                        printf("open '%s': %s\n", scan->path, strerror(errno));
                        if (errno == EIO)
index 67a4d6a..aea79d7 100644 (file)
@@ -308,7 +308,7 @@ static void partition_check(struct monitor *m) {
 
                fstat(dfd, &dstat);
 
-               while (e = readdir(dir)) {
+               while ((e = readdir(dir))) {
                        if (fstatat(dfd, e->d_name, &estat, AT_SYMLINK_NOFOLLOW) == 0
                            && S_ISDIR(estat.st_mode)
                            && dstat.st_dev != estat.st_dev) {
@@ -327,7 +327,7 @@ static void partition_check(struct monitor *m) {
                if (!ez_list_empty(&old)){
                        dir = opendir("/dev");
                        dfd = dirfd(dir);
-                       while (e = readdir(dir)) {
+                       while ((e = readdir(dir))) {
                                if (fstatat(dfd, e->d_name, &estat, AT_SYMLINK_NOFOLLOW) == 0) {
                                        // check if starts with sd?
                                        struct oldnode *w, *n;
index 0fbdb92..a6a0a9e 100644 (file)
@@ -169,31 +169,6 @@ void search_suffix(const char *path) {
 
 /* ********************************************************************** */
 
-// some basic consistency checking
-// see also dbindex_validate, need to be merged
-static void check(dbindex *db) {
-       printf("Check file-by-diskid index\n");
-       dbtxn *tx = dbindex_begin(db, NULL, 1);
-       dbscan *scan = dbfile_scan_disk(tx, db, -1);
-       uint32_t fid;
-       int count =0;
-
-       while ((fid = dbfile_scan_next(scan)) != ~0) {
-               dbfile *f = dbfile_get(tx, db, fid);
-               if (f == NULL) {
-                       printf(" %d missing\n", fid);
-               } else {
-                       printf(" in %d\n", fid);
-               }
-               dbfile_free(f);
-               count++;
-       }
-       printf("total %d\n", count);
-       dbfile_scan_close(scan);
-}
-
-/* ********************************************************************** */
-
 int main(int argc, char **argv) {
        const char *dbdir = MAIN_INDEX;
        dbid_t diskid = 0;
@@ -223,7 +198,7 @@ int main(int argc, char **argv) {
                } else if (strcmp(cmd, "-l") == 0) {
                        info.listid = atoi(argv[++i]);
                } else if (strcmp(cmd, "check") == 0) {
-                       check(db);
+                       //check(db);
                } else if (strcmp(cmd, "shuffle") == 0) {
                        //dbshuffle_init2(db);
                } else if (strcmp(cmd, "file-dump") == 0) {
index 0c4188d..9f70b25 100644 (file)
@@ -790,7 +790,7 @@ int audio_goto_file(struct audio_player *ap, dblistcursor *info) {
                goto fail;
        }
 
-       if (res = audio_init_media(ap, dbfile_full_path(tx, ap->index, file)))
+       if ((res = audio_init_media(ap, dbfile_full_path(tx, ap->index, file))))
                goto fail;
 
        ap->playing = file;