Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite0f05cd

Browse files
committed
Improve some ancient, crufty code in bootstrap + initdb.
At some point back in the last century, somebody felt that readingall of pg_type twice was cheaper, or at least easier, than usingrepalloc() to resize the Typ[] array dynamically. That seems like anentirely wacko proposition, so rewrite the code to do it the otherway. (To add insult to injury, there were two not-quite-identicalcopies of said code.)initdb.c's readfile() function had the same disease of preferringto do double the I/O to avoid resizing its output array. Here,we can make things easier by using the just-invented pg_get_line()function to handle reading individual lines without a predeterminednotion of how long they are.On my machine, it's difficult to detect any net change in theoverall runtime of initdb from these changes; but they shouldhelp on slower buildfarm machines (especially since a buildfarmcycle involves a lot of initdb's these days).My attention was drawn to these places by scan-build complaints,but on inspection they needed a lot more work than just suppressingdead stores :-(
1 parenta5cc4da commite0f05cd

File tree

2 files changed

+74
-91
lines changed

2 files changed

+74
-91
lines changed

‎src/backend/bootstrap/bootstrap.c

Lines changed: 60 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,12 @@
5353
uint32bootstrap_data_checksum_version=0;/* No checksum */
5454

5555

56-
#defineALLOC(t,c) \
57-
((t *) MemoryContextAllocZero(TopMemoryContext, (unsigned)(c) * sizeof(t)))
58-
5956
staticvoidCheckerModeMain(void);
6057
staticvoidBootstrapModeMain(void);
6158
staticvoidbootstrap_signals(void);
6259
staticvoidShutdownAuxiliaryProcess(intcode,Datumarg);
6360
staticForm_pg_attributeAllocateAttribute(void);
61+
staticvoidpopulate_typ_array(void);
6462
staticOidgettype(char*type);
6563
staticvoidcleanup(void);
6664

@@ -583,46 +581,24 @@ ShutdownAuxiliaryProcess(int code, Datum arg)
583581

584582
/* ----------------
585583
*boot_openrel
584+
*
585+
* Execute BKI OPEN command.
586586
* ----------------
587587
*/
588588
void
589589
boot_openrel(char*relname)
590590
{
591591
inti;
592-
structtypmap**app;
593-
Relationrel;
594-
TableScanDescscan;
595-
HeapTupletup;
596592

597593
if (strlen(relname) >=NAMEDATALEN)
598594
relname[NAMEDATALEN-1]='\0';
599595

596+
/*
597+
* pg_type must be filled before any OPEN command is executed, hence we
598+
* can now populate the Typ array if we haven't yet.
599+
*/
600600
if (Typ==NULL)
601-
{
602-
/* We can now load the pg_type data */
603-
rel=table_open(TypeRelationId,NoLock);
604-
scan=table_beginscan_catalog(rel,0,NULL);
605-
i=0;
606-
while ((tup=heap_getnext(scan,ForwardScanDirection))!=NULL)
607-
++i;
608-
table_endscan(scan);
609-
app=Typ=ALLOC(structtypmap*,i+1);
610-
while (i-->0)
611-
*app++=ALLOC(structtypmap,1);
612-
*app=NULL;
613-
scan=table_beginscan_catalog(rel,0,NULL);
614-
app=Typ;
615-
while ((tup=heap_getnext(scan,ForwardScanDirection))!=NULL)
616-
{
617-
(*app)->am_oid= ((Form_pg_type)GETSTRUCT(tup))->oid;
618-
memcpy((char*)&(*app)->am_typ,
619-
(char*)GETSTRUCT(tup),
620-
sizeof((*app)->am_typ));
621-
app++;
622-
}
623-
table_endscan(scan);
624-
table_close(rel,NoLock);
625-
}
601+
populate_typ_array();
626602

627603
if (boot_reldesc!=NULL)
628604
closerel(NULL);
@@ -889,6 +865,52 @@ cleanup(void)
889865
closerel(NULL);
890866
}
891867

868+
/* ----------------
869+
*populate_typ_array
870+
*
871+
* Load the Typ array by reading pg_type.
872+
* ----------------
873+
*/
874+
staticvoid
875+
populate_typ_array(void)
876+
{
877+
Relationrel;
878+
TableScanDescscan;
879+
HeapTupletup;
880+
intnalloc;
881+
inti;
882+
883+
Assert(Typ==NULL);
884+
885+
nalloc=512;
886+
Typ= (structtypmap**)
887+
MemoryContextAlloc(TopMemoryContext,nalloc*sizeof(structtypmap*));
888+
889+
rel=table_open(TypeRelationId,NoLock);
890+
scan=table_beginscan_catalog(rel,0,NULL);
891+
i=0;
892+
while ((tup=heap_getnext(scan,ForwardScanDirection))!=NULL)
893+
{
894+
Form_pg_typetypForm= (Form_pg_type)GETSTRUCT(tup);
895+
896+
/* make sure there will be room for a trailing NULL pointer */
897+
if (i >=nalloc-1)
898+
{
899+
nalloc *=2;
900+
Typ= (structtypmap**)
901+
repalloc(Typ,nalloc*sizeof(structtypmap*));
902+
}
903+
Typ[i]= (structtypmap*)
904+
MemoryContextAlloc(TopMemoryContext,sizeof(structtypmap));
905+
Typ[i]->am_oid=typForm->oid;
906+
memcpy(&(Typ[i]->am_typ),typForm,sizeof(Typ[i]->am_typ));
907+
i++;
908+
}
909+
Typ[i]=NULL;/* Fill trailing NULL pointer */
910+
table_endscan(scan);
911+
table_close(rel,NoLock);
912+
}
913+
892914
/* ----------------
893915
*gettype
894916
*
@@ -903,14 +925,10 @@ cleanup(void)
903925
staticOid
904926
gettype(char*type)
905927
{
906-
inti;
907-
Relationrel;
908-
TableScanDescscan;
909-
HeapTupletup;
910-
structtypmap**app;
911-
912928
if (Typ!=NULL)
913929
{
930+
structtypmap**app;
931+
914932
for (app=Typ;*app!=NULL;app++)
915933
{
916934
if (strncmp(NameStr((*app)->am_typ.typname),type,NAMEDATALEN)==0)
@@ -922,33 +940,16 @@ gettype(char *type)
922940
}
923941
else
924942
{
943+
inti;
944+
925945
for (i=0;i<n_types;i++)
926946
{
927947
if (strncmp(type,TypInfo[i].name,NAMEDATALEN)==0)
928948
returni;
929949
}
950+
/* Not in TypInfo, so we'd better be able to read pg_type now */
930951
elog(DEBUG4,"external type: %s",type);
931-
rel=table_open(TypeRelationId,NoLock);
932-
scan=table_beginscan_catalog(rel,0,NULL);
933-
i=0;
934-
while ((tup=heap_getnext(scan,ForwardScanDirection))!=NULL)
935-
++i;
936-
table_endscan(scan);
937-
app=Typ=ALLOC(structtypmap*,i+1);
938-
while (i-->0)
939-
*app++=ALLOC(structtypmap,1);
940-
*app=NULL;
941-
scan=table_beginscan_catalog(rel,0,NULL);
942-
app=Typ;
943-
while ((tup=heap_getnext(scan,ForwardScanDirection))!=NULL)
944-
{
945-
(*app)->am_oid= ((Form_pg_type)GETSTRUCT(tup))->oid;
946-
memmove((char*)&(*app++)->am_typ,
947-
(char*)GETSTRUCT(tup),
948-
sizeof((*app)->am_typ));
949-
}
950-
table_endscan(scan);
951-
table_close(rel,NoLock);
952+
populate_typ_array();
952953
returngettype(type);
953954
}
954955
elog(ERROR,"unrecognized type \"%s\"",type);

