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

Commite0a9476

Browse files
author
Nikita Glukhov
committed
Variable-length jsonb KV map entries
1 parent973254e commite0a9476

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;
@@ -549,6 +570,24 @@ JsonFindValueInContainer(JsonContainer *json, uint32 flags, JsonValue *key)
549570
returnNULL;
550571
}
551572

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

@@ -578,16 +617,8 @@ getKeyJsonValueFromContainer(JsonContainer *jsc,
578617
* Binary search the container. Since we know this is an object, account
579618
* for *Pairs* of Jentrys
580619
*/
581-
if (sorted_values)
582-
{
583-
kvmap=&children[count*2];
584-
baseAddr= (char*)&kvmap[count];
585-
}
586-
else
587-
{
588-
kvmap=NULL;
589-
baseAddr= (char*) (children+count*2);
590-
}
620+
baseAddr=initKVMap(&kvmap,baseAddr,count,sorted_values);
621+
591622
stopLow=0;
592623
stopHigh=count;
593624
while (stopLow<stopHigh)
@@ -608,7 +639,7 @@ getKeyJsonValueFromContainer(JsonContainer *jsc,
608639
if (difference==0)
609640
{
610641
/* Found our key, return corresponding value */
611-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
642+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
612643

613644
if (!res)
614645
res=palloc(sizeof(JsonbValue));
@@ -1097,6 +1128,7 @@ JsonbIteratorToken
10971128
JsonbIteratorNext(JsonIterator**jsit,JsonbValue*val,boolskipNested)
10981129
{
10991130
JsonbIterator**it= (JsonbIterator**)jsit;
1131+
intentry_index;
11001132

11011133
if (*it==NULL)
11021134
returnWJB_DONE;
@@ -1209,17 +1241,19 @@ JsonbIteratorNext(JsonIterator **jsit, JsonbValue *val, bool skipNested)
12091241
/* Set state for next call */
12101242
(*it)->state=JBI_OBJECT_KEY;
12111243

1244+
entry_index=JSONB_KVMAP_ENTRY(&(*it)->kvmap, (*it)->curIndex)+ (*it)->nElems;
1245+
12121246
fillCompressedJsonbValue((*it)->compressed, (*it)->container,
1213-
((*it)->kvMap ? (*it)->kvMap[(*it)->curIndex] : (*it)->curIndex)+ (*it)->nElems,
1247+
entry_index,
12141248
(*it)->dataProper,
1215-
(*it)->kvMap ?
1216-
getJsonbOffset((*it)->container,(*it)->kvMap[(*it)->curIndex]+ (*it)->nElems) :
1249+
(*it)->kvmap.entry_size ?
1250+
getJsonbOffset((*it)->container,entry_index) :
12171251
(*it)->curValueOffset,
12181252
val);
12191253

12201254
JBE_ADVANCE_OFFSET((*it)->curDataOffset,
12211255
(*it)->children[(*it)->curIndex]);
1222-
if (!(*it)->kvMap)
1256+
if (!(*it)->kvmap.entry_size)
12231257
JBE_ADVANCE_OFFSET((*it)->curValueOffset,
12241258
(*it)->children[(*it)->curIndex+ (*it)->nElems]);
12251259
(*it)->curIndex++;
@@ -1261,6 +1295,7 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
12611295
structCompressedJsonb*cjb)
12621296
{
12631297
JsonbIterator*it;
1298+
inttype=container->header&JB_TMASK;
12641299

12651300
it=palloc0(sizeof(JsonbIterator));
12661301
it->ji.container=cont;
@@ -1273,7 +1308,7 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
12731308
/* Array starts just after header */
12741309
it->children=container->children;
12751310

1276-
switch (container->header&JB_TMASK)
1311+
switch (type)
12771312
{
12781313
caseJB_TSCALAR:
12791314
it->isScalar= true;
@@ -1288,16 +1323,12 @@ jsonbIteratorInit(JsonContainer *cont, const JsonbContainer *container,
12881323
break;
12891324

12901325
caseJB_TOBJECT:
1291-
it->kvMap=NULL;
1326+
caseJB_TOBJECT_SORTED:
12921327
it->dataProper=
12931328
(char*)it->children+it->nElems*sizeof(JEntry)*2;
1294-
it->state=JBI_OBJECT_START;
1295-
break;
1329+
it->dataProper=initKVMap(&it->kvmap,it->dataProper,it->nElems,
1330+
type==JB_TOBJECT_SORTED);
12961331

1297-
caseJB_TOBJECT_SORTED:
1298-
it->kvMap= (uint32*)
1299-
((char*)it->children+it->nElems*sizeof(JEntry)*2);
1300-
it->dataProper= (char*)&it->kvMap[it->nElems];
13011332
it->state=JBI_OBJECT_START;
13021333
break;
13031334

@@ -2021,6 +2052,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20212052
uint32header;
20222053
intnPairs=val->val.object.nPairs;
20232054
intreserved_size;
2055+
intkvmap_entry_size;
20242056
boolsorted_values=jsonb_sort_field_values&&nPairs>1;
20252057
struct
20262058
{
@@ -2047,6 +2079,7 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20472079
{
20482080
if (values[i].index!=i)
20492081
{
2082+
kvmap_entry_size=JSONB_KVMAP_ENTRY_SIZE(nPairs);
20502083
sorted_values= true;
20512084
break;
20522085
}
@@ -2069,16 +2102,45 @@ convertJsonbObject(StringInfo buffer, JEntry *pheader, const JsonbValue *val, in
20692102
/* Reserve space for the JEntries of the keys and values. */
20702103
reserved_size=sizeof(JEntry)*nPairs*2;
20712104
if (sorted_values)
2072-
reserved_size+=sizeof(int32)*nPairs;
2105+
reserved_size+=INTALIGN(kvmap_entry_size*nPairs);
20732106

20742107
jentry_offset=reserveFromBuffer(buffer,reserved_size);
20752108

20762109
/* Write key-value map */
20772110
if (sorted_values)
20782111
{
2112+
intkvmap_offset=jentry_offset+sizeof(JEntry)*nPairs*2;
2113+
20792114
for (i=0;i<nPairs;i++)
2080-
copyToBuffer(buffer,jentry_offset+sizeof(JEntry)*nPairs*2+values[i].index*sizeof(int32),
2081-
&i,sizeof(int32));
2115+
{
2116+
uint8entry1;
2117+
uint16entry2;
2118+
uint32entry4;
2119+
void*pentry;
2120+
2121+
if (kvmap_entry_size==1)
2122+
{
2123+
entry1= (uint8)i;
2124+
pentry=&entry1;
2125+
}
2126+
elseif (kvmap_entry_size==2)
2127+
{
2128+
entry2= (uint16)i;
2129+
pentry=&entry2;
2130+
}
2131+
else
2132+
{
2133+
entry4= (int32)i;
2134+
pentry=&entry4;
2135+
}
2136+
2137+
copyToBuffer(buffer,kvmap_offset+values[i].index*kvmap_entry_size,
2138+
pentry,kvmap_entry_size);
2139+
}
2140+
2141+
if ((kvmap_entry_size*nPairs) %ALIGNOF_INT)
2142+
memset(buffer->data+kvmap_offset+kvmap_entry_size*nPairs,0,
2143+
ALIGNOF_INT- (kvmap_entry_size*nPairs) %ALIGNOF_INT);
20822144
}
20832145

20842146
/*
@@ -2670,9 +2732,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26702732
intcount=container->header&JB_CMASK;
26712733
/* Since this is an object, account for *Pairs* of Jentrys */
26722734
boolsorted_values= (container->header&JB_TMASK)==JB_TOBJECT_SORTED;
2673-
char*base_addr= (char*) (children+count*2)+ (sorted_values ?sizeof(uint32)*count :0);
2674-
uint32*kvmap=sorted_values ?&container->children[count*2] :NULL;
2675-
Sizebase_offset=base_addr- (char*)jb;
2735+
char*base_addr= (char*) (children+count*2);
2736+
JsonbKVMapkvmap;
2737+
Sizebase_offset;
26762738
uint32stopLow=0,
26772739
stopHigh=count;
26782740

@@ -2682,6 +2744,9 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
26822744
if (count <=0)
26832745
returnNULL;
26842746

2747+
base_addr=initKVMap(&kvmap,base_addr,count,sorted_values);
2748+
base_offset=base_addr- (char*)jb;
2749+
26852750
key.type=jbvString;
26862751
key.val.string.val=keystr;
26872752
key.val.string.len=keylen;
@@ -2713,7 +2778,7 @@ findValueInCompressedJsonbObject(CompressedJsonb *cjb, const char *keystr, int k
27132778
if (difference==0)
27142779
{
27152780
/* Found our key, return corresponding value */
2716-
intindex=(sorted_values ?kvmap[stopMiddle] :stopMiddle)+count;
2781+
intindex=JSONB_KVMAP_ENTRY(&kvmap,stopMiddle)+count;
27172782

27182783
returnfillCompressedJsonbValue(cjb,container,index,base_addr,
27192784
getJsonbOffset(container,index),

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp