summaryrefslogtreecommitdiffstats
path: root/fs/jffs2/mergesort.c
diff options
context:
space:
mode:
authorMark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>2015-07-01 16:38:29 +1200
committerTom Rini <trini@konsulko.com>2015-08-12 20:47:32 -0400
commit10d3ac346f54ab9526cd352239a5906ee2b92fee (patch)
treec3dc2f4c0df60a876aba4de9b962bd84d6b570e5 /fs/jffs2/mergesort.c
parent54a883840be500cbcda4903118dd571e4532e83f (diff)
downloadtalos-obmc-uboot-10d3ac346f54ab9526cd352239a5906ee2b92fee.tar.gz
talos-obmc-uboot-10d3ac346f54ab9526cd352239a5906ee2b92fee.zip
JFFS2: Use merge sort when parsing filesystem
When building the file system the existing code does an insertion into a linked list. It attempts to speed this up by keeping a pointer to where the last entry was inserted but it's still slow. Now the nodes are just inserted into the list without searching through for the correct place. This unsorted list is then sorted once using mergesort after all the entries have been added to the list. This speeds up the scanning of the flash file system considerably. Signed-off-by: Mark Tomlinson <mark.tomlinson@alliedtelesis.co.nz>
Diffstat (limited to 'fs/jffs2/mergesort.c')
-rw-r--r--fs/jffs2/mergesort.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/fs/jffs2/mergesort.c b/fs/jffs2/mergesort.c
new file mode 100644
index 0000000000..6e633a1133
--- /dev/null
+++ b/fs/jffs2/mergesort.c
@@ -0,0 +1,52 @@
+/*
+ * This file is copyright 2001 Simon Tatham.
+ * Rewritten from original source 2006 by Dan Merillat for use in u-boot.
+ *
+ * Original code can be found at:
+ * http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html
+ *
+ * SPDX-License-Identifier: MIT
+ */
+
+#include <common.h>
+#include "jffs2_private.h"
+
+int sort_list(struct b_list *list)
+{
+ struct b_node *p, *q, *e, **tail;
+ int k, psize, qsize;
+
+ if (!list->listHead)
+ return 0;
+
+ for (k = 1; k < list->listCount; k *= 2) {
+ tail = &list->listHead;
+ for (p = q = list->listHead; p; p = q) {
+ /* step 'k' places from p; */
+ for (psize = 0; q && psize < k; psize++)
+ q = q->next;
+ qsize = k;
+
+ /* two lists, merge them. */
+ while (psize || (qsize && q)) {
+ /* merge the next element */
+ if (psize == 0 ||
+ ((qsize && q) &&
+ list->listCompare(p, q))) {
+ /* p is empty, or p > q, so q next */
+ e = q;
+ q = q->next;
+ qsize--;
+ } else {
+ e = p;
+ p = p->next;
+ psize--;
+ }
+ e->next = NULL; /* break accidental loops. */
+ *tail = e;
+ tail = &e->next;
+ }
+ }
+ }
+ return 0;
+}
OpenPOWER on IntegriCloud