Fixes for record cluster merge, PAZ-901
authorAdam Dickmeiss <adam@indexdata.dk>
Tue, 3 Dec 2013 12:05:23 +0000 (13:05 +0100)
committerAdam Dickmeiss <adam@indexdata.dk>
Tue, 3 Dec 2013 12:05:23 +0000 (13:05 +0100)
src/reclists.c
src/record.h

index 00133ed..5822dbe 100644 (file)
@@ -36,8 +36,8 @@ struct reclist
     unsigned hash_size;
 
     int num_records;
-    struct reclist_bucket *sorted_list;
-    struct reclist_bucket *sorted_ptr;
+    struct record_cluster *sorted_list;
+    struct record_cluster *sorted_ptr;
     NMEM nmem;
     YAZ_MUTEX mutex;
 };
@@ -46,8 +46,6 @@ struct reclist_bucket
 {
     struct record_cluster *record;
     struct reclist_bucket *hash_next;
-    struct reclist_bucket *sorted_next;
-    struct reclist_sortparms *sort_parms;
 };
 
 static void append_merge_keys(struct record_metadata_attr **p,
@@ -162,10 +160,9 @@ struct reclist_sortparms *reclist_parse_sortparms(NMEM nmem, const char *parms,
 
 static int reclist_cmp(const void *p1, const void *p2)
 {
-    struct reclist_sortparms *sortparms =
-        (*(struct reclist_bucket **) p1)->sort_parms;
-    struct record_cluster *r1 = (*(struct reclist_bucket**) p1)->record;
-    struct record_cluster *r2 = (*(struct reclist_bucket**) p2)->record;
+    struct record_cluster *r1 = (*(struct record_cluster**) p1);
+    struct record_cluster *r2 = (*(struct record_cluster**) p2);
+    struct reclist_sortparms *sortparms = r1->sort_parms;
     struct reclist_sortparms *s;
     int res = 0;
 
@@ -233,7 +230,7 @@ void reclist_limit(struct reclist *l, struct session *se, int lazy)
 {
     unsigned i;
     int num = 0;
-    struct reclist_bucket **pp = &l->sorted_list;
+    struct record_cluster **pp = &l->sorted_list;
 
     reclist_enter(l);
 
@@ -243,12 +240,22 @@ void reclist_limit(struct reclist *l, struct session *se, int lazy)
         {
             struct reclist_bucket *p;
             for (p = l->hashtable[i]; p; p = p->hash_next)
+                p->record->sorted_next = 0;
+        }
+        for (i = 0; i < l->hash_size; i++)
+        {
+            struct reclist_bucket *p;
+            for (p = l->hashtable[i]; p; p = p->hash_next)
             {
                 if (session_check_cluster_limit(se, p->record))
                 {
-                    *pp = p;
-                    pp = &p->sorted_next;
-                    num++;
+                    if (!p->record->sorted_next)
+                    {
+                        *pp = p->record;
+                        pp = &p->record->sorted_next;
+                        *pp = p->record; /* signal already in use */
+                        num++;
+                    }
                 }
             }
         }
@@ -260,9 +267,9 @@ void reclist_limit(struct reclist *l, struct session *se, int lazy)
 
 void reclist_sort(struct reclist *l, struct reclist_sortparms *parms)
 {
-    struct reclist_bucket **flatlist = xmalloc(sizeof(*flatlist) * l->num_records);
-    struct reclist_bucket *ptr;
-    struct reclist_bucket **prev;
+    struct record_cluster **flatlist = xmalloc(sizeof(*flatlist) * l->num_records);
+    struct record_cluster *ptr;
+    struct record_cluster **prev;
     int i = 0;
 
     reclist_enter(l);
@@ -295,7 +302,7 @@ struct record_cluster *reclist_read_record(struct reclist *l)
 {
     if (l && l->sorted_ptr)
     {
-        struct record_cluster *t = l->sorted_ptr->record;
+        struct record_cluster *t = l->sorted_ptr;
         l->sorted_ptr = l->sorted_ptr->sorted_next;
         return t;
     }
@@ -369,11 +376,24 @@ static void merge_cluster(struct reclist *l,
                           struct record_cluster *dst,
                           struct record_cluster *src)
 {
+    struct record_metadata_attr *mkl;
     struct record **rp = &dst->records;
     for (; *rp; rp = &(*rp)->next)
         ;
     *rp = src->records;
 
+    for (mkl = src->merge_keys; mkl; mkl = mkl->next)
+    {
+        const char *merge_key = mkl->value;
+        unsigned int bucket =
+            jenkins_hash((unsigned char*) merge_key) % l->hash_size;
+        struct reclist_bucket *p;
+
+        for (p = l->hashtable[bucket]; p; p = p->hash_next)
+            if (p->record == src)
+                p->record = dst;
+    }
+
     /* not merging metadata and sortkeys yet */
 
     relevance_mergerec(r, dst, src);
@@ -477,23 +497,16 @@ struct record_cluster *reclist_insert(struct reclist *l,
                         cluster = rb->record;
                         *re = record;
                         record->next = 0;
+                        yaz_log(YLOG_LOG, "reclist: record insert %p", cluster);
                     }
                     else
                     {
                         if (cluster != rb->record)
                         {
-                            if (!rb->record->records)
-                            {
-                                ; /* already merged */
-                            }
-                            else
-                            {
-                                merge_cluster(l, r, cluster, rb->record);
-
-                                rb->record->records = 0; /* signal merged */
-                            }
-                            /* update the hash table */
-                            rb->record = cluster;
+                            assert(rb->record->relevance_explain1);
+                            yaz_log(YLOG_LOG, "reclist: cluster merge %p %p", cluster, rb->record);
+                            merge_cluster(l, r, cluster, rb->record);
+                            (*total)--;
                         }
                     }
                 }
@@ -503,6 +516,7 @@ struct record_cluster *reclist_insert(struct reclist *l,
         {
             (*total)++;
             cluster = new_cluster(l, r, service, record, merge_keys);
+            yaz_log(YLOG_LOG, "reclist: new cluster p=%p", cluster);
         }
 
         if (!rb)
index fc01b5c..b06ad14 100644 (file)
@@ -93,6 +93,8 @@ struct record_cluster
     WRBUF relevance_explain1;
     WRBUF relevance_explain2;
     struct record *records;
+    struct record_cluster *sorted_next;
+    struct reclist_sortparms *sort_parms;
 };
 
 #endif // RECORD_H