Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package parti for openSUSE:Factory checked 
in at 2026-03-19 17:38:30
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/parti (Old)
 and      /work/SRC/openSUSE:Factory/.parti.new.8177 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "parti"

Thu Mar 19 17:38:30 2026 rev:20 rq:1341017 version:2.11

Changes:
--------
--- /work/SRC/openSUSE:Factory/parti/parti.changes      2025-05-14 
17:01:10.911178618 +0200
+++ /work/SRC/openSUSE:Factory/.parti.new.8177/parti.changes    2026-03-19 
17:39:15.322478383 +0100
@@ -1,0 +2,7 @@
+Wed Mar 18 17:49:42 UTC 2026 - [email protected]
+
+- merge gh#wfeldt/parti#24
+- greatly speed up internal disk data handling
+- 2.11
+
+--------------------------------------------------------------------

Old:
----
  parti-2.10.tar.xz

New:
----
  parti-2.11.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ parti.spec ++++++
--- /var/tmp/diff_new_pack.rsQlZJ/_old  2026-03-19 17:39:15.806498438 +0100
+++ /var/tmp/diff_new_pack.rsQlZJ/_new  2026-03-19 17:39:15.810498604 +0100
@@ -18,7 +18,7 @@
 
 
 Name:           parti
-Version:        2.10
+Version:        2.11
 Release:        0
 Summary:        Show partition table information
 License:        GPL-3.0-only

++++++ parti-2.10.tar.xz -> parti-2.11.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parti-2.10/VERSION new/parti-2.11/VERSION
--- old/parti-2.10/VERSION      2025-05-13 18:30:52.000000000 +0200
+++ new/parti-2.11/VERSION      2026-03-18 18:49:42.000000000 +0100
@@ -1 +1 @@
-2.10
+2.11
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parti-2.10/changelog new/parti-2.11/changelog
--- old/parti-2.10/changelog    2025-05-13 18:30:52.000000000 +0200
+++ new/parti-2.11/changelog    2026-03-18 18:49:42.000000000 +0100
@@ -1,3 +1,7 @@
+2026-03-18:    2.11
+       - merge gh#wfeldt/parti#24
+       - greatly speed up internal disk data handling
+
 2025-05-13:    2.10
        - merge gh#wfeldt/parti#23
        - fix build for older gcc versions
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parti-2.10/disk.c new/parti-2.11/disk.c
--- old/parti-2.10/disk.c       2025-05-13 18:30:52.000000000 +0200
+++ new/parti-2.11/disk.c       2026-03-18 18:49:42.000000000 +0100
@@ -23,19 +23,21 @@
 
 int disk_read(disk_t *disk, void *buffer, uint64_t block_nr, unsigned count)
 {
-  unsigned factor = disk->block_size / disk->chunk_size;
+  unsigned factor = disk->block_size / DISK_CHUNK_SIZE;
 
   // fprintf(stderr, "read: %llu - %u (factor = %u)\n", (unsigned long long) 
block_nr, count, factor);
 
+  uint64_t chunk_nr = block_nr * factor;
+
   count *= factor;
-  block_nr *= factor;
 
-  for(unsigned u = 0; u < count; u++, block_nr++, buffer += disk->chunk_size) {
-    // fprintf(stderr, "read request: disk %u, addr %08"PRIx64"\n", 
disk->index, block_nr * disk->chunk_size);
-    if(!disk_cache_read(disk, buffer, block_nr)) {
-      int err = disk_read_single(disk, buffer, block_nr);
+  for(unsigned u = 0; u < count; u++, chunk_nr++, buffer += DISK_CHUNK_SIZE) {
+    // fprintf(stderr, "read request: disk %u, addr %08"PRIx64"\n", 
disk->index, chunk_nr * DISK_CHUNK_SIZE);
+    if(disk_cache_read(disk, &(disk_chunk_t) { .nr = chunk_nr, .data = buffer 
})) {
+      int err = disk_read_single(disk, buffer, chunk_nr);
+      if(err) return err;
+      err = disk_cache_store(disk, &(disk_chunk_t) { .nr = chunk_nr, .data = 
buffer });
       if(err) return err;
-      disk_cache_store(disk, buffer, block_nr);
     }
   }
 
@@ -46,15 +48,15 @@
 int disk_read_single(disk_t *disk, void *buffer, uint64_t block_nr)
 {
   if(disk->fd == -1) {
-    // fprintf(stderr, "cache miss: disk %u, addr %08"PRIx64"\n", disk->index, 
block_nr * disk->chunk_size);
-    memset(buffer, 0, disk->chunk_size);
+    // fprintf(stderr, "cache miss: disk %u, addr %08"PRIx64"\n", disk->index, 
block_nr * DISK_CHUNK_SIZE);
+    memset(buffer, 0, DISK_CHUNK_SIZE);
 
     return 0;
   }
 
   // fprintf(stderr, "read: %llu[%llu]\n", (unsigned long long) block_nr, 
(unsigned long long) disk->size);
 
-  off_t offset = block_nr * disk->chunk_size;
+  off_t offset = block_nr * DISK_CHUNK_SIZE;
 
   if(lseek(disk->fd, offset, SEEK_SET) != offset) {
     fprintf(stderr, "sector %"PRIu64" not found\n", block_nr);
@@ -62,7 +64,7 @@
     return 2;
   }
 
-  if(read(disk->fd, buffer, disk->chunk_size) != disk->chunk_size) {
+  if(read(disk->fd, buffer, DISK_CHUNK_SIZE) != DISK_CHUNK_SIZE) {
     fprintf(stderr, "error reading sector %"PRIu64"\n", block_nr);
 
     return 3;
@@ -72,30 +74,96 @@
 }
 
 
-int disk_cache_read(disk_t *disk, void *buffer, uint64_t chunk_nr)
+int disk_cache_read(disk_t *disk, disk_chunk_t *chunk)
 {
-  for(disk_data_t *disk_data = disk->data; disk_data; disk_data = 
disk_data->next) {
-    if(disk_data->chunk_nr == chunk_nr) {
-      memcpy(buffer, disk_data->data, disk->chunk_size);
-      return 1;
+  if(!chunk || !chunk->data || chunk->nr == UINT64_MAX) return 1;
+
+  int match;
+  unsigned u = disk_find_chunk(disk, chunk->nr, &match);
+
+  if(!match) return 2;
+
+  memcpy(chunk->data, disk->chunks.list[u].data, DISK_CHUNK_SIZE);
+
+  return 0;
+}
+
+
+int disk_cache_store(disk_t *disk, disk_chunk_t *chunk)
+{
+  if(!chunk || !chunk->data || chunk->nr == UINT64_MAX) return 1;
+
+  int match;
+  unsigned u = disk_find_chunk(disk, chunk->nr, &match);
+
+  if(!match) {
+    if(disk->chunks.len >= DISK_MAX_CHUNKS) return 2;
+    void *buffer = malloc(DISK_CHUNK_SIZE);
+    if(!buffer) return 3;
+    memcpy(buffer, chunk->data, DISK_CHUNK_SIZE);
+    disk->chunks.len++;
+    if(disk->chunks.len > disk->chunks.max) {
+      disk->chunks.max += DISK_CHUNKS_EXTRA;
+      disk->chunks.list = realloc(disk->chunks.list, disk->chunks.max * sizeof 
(disk_chunk_t));
+      if(disk->chunks.list == NULL) {
+        free(buffer);
+        disk->chunks.len = disk->chunks.max = 0;
+        return 4;
+      }
     }
+    if(u + 1 < disk->chunks.len) {
+      memmove(disk->chunks.list + u + 1, disk->chunks.list + u, sizeof 
(disk_chunk_t) * (disk->chunks.len - u - 1));
+    }
+    disk->chunks.list[u].nr = chunk->nr;
+    disk->chunks.list[u].data = buffer;
   }
 
   return 0;
 }
 
 
-void disk_cache_store(disk_t *disk, void *buffer, uint64_t chunk_nr)
+// Binary search.
+// If matched, return value is index that matched.
+// If no match, return value is position at which to insert new value (may
+// point at position right after end of the list).
+unsigned disk_find_chunk(disk_t *disk, uint64_t chunk_nr, int *match)
 {
-  // fprintf(stderr, "cache store: disk %u, addr %08"PRIx64"\n", disk->index, 
chunk_nr * disk->chunk_size);
-  disk_data_t *disk_data = calloc(1, sizeof *disk_data);
+  *match = 0;
+
+  disk_chunk_t *chunk_list = disk->chunks.list;
+
+  unsigned u_start = 0;
+  unsigned u_end = disk->chunks.len;
+  unsigned u = 0;
 
-  disk_data->chunk_nr = chunk_nr;
-  disk_data->data = malloc(disk->chunk_size);
-  memcpy(disk_data->data, buffer, disk->chunk_size);
+  while(u_end > u_start) {
+    u = (u_end + u_start) / 2;
+
+    int64_t i = chunk_nr - chunk_list[u].nr;
+
+    if(i == 0) {
+      *match = 1;
+      break;
+    }
+
+    if(u_end == u_start + 1) {
+      if(i > 0) u++;
+      break;
+    }
 
-  disk_data->next = disk->data;
-  disk->data = disk_data;
+    if(i > 0) {
+      if(u_end == u + 1) {
+        if(i > 0) u++;
+        break;
+      }
+      u_start = u;
+    }
+    else {
+      u_end = u;
+    }
+  }
+
+  return u;
 }
 
 
@@ -113,16 +181,9 @@
 
   fprintf(f, "# disk %u, size = %"PRIu64"\n", disk->index, 
disk->size_in_bytes);
 
-  uint64_t chunk_nr = 0;
-  disk_data_t *disk_data;
-
-  do {
-    disk_data = disk_cache_search(disk, &chunk_nr);
-    if(disk_data) {
-      disk_cache_dump(disk, disk_data, f);
-    }
+  for(unsigned u = 0; u < disk->chunks.len; u++) {
+    disk_cache_dump(disk, disk->chunks.list + u, f);
   }
-  while(chunk_nr != UINT64_MAX);
 
   if(f != stdout) fclose(f);
 
@@ -132,23 +193,16 @@
 
 int disk_to_fd(disk_t *disk, uint64_t offset)
 {
-  uint64_t chunk_nr = 0;
-  disk_data_t *disk_data;
-
   int fd = syscall(SYS_memfd_create, "", 0);
 
   if(fd == -1) return 0;
 
-  do {
-    disk_data = disk_cache_search(disk, &chunk_nr);
-    if(disk_data) {
-      if(disk_data->chunk_nr * disk->chunk_size >= offset) {
-        lseek(fd, disk_data->chunk_nr * disk->chunk_size - offset, SEEK_SET);
-        write(fd, disk_data->data, disk->chunk_size);
-      }
+  for(unsigned u = 0; u < disk->chunks.len; u++) {
+    if(disk->chunks.list[u].nr * DISK_CHUNK_SIZE >= offset) {
+      lseek(fd, disk->chunks.list[u].nr * DISK_CHUNK_SIZE - offset, SEEK_SET);
+      write(fd, disk->chunks.list[u].data, DISK_CHUNK_SIZE);
     }
   }
-  while(chunk_nr != UINT64_MAX);
 
   lseek(fd, 0, SEEK_SET);
 
@@ -156,19 +210,21 @@
 }
 
 
-void disk_cache_dump(disk_t *disk, disk_data_t *disk_data, FILE *file)
+int disk_cache_dump(disk_t *disk, disk_chunk_t *chunk, FILE *file)
 {
+  if(!file) return 1;
+
   uint8_t all_zeros[16] = {};
-  uint8_t *data = disk_data->data;
+  uint8_t *data = chunk->data;
 
   uint64_t max_addr = disk->size_in_bytes - 1;
   unsigned address_digits = 0;
   while(max_addr >>= 4) address_digits++;
   if(address_digits < 4) address_digits = 4;
 
-  for(unsigned u = 0; u < disk->chunk_size; u += 16) {
+  for(unsigned u = 0; u < DISK_CHUNK_SIZE; u += 16) {
     if(memcmp(data + u, &all_zeros, 16)) {
-      fprintf(file, "%0*"PRIx64" ", address_digits, disk_data->chunk_nr * 
disk->chunk_size + u);
+      fprintf(file, "%0*"PRIx64" ", address_digits, chunk->nr * 
DISK_CHUNK_SIZE + u);
       for(unsigned u1 = 0; u1 < 16; u1++) {
         fprintf(file, " %02x", data[u + u1]);
       }
@@ -179,28 +235,8 @@
       fprintf(file, "\n");
     }
   }
-}
-
-
-disk_data_t *disk_cache_search(disk_t *disk, uint64_t *chunk_nr)
-{
-  disk_data_t *disk_data_found = NULL;
-  uint64_t next_chunk_nr = UINT64_MAX;
-
-  if(*chunk_nr == next_chunk_nr) return NULL;
 
-  for(disk_data_t *disk_data = disk->data; disk_data; disk_data = 
disk_data->next) {
-    if(disk_data->chunk_nr == *chunk_nr) {
-      disk_data_found = disk_data;
-    }
-    if(disk_data->chunk_nr > *chunk_nr && disk_data->chunk_nr < next_chunk_nr) 
{
-      next_chunk_nr = disk_data->chunk_nr;
-    }
-  }
-
-  *chunk_nr = next_chunk_nr;
-
-  return disk_data_found;
+  return 0;
 }
 
 
@@ -231,7 +267,7 @@
 void disk_init(char *file_name)
 {
   struct stat sbuf;
-  disk_t disk = { .chunk_size = 512, .block_size = 512 };
+  disk_t disk = { .block_size = DISK_CHUNK_SIZE };
 
   disk.fd = open(file_name, O_RDONLY | O_LARGEFILE);
 
@@ -264,7 +300,7 @@
 
   disk_t disk = { .fd = -1 };
 
-  uint8_t chunk[512];
+  uint8_t buffer[DISK_CHUNK_SIZE];
   uint64_t current_chunk_nr = UINT64_MAX;
 
   while(getline(&line, &line_len, file) > 0) {
@@ -275,14 +311,14 @@
     uint8_t line_data[16];
     if(sscanf(line, "# disk %u, size = %"SCNu64"", &index, &size) == 2) {
       if(disk.name) {
-        if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, chunk, 
current_chunk_nr);
+        if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, 
&(disk_chunk_t) { .nr = current_chunk_nr, .data = buffer });
         disk_add_to_list(&disk);
         disk = (disk_t) { .index = disk_list_size };
         current_chunk_nr = UINT64_MAX;
       }
       asprintf(&disk.name, "%s#%u", file_name, index);
       disk.size_in_bytes = size;
-      disk.chunk_size = disk.block_size = 512;
+      disk.block_size = DISK_CHUNK_SIZE;
     }
     else if(
       sscanf(line,
@@ -296,15 +332,13 @@
       !(addr & 0xf) &&
       addr <= disk.size_in_bytes + 16
     ) {
-      // fprintf(stderr, "XXX %08"PRIx64" %02x %02x\n", addr, line_data[0], 
line_data[1]);
-      uint64_t chunk_nr = addr / disk.chunk_size;
-      // fprintf(stderr, "ZZZ chunk_nr %"PRIu64", current_chunk_nr 
%"PRIu64"\n", chunk_nr, current_chunk_nr);
+      uint64_t chunk_nr = addr / DISK_CHUNK_SIZE;
       if(chunk_nr != current_chunk_nr) {
-        if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, chunk, 
current_chunk_nr);
+        if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, 
&(disk_chunk_t) { .nr = current_chunk_nr, .data = buffer });
         current_chunk_nr = chunk_nr;
-        memset(chunk, 0, sizeof chunk);
+        memset(buffer, 0, sizeof buffer);
       }
-      memcpy(chunk + (addr % disk.chunk_size), line_data, 16);
+      memcpy(buffer + (addr % DISK_CHUNK_SIZE), line_data, 16);
     }
     else {
       fprintf(stderr, "%s: line %u: invalid import data: %s\n", file_name, 
line_nr, line);
@@ -315,7 +349,7 @@
   free(line);
 
   if(disk.name) {
-    if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, chunk, 
current_chunk_nr);
+    if(current_chunk_nr != UINT64_MAX) disk_cache_store(&disk, &(disk_chunk_t) 
{ .nr = current_chunk_nr, .data = buffer });
     disk_add_to_list(&disk);
   }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/parti-2.10/disk.h new/parti-2.11/disk.h
--- old/parti-2.10/disk.h       2025-05-13 18:30:52.000000000 +0200
+++ new/parti-2.11/disk.h       2026-03-18 18:49:42.000000000 +0100
@@ -1,10 +1,16 @@
 #include <json-c/json.h>
 
-typedef struct disk_data_s {
-  struct disk_data_s *next;
-  uint64_t chunk_nr;
+// internal block size, fixed
+#define DISK_CHUNK_SIZE                512
+// resize internal chunk list by that amount, if needed
+#define DISK_CHUNKS_EXTRA      256
+// maximum number of chunks to store in internal cache (cache size = 512 MiB)
+#define DISK_MAX_CHUNKS                1024*1024
+
+typedef struct {
+  uint64_t nr;
   uint8_t *data;
-} disk_data_t;
+} disk_chunk_t;
 
 typedef struct {
   char *name;
@@ -14,11 +20,13 @@
   unsigned sectors;
   unsigned cylinders;
   uint64_t size_in_bytes;
-  unsigned chunk_size;
   unsigned block_size;
   unsigned grub_used:1;
   unsigned isolinux_used:1;
-  disk_data_t *data;
+  struct {
+    disk_chunk_t *list;
+    unsigned len, max;
+  } chunks;
   json_object *json_disk;
   json_object *json_current;
 } disk_t;
@@ -29,10 +37,11 @@
 int disk_read(disk_t *disk, void *buf, uint64_t sector, unsigned cnt);
 int disk_read_single(disk_t *disk, void *buffer, uint64_t block_nr);
 
-int disk_cache_read(disk_t *disk, void *buffer, uint64_t chunk_nr);
-void disk_cache_dump(disk_t *disk, disk_data_t *disk_data, FILE *file);
-void disk_cache_store(disk_t *disk, void *buffer, uint64_t chunk_nr);
-disk_data_t *disk_cache_search(disk_t *disk, uint64_t *chunk_nr);
+int disk_cache_read(disk_t *disk, disk_chunk_t *chunk);
+int disk_cache_store(disk_t *disk, disk_chunk_t *chunk);
+int disk_cache_dump(disk_t *disk, disk_chunk_t *chunk, FILE *file);
+
+unsigned disk_find_chunk(disk_t *disk, uint64_t chunk_nr, int *match);
 
 int disk_export(disk_t *disk, char *file_name);
 int disk_to_fd(disk_t *disk, uint64_t offset);

Reply via email to