‎src/bin/initdb/initdb.c

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -468,54 +468,36 @@ filter_lines_with_token(char **lines, const char *token)
468468
staticchar**
469469
readfile(constchar*path)
470470
{
471+
char**result;
471472
FILE*infile;
472-
intmaxlength=1,
473-
linelen=0;
474-
intnlines=0;
473+
intmaxlines;
475474
intn;
476-
char**result;
477-
char*buffer;
478-
intc;
475+
char*ln;
479476

480477
if ((infile=fopen(path,"r"))==NULL)
481478
{
482479
pg_log_error("could not open file \"%s\" for reading: %m",path);
483480
exit(1);
484481
}
485482

486-
/* pass over the file twice - the first time to size the result */
483+
maxlines=1024;
484+
result= (char**)pg_malloc(maxlines*sizeof(char*));
487485

488-
while ((c=fgetc(infile))!=EOF)
486+
n=0;
487+
while ((ln=pg_get_line(infile))!=NULL)
489488
{
490-
linelen++;
491-
if (c=='\n')
489+
/* make sure there will be room for a trailing NULL pointer */
490+
if (n >=maxlines-1)
492491
{
493-
nlines++;
494-
if (linelen>maxlength)
495-
maxlength=linelen;
496-
linelen=0;
492+
maxlines *=2;
493+
result= (char**)pg_realloc(result,maxlines*sizeof(char*));
497494
}
498-
}
499-
500-
/* handle last line without a terminating newline (yuck) */
501-
if (linelen)
502-
nlines++;
503-
if (linelen>maxlength)
504-
maxlength=linelen;
505495

506-
/* set up the result and the line buffer */
507-
result= (char**)pg_malloc((nlines+1)*sizeof(char*));
508-
buffer= (char*)pg_malloc(maxlength+1);
509-
510-
/* now reprocess the file and store the lines */
511-
rewind(infile);
512-
n=0;
513-
while (fgets(buffer,maxlength+1,infile)!=NULL&&n<nlines)
514-
result[n++]=pg_strdup(buffer);
496+
result[n++]=ln;
497+
}
498+
result[n]=NULL;
515499

516500
fclose(infile);
517-
free(buffer);
518-
result[n]=NULL;
519501

520502
returnresult;
521503
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp