diffcore-order: export generic ordering interface

diffcore_order() interface only accepts a queue of `struct diff_filepair`. In the next patches, we'll want to order `struct combine_diff_path` by path, so let's first rework diffcore-order to also provide generic low-level interface for ordering arbitrary objects, provided they have path accessors. The new interface is: - `struct obj_order` for describing objects to ordering routine, and - order_objects() for actually doing the ordering work. Signed-off-by: Kirill Smelkov <kirr@mns.spb.ru> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kirill Smelkov committed Jan 20, 2014 at 20:20 UTC 1df4320fa25d3784b035936b35725460d46f1ca0
2 files changed +46 -19
diffcore-order.c
+32 -19
@@ -57,12 +57,6 @@ static void prepare_order(const char *orderfile)
57 }
58 }
59
60 -struct pair_order {
61 - struct diff_filepair *pair;
62 - int orig_order;
63 - int order;
64 -};
65 -
60 static int match_order(const char *path)
61 {
62 int i;
@@ -84,35 +78,54 @@ static int match_order(const char *path)
78 return order_cnt;
79 }
80
87 -static int compare_pair_order(const void *a_, const void *b_)
81 +static int compare_objs_order(const void *a_, const void *b_)
82 {
89 - struct pair_order const *a, *b;
90 - a = (struct pair_order const *)a_;
91 - b = (struct pair_order const *)b_;
83 + struct obj_order const *a, *b;
84 + a = (struct obj_order const *)a_;
85 + b = (struct obj_order const *)b_;
86 if (a->order != b->order)
87 return a->order - b->order;
88 return a->orig_order - b->orig_order;
89 }
90
91 +void order_objects(const char *orderfile, obj_path_fn_t obj_path,
92 + struct obj_order *objs, int nr)
93 +{
94 + int i;
95 +
96 + if (!nr)
97 + return;
98 +
99 + prepare_order(orderfile);
100 + for (i = 0; i < nr; i++) {
101 + objs[i].orig_order = i;
102 + objs[i].order = match_order(obj_path(objs[i].obj));
103 + }
104 + qsort(objs, nr, sizeof(*objs), compare_objs_order);
105 +}
106 +
107 +static const char *pair_pathtwo(void *obj)
108 +{
109 + struct diff_filepair *pair = (struct diff_filepair *)obj;
110 +
111 + return pair->two->path;
112 +}
113 +
114 void diffcore_order(const char *orderfile)
115 {
116 struct diff_queue_struct *q = &diff_queued_diff;
100 - struct pair_order *o;
117 + struct obj_order *o;
118 int i;
119
120 if (!q->nr)
121 return;
122
123 o = xmalloc(sizeof(*o) * q->nr);
107 - prepare_order(orderfile);
108 - for (i = 0; i < q->nr; i++) {
109 - o[i].pair = q->queue[i];
110 - o[i].orig_order = i;
111 - o[i].order = match_order(o[i].pair->two->path);
112 - }
113 - qsort(o, q->nr, sizeof(*o), compare_pair_order);
124 for (i = 0; i < q->nr; i++)
115 - q->queue[i] = o[i].pair;
125 + o[i].obj = q->queue[i];
126 + order_objects(orderfile, pair_pathtwo, o, q->nr);
127 + for (i = 0; i < q->nr; i++)
128 + q->queue[i] = o[i].obj;
129 free(o);
130 return;
131 }
diffcore.h
+14
@@ -109,6 +109,20 @@ extern void diffcore_merge_broken(void);
109 extern void diffcore_pickaxe(struct diff_options *);
110 extern void diffcore_order(const char *orderfile);
111
112 +/* low-level interface to diffcore_order */
113 +struct obj_order {
114 + void *obj; /* setup by caller */
115 +
116 + /* setup/used by order_objects() */
117 + int orig_order;
118 + int order;
119 +};
120 +
121 +typedef const char *(*obj_path_fn_t)(void *obj);
122 +
123 +void order_objects(const char *orderfile, obj_path_fn_t obj_path,
124 + struct obj_order *objs, int nr);
125 +
126 #define DIFF_DEBUG 0
127 #if DIFF_DEBUG
128 void diff_debug_filespec(struct diff_filespec *, int, const char *);