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

Commitcae8663

Browse files
author
Nikita Glukhov
committed
Variable-length jsonb KV map entries
1 parentf100794 commitcae8663

File tree

1 file changed

+98
-33
lines changed

1 file changed

+98
-33
lines changed

‎src/backend/utils/adt/jsonb_util.c

Lines changed: 98 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,27 @@ typedef struct CompressedJsonb
6666
intoffset;
6767
}CompressedJsonb;
6868

69+
typedefstructJsonbKVMap
70+
{
71+
union
72+
{
73+
constuint8*entries1;
74+
constuint16*entries2;
75+
constint32*entries4;
76+
constvoid*entries;
77+
}map;
78+
intentry_size;
79+
}JsonbKVMap;
80+
81+
#defineJSONB_KVMAP_ENTRY_SIZE(nPairs) \
82+
((nPairs) < 256 ? 1 : (nPairs) < 65536 ? 2 : 4)
83+
84+
#defineJSONB_KVMAP_ENTRY(kvmap,index) \
85+
(!(kvmap)->entry_size ? (index) : \
86+
(kvmap)->entry_size == 1 ? (int32) (kvmap)->map.entries1[index] : \
87+
(kvmap)->entry_size == 2 ? (int32) (kvmap)->map.entries2[index] : \
88+
(kvmap)->map.entries4[index])
89+
6990
structJsonbIterator
7091
{
7192
JsonIteratorji;
@@ -81,7 +102,7 @@ struct JsonbIterator
81102
constJEntry*children;/* JEntrys for child nodes */
82103
/* Data proper. This points to the beginning of the variable-length data */
83104
char*dataProper;
84-
uint32*kvMap;
105+
JsonbKVMapkvmap;
85106

86107
/* Current item in buffer (up to nElems) */
87108
intcurIndex;
@@ -550,6 +571,24 @@ JsonFindValueInContainer(JsonContainer *json, uint32 flags, JsonValue *key)
550571
returnNULL;
551572
}
552573

