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

Commiteb7f58f

Browse files
author
Nikita Glukhov
committed
Variable-length jsonb KV map entries
1 parente9a81fb commiteb7f58f

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
@@ -67,6 +67,27 @@ typedef struct CompressedJsonb
6767
intoffset;
6868
}CompressedJsonb;
6969

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

87108
/* Current item in buffer (up to nElems) */
88109
intcurIndex;
@@ -544,6 +565,24 @@ JsonFindValueInContainer(JsonContainer *json, uint32 flags, JsonValue *key)
544565
returnNULL;
545566
}
546567

568+
staticvoid*
569+
initKVMap(JsonbKVMap*kvmap,void*pentries,intfield_count,boolsorted)
570+
{
571+
if (sorted)
572+
{
573+
kvmap->map.entries=pentries;
574+
kvmap->entry_size=JSONB_KVMAP_ENTRY_SIZE(field_count);
575+
576+
return (char*)pentries+INTALIGN(field_count*kvmap->entry_size);
577+
}
578+
else
579+
{
580+
kvmap->entry_size=0;
581+
582+
returnpentries;
583+
}
584+
}
585+
547586
/*
548587
* Find value by key in Jsonb object and fetch it into 'res', which is also
549588
* returned.
@@ -557,9 +596,9 @@ jsonbFindKeyInObject(JsonContainer *jsc, const char *keyVal, int keyLen,
557596
constJsonbContainerHeader*container=JsonContainerDataPtr(jsc);
558597
constJEntry*children=container->children;
559598
intcount=JsonContainerSize(jsc);
560-
char*baseAddr;
599+
char*baseAddr= (char*) (children+count*2);
561600
boolsorted_values= (container->header&JBC_TMASK)==JBC_TOBJECT_SORTED;
562-
constuint32*kvmap;
601+
JsonbKVMapkvmap;
563602
uint32stopLow,
564603
stopHigh;
565604

@@ -573,16 +612,8 @@ jsonbFindKeyInObject(JsonContainer *jsc, const char *keyVal, int keyLen,
573612
* Binary search the container. Since we know this is an object, account
574613
* for *Pairs* of Jentrys
575614
*/
576-
if (sorted_values)
577-
{
578-
kvmap=&children[count*2];
579-
baseAddr= (char*)&kvmap[count];
580-
}
581-
else
582-
{
583-
kvmap=NULL;
584-
baseAddr= (char*) (children+count*2);
585-
}
615+
baseAddr=initKVMap(&kvmap,baseAddr,count,sorted_values);
616+
586617
stopLow=0;
587618
stopHigh=count;
588619
while (stopLow<stopHigh)
@@ -603,7 +634,7 @@ jsonbFindKeyInObject(JsonContainer *jsc, const char *keyVal, int keyLen,
603634
if (difference==0)
604635
{
605636
/* Found our key, return corresponding value */
606-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
637+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
607638

608639
if (!res)
609640
res=palloc(sizeof(JsonbValue));
@@ -1099,6 +1130,7 @@ static JsonbIteratorToken
10991130
jsonbIteratorNext(JsonIterator**jsit,JsonbValue*val,boolskipNested)
11001131
{
11011132
jsonbIterator**it= (jsonbIterator**)jsit;
1133+
intentry_index;
11021134

11031135
if (*it==NULL)
11041136
returnWJB_DONE;
@@ -1215,17 +1247,19 @@ jsonbIteratorNext(JsonIterator **jsit, JsonbValue *val, bool skipNested)
12151247
/* Set state for next call */
12161248
(*it)->state=JBI_OBJECT_KEY;
12171249

1250+
entry_index=JSONB_KVMAP_ENTRY(&(*it)->kvmap, (*it)->curIndex)+ (*it)->nElems;
1251+
12181252
fillCompressedJsonbValue((*it)->compressed, (*it)->container,
1219-
((*it)->kvMap ? (*it)->kvMap[(*it)->curIndex] : (*it)->curIndex)+ (*it)->nElems,
1253+
entry_index,
12201254
(*it)->dataProper,
1221-
(*it)->kvMap ?
1222-
getJsonbOffset((*it)->container,(*it)->kvMap[(*it)->curIndex]+ (*it)->nElems) :
1255+
(*it)->kvmap.entry_size ?
1256+
getJsonbOffset((*it)->container,entry_index) :
12231257
(*it)->curValueOffset,
12241258
val);
12251259

12261260
JBE_ADVANCE_OFFSET((*it)->curDataOffset,
12271261
(*it)->children[(*it)->curIndex]);
1228-
if (!(*it)->kvMap)
1262+
if (!(*it)->kvmap.entry_size)
12291263
JBE_ADVANCE_OFFSET((*it)->curValueOffset,
12301264
(*it)->children[(*it)->curIndex+ (*it)->nElems]);
12311265
(*it)->curIndex++;
@@ -1268,6 +1302,7 @@ jsonbIteratorInitExt(JsonContainer *cont,
12681302
structCompressedJsonb*cjb)
12691303
{
12701304
jsonbIterator*it;
1305+
inttype=container->header&JBC_TMASK;
12711306

12721307
it=palloc0(sizeof(jsonbIterator));
12731308
it->ji.container=cont;
@@ -1280,7 +1315,7 @@ jsonbIteratorInitExt(JsonContainer *cont,
12801315
/* Array starts just after header */
12811316
it->children=container->children;
12821317

1283-
switch (container->header&JBC_TMASK)
1318+
switch (type)
12841319
{
12851320
caseJBC_TSCALAR:
12861321
it->isScalar= true;
@@ -1295,16 +1330,12 @@ jsonbIteratorInitExt(JsonContainer *cont,
12951330
break;
12961331

12971332
caseJBC_TOBJECT:
1298-
it->kvMap=NULL;
1333+
caseJBC_TOBJECT_SORTED:
12991334
it->dataProper=
13001335
(char*)it->children+it->nElems*sizeof(JEntry)*2;
1301-
it->state=JBI_OBJECT_START;
1302-
break;
1336+
it->dataProper=initKVMap(&it->kvmap,it->dataProper,it->nElems,
1337+
type==JBC_TOBJECT_SORTED);
13031338

1304-
caseJBC_TOBJECT_SORTED:
1305-
it->kvMap= (uint32*)
1306-
((char*)it->children+it->nElems*sizeof(JEntry)*2);
1307-
it->dataProper= (char*)&it->kvMap[it->nElems];
13081339
it->state=JBI_OBJECT_START;
13091340
break;
13101341

@@ -2031,6 +2062,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20312062
uint32header;
20322063
intnPairs=val->val.object.nPairs;
20332064
intreserved_size;
2065+
intkvmap_entry_size;
20342066
boolsorted_values=jsonb_sort_field_values&&nPairs>1;
20352067
struct
20362068
{
@@ -2057,6 +2089,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20572089
{
20582090
if (values[i].index!=i)
20592091
{
2092+
kvmap_entry_size=JSONB_KVMAP_ENTRY_SIZE(nPairs);
20602093
sorted_values= true;
20612094
break;
20622095
}
@@ -2079,16 +2112,45 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20792112
/* Reserve space for the JEntries of the keys and values. */
20802113
reserved_size=sizeof(JEntry)*nPairs*2;
20812114
if (sorted_values)
2082-
reserved_size+=sizeof(int32)*nPairs;
2115+
reserved_size+=INTALIGN(kvmap_entry_size*nPairs);
20832116

20842117
jentry_offset=reserveFromBuffer(buffer,reserved_size);
20852118

20862119
/* Write key-value map */
20872120
if (sorted_values)
20882121
{
2122+
intkvmap_offset=jentry_offset+sizeof(JEntry)*nPairs*2;
2123+
20892124
for (i=0;i<nPairs;i++)
2090-
copyToBuffer(buffer,jentry_offset+sizeof(JEntry)*nPairs*2+values[i].index*sizeof(int32),
2091-
(void*)&i,sizeof(int32));
2125+
{
2126+
uint8entry1;
2127+
uint16entry2;
2128+
uint32entry4;
2129+
void*pentry;
2130+
2131+
if (kvmap_entry_size==1)
2132+
{
2133+
entry1= (uint8)i;
2134+
pentry=&entry1;
2135+
}
2136+
elseif (kvmap_entry_size==2)
2137+
{
2138+
entry2= (uint16)i;
2139+
pentry=&entry2;
2140+
}
2141+
else
2142+
{
2143+
entry4= (int32)i;
2144+
pentry=&entry4;
2145+
}
2146+
2147+
copyToBuffer(buffer,kvmap_offset+values[i].index*kvmap_entry_size,
2148+
pentry,kvmap_entry_size);
2149+
}
2150+
2151+
if ((kvmap_entry_size*nPairs) %ALIGNOF_INT)
2152+
memset(buffer->data+kvmap_offset+kvmap_entry_size*nPairs,0,
2153+
ALIGNOF_INT- (kvmap_entry_size*nPairs) %ALIGNOF_INT);
20922154
}
20932155

20942156
/*
@@ -2614,9 +2676,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26142676
intcount=container->header&JBC_CMASK;
26152677
/* Since this is an object, account for *Pairs* of Jentrys */
26162678
boolsorted_values= (container->header&JBC_TMASK)==JBC_TOBJECT_SORTED;
2617-
char*base_addr= (char*) (children+count*2)+ (sorted_values ?sizeof(uint32)*count :0);
2618-
uint32*kvmap=sorted_values ?&container->children[count*2] :NULL;
2619-
Sizebase_offset=base_addr- (char*)jb;
2679+
char*base_addr= (char*) (children+count*2);
2680+
JsonbKVMapkvmap;
2681+
Sizebase_offset;
26202682
uint32stopLow=0,
26212683
stopHigh=count;
26222684

@@ -2627,6 +2689,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26272689
if (count <=0)
26282690
returnNULL;
26292691

2692+
base_addr=initKVMap(&kvmap,base_addr,count,sorted_values);
2693+
base_offset=base_addr- (char*)jb;
2694+
26302695
key.type=jbvString;
26312696
key.val.string.val=keystr;
26322697
key.val.string.len=keylen;
@@ -2658,7 +2723,7 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26582723
if (difference==0)
26592724
{
26602725
/* Found our key, return corresponding value */
2661-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
2726+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
26622727

26632728
if (!res)
26642729
res=palloc(sizeof(*res));

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp