Skip to content

Commit 70257b3

Browse files
committed
PGPRO-427: Remove unnecessary sorts, add binary search
1 parent 6a95d7c commit 70257b3

File tree

3 files changed

+34
-73
lines changed

3 files changed

+34
-73
lines changed

src/backup.c

Lines changed: 33 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,6 @@ static void check_system_identifiers(void);
130130
static void confirm_block_size(const char *name, int blcksz);
131131
static void set_cfs_datafiles(parray *files, const char *root, char *relative, size_t i);
132132

133-
/*
134-
* A little optimization used in process_block_change().
135-
*/
136-
static pgFile *last_used_file = NULL;
137-
138-
139133
#define disconnect_and_exit(code) \
140134
{ \
141135
if (conn != NULL) PQfinish(conn); \
@@ -618,6 +612,19 @@ do_backup_instance(void)
618612
else
619613
dir_list_file(backup_files_list, pgdata, true, true, false);
620614

615+
/*
616+
* Sort pathname ascending. It is necessary to create intermediate
617+
* directories sequentially.
618+
*
619+
* For example:
620+
* 1 - create 'base'
621+
* 2 - create 'base/1'
622+
*
623+
* Sorted array is used at least in parse_backup_filelist_filenames(),
624+
* extractPageMap(), make_pagemap_from_ptrack().
625+
*/
626+
parray_qsort(backup_files_list, pgFileComparePath);
627+
621628
/* Extract information about files in backup_list parsing their names:*/
622629
parse_backup_filelist_filenames(backup_files_list, pgdata);
623630

@@ -635,9 +642,6 @@ do_backup_instance(void)
635642
*/
636643
if (current.backup_mode == BACKUP_MODE_DIFF_PAGE)
637644
{
638-
/* Just in case initialize it to NULL */
639-
last_used_file = NULL;
640-
641645
/*
642646
* Build the page map. Obtain information about changed pages
643647
* reading WAL segments present in archives up to the point
@@ -651,26 +655,16 @@ do_backup_instance(void)
651655
*/
652656
!current.from_replica, backup_files_list);
653657
}
654-
655-
if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK)
658+
else if (current.backup_mode == BACKUP_MODE_DIFF_PTRACK)
656659
{
657-
parray_qsort(backup_files_list, pgFileComparePath);
660+
/*
661+
* Build the page map from ptrack information.
662+
*/
658663
make_pagemap_from_ptrack(backup_files_list);
659664
}
660665

661666
/*
662-
* Sort pathname ascending. It is necessary to create intermediate
663-
* directories sequentially.
664-
*
665-
* For example:
666-
* 1 - create 'base'
667-
* 2 - create 'base/1'
668-
*/
669-
parray_qsort(backup_files_list, pgFileComparePath);
670-
671-
/*
672-
* Make directories before backup
673-
* and setup threads at the same time
667+
* Make directories before backup and setup threads at the same time
674668
*/
675669
for (i = 0; i < parray_num(backup_files_list); i++)
676670
{
@@ -771,12 +765,14 @@ do_backup_instance(void)
771765
for (i = 0; i < parray_num(xlog_files_list); i++)
772766
{
773767
pgFile *file = (pgFile *) parray_get(xlog_files_list, i);
768+
774769
if (S_ISREG(file->mode))
775770
calc_file_checksum(file);
776771
/* Remove file path root prefix*/
777772
if (strstr(file->path, database_path) == file->path)
778773
{
779774
char *ptr = file->path;
775+
780776
file->path = pstrdup(GetRelativePath(ptr, database_path));
781777
free(ptr);
782778
}
@@ -2300,27 +2296,6 @@ write_backup_file_list(parray *files, const char *root)
23002296
elog(ERROR, "cannot write file list \"%s\": %s", path, strerror(errno));
23012297
}
23022298

2303-
/*
2304-
* A helper function to create the path of a relation file and segment.
2305-
* The returned path is palloc'd
2306-
*/
2307-
static char *
2308-
datasegpath(RelFileNode rnode, ForkNumber forknum, BlockNumber segno)
2309-
{
2310-
char *path;
2311-
char *segpath;
2312-
2313-
path = relpathperm(rnode, forknum);
2314-
if (segno > 0)
2315-
{
2316-
segpath = psprintf("%s.%u", path, segno);
2317-
pfree(path);
2318-
return segpath;
2319-
}
2320-
else
2321-
return path;
2322-
}
2323-
23242299
/*
23252300
* Find pgfile by given rnode in the backup_files_list
23262301
* and add given blkno to its pagemap.
@@ -2332,36 +2307,24 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23322307
char *rel_path;
23332308
BlockNumber blkno_inseg;
23342309
int segno;
2335-
pgFile *file_item = NULL;
2336-
int j;
2310+
pgFile **file_item;
2311+
pgFile f;
23372312

23382313
segno = blkno / RELSEG_SIZE;
23392314
blkno_inseg = blkno % RELSEG_SIZE;
23402315

2341-
rel_path = datasegpath(rnode, forknum, segno);
2342-
path = pg_malloc(strlen(rel_path) + strlen(pgdata) + 2);
2343-
sprintf(path, "%s/%s", pgdata, rel_path);
2344-
2345-
/*
2346-
* Little optimization in case if we need the same file as in the previoius
2347-
* call.
2348-
*/
2349-
if (last_used_file && strcmp(last_used_file->path, path) == 0)
2350-
file_item = last_used_file;
2316+
rel_path = relpathperm(rnode, forknum);
2317+
if (segno > 0)
2318+
path = psprintf("%s/%s.%u", pgdata, rel_path, segno);
23512319
else
2352-
{
2353-
for (j = 0; j < parray_num(backup_files_list); j++)
2354-
{
2355-
pgFile *p = (pgFile *) parray_get(backup_files_list, j);
2320+
path = psprintf("%s/%s", pgdata, rel_path);
23562321

2357-
if (strcmp(p->path, path) == 0)
2358-
{
2359-
file_item = p;
2360-
last_used_file = p;
2361-
break;
2362-
}
2363-
}
2364-
}
2322+
pg_free(rel_path);
2323+
2324+
f.path = path;
2325+
/* backup_files_list should be sorted before */
2326+
file_item = (pgFile **) parray_bsearch(backup_files_list, &f,
2327+
pgFileComparePath);
23652328

23662329
/*
23672330
* If we don't have any record of this file in the file map, it means
@@ -2370,10 +2333,9 @@ process_block_change(ForkNumber forknum, RelFileNode rnode, BlockNumber blkno)
23702333
* backup would simply copy it as-is.
23712334
*/
23722335
if (file_item)
2373-
datapagemap_add(&file_item->pagemap, blkno_inseg);
2336+
datapagemap_add(&(*file_item)->pagemap, blkno_inseg);
23742337

23752338
pg_free(path);
2376-
pg_free(rel_path);
23772339
}
23782340

23792341
/*

src/delete.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ pgBackupDeleteFiles(pgBackup *backup)
281281

282282
/* print progress */
283283
elog(VERBOSE, "delete file(%zd/%lu) \"%s\"", i + 1,
284-
(unsigned long) parray_num(files), file->path);
284+
(unsigned long) parray_num(files), file->path);
285285

286286
if (remove(file->path))
287287
{

src/dir.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,6 @@ dir_list_file(parray *files, const char *root, bool exclude, bool omit_symlink,
385385
parray_append(files, file);
386386

387387
dir_list_file_internal(files, root, file, exclude, omit_symlink, black_list);
388-
parray_qsort(files, pgFileComparePath);
389388
}
390389

391390
/*

0 commit comments

Comments
 (0)