574+
staticvoid*
575+
initKVMap(JsonbKVMap*kvmap,void*pentries,intfield_count,boolsorted)
576+
{
577+
if (sorted)
578+
{
579+
kvmap->map.entries=pentries;
580+
kvmap->entry_size=JSONB_KVMAP_ENTRY_SIZE(field_count);
581+
582+
return (char*)pentries+INTALIGN(field_count*kvmap->entry_size);
583+
}
584+
else
585+
{
586+
kvmap->entry_size=0;
587+
588+
returnpentries;
589+
}
590+
}
591+
553592
/*
554593
* Find value by key in Jsonb object and fetch it into 'res', which is also
555594
* returned.
@@ -563,9 +602,9 @@ getKeyJsonValueFromContainer(JsonContainer *jsc,
563602
constJsonbContainer*container=JsonContainerDataPtr(jsc);
564603
constJEntry*children=container->children;
565604
intcount=JsonContainerSize(jsc);
566-
char*baseAddr;
605+
char*baseAddr= (char*) (children+count*2);
567606
boolsorted_values= (container->header&JB_TMASK)==JB_TOBJECT_SORTED;
568-
constuint32*kvmap;
607+
JsonbKVMapkvmap;
569608
uint32stopLow,
570609
stopHigh;
571610

@@ -579,16 +618,8 @@ getKeyJsonValueFromContainer(JsonContainer *jsc,
579618
* Binary search the container. Since we know this is an object, account
580619
* for *Pairs* of Jentrys
581620
*/
582-
if (sorted_values)
583-
{
584-
kvmap=&children[count*2];
585-
baseAddr= (char*)&kvmap[count];
586-
}
587-
else
588-
{
589-
kvmap=NULL;
590-
baseAddr= (char*) (children+count*2);
591-
}
621+
baseAddr=initKVMap(&kvmap,baseAddr,count,sorted_values);
622+
592623
stopLow=0;
593624
stopHigh=count;
594625
while (stopLow<stopHigh)
@@ -609,7 +640,7 @@ getKeyJsonValueFromContainer(JsonContainer *jsc,
609640
if (difference==0)
610641
{
611642
/* Found our key, return corresponding value */
612-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
643+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
613644

614645
if (!res)
615646
res=palloc(sizeof(JsonbValue));
@@ -1034,6 +1065,7 @@ JsonbIteratorToken
10341065
JsonbIteratorNext(JsonIterator**jsit,JsonbValue*val,boolskipNested)
10351066
{
10361067
JsonbIterator**it= (JsonbIterator**)jsit;
1068+
intentry_index;
10371069

10381070
if (*it==NULL)
10391071
returnWJB_DONE;
@@ -1146,17 +1178,19 @@ JsonbIteratorNext(JsonIterator **jsit, JsonbValue *val, bool skipNested)
11461178
/* Set state for next call */
11471179
(*it)->state=JBI_OBJECT_KEY;
11481180

1181+
entry_index=JSONB_KVMAP_ENTRY(&(*it)->kvmap, (*it)->curIndex)+ (*it)->nElems;
1182+
11491183
fillCompressedJsonbValue((*it)->compressed, (*it)->container,
1150-
((*it)->kvMap ? (*it)->kvMap[(*it)->curIndex] : (*it)->curIndex)+ (*it)->nElems,
1184+
entry_index,
11511185
(*it)->dataProper,
1152-
(*it)->kvMap ?
1153-
getJsonbOffset((*it)->container,(*it)->kvMap[(*it)->curIndex]+ (*it)->nElems) :
1186+
(*it)->kvmap.entry_size ?
1187+
getJsonbOffset((*it)->container,entry_index) :
11541188
(*it)->curValueOffset,
11551189
val);
11561190

11571191
JBE_ADVANCE_OFFSET((*it)->curDataOffset,
11581192
(*it)->children[(*it)->curIndex]);
1159-
if (!(*it)->kvMap)
1193+
if (!(*it)->kvmap.entry_size)
11601194
JBE_ADVANCE_OFFSET((*it)->curValueOffset,
11611195
(*it)->children[(*it)->curIndex+ (*it)->nElems]);
11621196
(*it)->curIndex++;
@@ -1198,6 +1232,7 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
11981232
structCompressedJsonb*cjb)
11991233
{
12001234
JsonbIterator*it;
1235+
inttype=container->header&JB_TMASK;
12011236

12021237
it=palloc0(sizeof(JsonbIterator));
12031238
it->ji.container=cont;
@@ -1210,7 +1245,7 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
12101245
/* Array starts just after header */
12111246
it->children=container->children;
12121247

1213-
switch (container->header&JB_TMASK)
1248+
switch (type)
12141249
{
12151250
caseJB_TSCALAR:
12161251
it->isScalar= true;
@@ -1225,16 +1260,12 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
12251260
break;
12261261

12271262
caseJB_TOBJECT:
1228-
it->kvMap=NULL;
1263+
caseJB_TOBJECT_SORTED:
12291264
it->dataProper=
12301265
(char*)it->children+it->nElems*sizeof(JEntry)*2;
1231-
it->state=JBI_OBJECT_START;
1232-
break;
1266+
it->dataProper=initKVMap(&it->kvmap,it->dataProper,it->nElems,
1267+
type==JB_TOBJECT_SORTED);
12331268

1234-
caseJB_TOBJECT_SORTED:
1235-
it->kvMap= (uint32*)
1236-
((char*)it->children+it->nElems*sizeof(JEntry)*2);
1237-
it->dataProper= (char*)&it->kvMap[it->nElems];
12381269
it->state=JBI_OBJECT_START;
12391270
break;
12401271

@@ -1958,6 +1989,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
19581989
uint32header;
19591990
intnPairs=val->val.object.nPairs;
19601991
intreserved_size;
1992+
intkvmap_entry_size;
19611993
boolsorted_values=jsonb_sort_field_values&&nPairs>1;
19621994
struct
19631995
{
@@ -1984,6 +2016,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
19842016
{
19852017
if (values[i].index!=i)
19862018
{
2019+
kvmap_entry_size=JSONB_KVMAP_ENTRY_SIZE(nPairs);
19872020
sorted_values= true;
19882021
break;
19892022
}
@@ -2006,16 +2039,45 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20062039
/* Reserve space for the JEntries of the keys and values. */
20072040
reserved_size=sizeof(JEntry)*nPairs*2;
20082041
if (sorted_values)
2009-
reserved_size+=sizeof(int32)*nPairs;
2042+
reserved_size+=INTALIGN(kvmap_entry_size*nPairs);
20102043

20112044
jentry_offset=reserveFromBuffer(buffer,reserved_size);
20122045

20132046
/* Write key-value map */
20142047
if (sorted_values)
20152048
{
2049+
intkvmap_offset=jentry_offset+sizeof(JEntry)*nPairs*2;
2050+
20162051
for (i=0;i<nPairs;i++)
2017-
copyToBuffer(buffer,jentry_offset+sizeof(JEntry)*nPairs*2+values[i].index*sizeof(int32),
2018-
&i,sizeof(int32));
2052+
{
2053+
uint8entry1;
2054+
uint16entry2;
2055+
uint32entry4;
2056+
void*pentry;
2057+
2058+
if (kvmap_entry_size==1)
2059+
{
2060+
entry1= (uint8)i;
2061+
pentry=&entry1;
2062+
}
2063+
elseif (kvmap_entry_size==2)
2064+
{
2065+
entry2= (uint16)i;
2066+
pentry=&entry2;
2067+
}
2068+
else
2069+
{
2070+
entry4= (int32)i;
2071+
pentry=&entry4;
2072+
}
2073+
2074+
copyToBuffer(buffer,kvmap_offset+values[i].index*kvmap_entry_size,
2075+
pentry,kvmap_entry_size);
2076+
}
2077+
2078+
if ((kvmap_entry_size*nPairs) %ALIGNOF_INT)
2079+
memset(buffer->data+kvmap_offset+kvmap_entry_size*nPairs,0,
2080+
ALIGNOF_INT- (kvmap_entry_size*nPairs) %ALIGNOF_INT);
20192081
}
20202082

20212083
/*
@@ -2607,9 +2669,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26072669
intcount=container->header&JB_CMASK;
26082670
/* Since this is an object, account for *Pairs* of Jentrys */
26092671
boolsorted_values= (container->header&JB_TMASK)==JB_TOBJECT_SORTED;
2610-
char*base_addr= (char*) (children+count*2)+ (sorted_values ?sizeof(uint32)*count :0);
2611-
uint32*kvmap=sorted_values ?&container->children[count*2] :NULL;
2612-
Sizebase_offset=base_addr- (char*)jb;
2672+
char*base_addr= (char*) (children+count*2);
2673+
JsonbKVMapkvmap;
2674+
Sizebase_offset;
26132675
uint32stopLow=0,
26142676
stopHigh=count;
26152677

@@ -2619,6 +2681,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26192681
if (count <=0)
26202682
returnNULL;
26212683

2684+
base_addr=initKVMap(&kvmap,base_addr,count,sorted_values);
2685+
base_offset=base_addr- (char*)jb;
2686+
26222687
key.type=jbvString;
26232688
key.val.string.val=keystr;
26242689
key.val.string.len=keylen;
@@ -2650,7 +2715,7 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26502715
if (difference==0)
26512716
{
26522717
/* Found our key, return corresponding value */
2653-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
2718+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
26542719

26552720
returnfillCompressedJsonbValue(cjb,container,index,base_addr,
26562721
getJsonbOffset(container,index),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp