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

Commit78c9dbc

Browse files
author
Nikita Glukhov
committed
TMP: in-place updates
1 parent3200771 commit78c9dbc

File tree

6 files changed

+319
-95
lines changed

6 files changed

+319
-95
lines changed

‎contrib/jsonb_toaster/jsonb_toast_internals.c

Lines changed: 124 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
#include"utils/snapmgr.h"
3636
#include"utils/jsonb.h"
3737

38+
typedefstructvaratt_external_diff
39+
{
40+
int32va_diff_offset;
41+
charva_diff_data[FLEXIBLE_ARRAY_MEMBER];
42+
}varatt_external_diff;
43+
3844
char*
3945
jsonxWriteCustomToastPointerHeader(char*ptr,Oidtoasterid,uint32header,
4046
intdatalen,intrawsize)
@@ -935,6 +941,7 @@ jsonx_create_fetch_datum_iterator(struct varlena *attr, Oid toasterid,
935941
uint32header,char*inline_data,intinline_size)
936942
{
937943
JsonxFetchDatumIteratoriter;
944+
uint32type=header&JSONX_POINTER_TYPE_MASK;
938945

939946
if (!VARATT_IS_EXTERNAL_ONDISK(attr))
940947
elog(ERROR,"create_fetch_datum_iterator shouldn't be called for non-ondisk datums");
@@ -949,19 +956,19 @@ jsonx_create_fetch_datum_iterator(struct varlena *attr, Oid toasterid,
949956
iter->toasterid=toasterid;
950957
iter->chunk_tids_inline_size=inline_size;
951958

952-
if (inline_size <=0)
959+
if (inline_size <=0||type==JSONX_POINTER_DIFF)
953960
{
954961
iter->nchunk_tids=0;
955962
iter->chunk_tids=NULL;
956963
iter->compressed_chunk_tids=NULL;
957-
iter->compressed_chunks=(header&JSONX_POINTER_TYPE_MASK)==JSONX_POINTER_COMPRESSED_CHUNKS;
964+
iter->compressed_chunks=type==JSONX_POINTER_COMPRESSED_CHUNKS;
958965
}
959966
else
960967
{
961968
iter->nchunk_tids=header& ~JSONX_POINTER_TYPE_MASK;
962969
iter->compressed_chunks= false;
963970

964-
if ((header&JSONX_POINTER_TYPE_MASK)==JSONX_POINTER_DIRECT_TIDS_COMP)
971+
if (type==JSONX_POINTER_DIRECT_TIDS_COMP)
965972
{
966973
iter->chunk_tids=palloc0(sizeof(ItemPointerData)*iter->nchunk_tids);
967974
iter->compressed_chunk_tids= (char*)inline_data;
@@ -1503,6 +1510,9 @@ jsonx_fetch_datum_iterate_to(JsonxFetchDatumIterator iter, int32 chunkno, int32
15031510
staticvoid
15041511
jsonx_free_detoast_iterator_internal(JsonxDetoastIteratoriter)
15051512
{
1513+
if (iter->orig_buf&&iter->orig_buf!=iter->buf)
1514+
free_toast_buffer(iter->orig_buf);
1515+
15061516
if (iter->compressed&&iter->buf)
15071517
{
15081518
free_toast_buffer(iter->buf);
@@ -1554,9 +1564,10 @@ jsonx_create_detoast_iterator(struct varlena *attr)
15541564
if (VARATT_IS_CUSTOM(attr))
15551565
{
15561566
uint32header=JSONX_CUSTOM_PTR_GET_HEADER(attr);
1567+
uint32type=header&JSONX_POINTER_TYPE_MASK;
15571568
char*data= (char*)JSONX_CUSTOM_PTR_GET_DATA(attr);
1558-
char*inlineData;
1559-
uint32inlineSize;
1569+
char*inline_data;
1570+
uint32inline_size;
15601571

15611572
if (!VARATT_IS_EXTERNAL_ONDISK(data))
15621573
returnNULL;
@@ -1568,13 +1579,13 @@ jsonx_create_detoast_iterator(struct varlena *attr)
15681579
iter->nrefs=1;
15691580
iter->gen.free_callback.func= (void (*)(void*))jsonx_free_detoast_iterator_internal;
15701581

1571-
inlineData=data+TOAST_POINTER_SIZE;
1572-
inlineSize=JSONX_CUSTOM_PTR_GET_DATA_SIZE(attr)-TOAST_POINTER_SIZE;
1582+
inline_data=data+TOAST_POINTER_SIZE;
1583+
inline_size=JSONX_CUSTOM_PTR_GET_DATA_SIZE(attr)-TOAST_POINTER_SIZE;
15731584

15741585
iter->fetch_datum_iterator=
15751586
jsonx_create_fetch_datum_iterator((structvarlena*)data,
15761587
VARATT_CUSTOM_GET_TOASTERID(attr),
1577-
header,inlineData,inlineSize);
1588+
header,inline_data,inline_size);
15781589

15791590
if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
15801591
{
@@ -1583,14 +1594,30 @@ jsonx_create_detoast_iterator(struct varlena *attr)
15831594

15841595
/* prepare buffer to received decompressed data */
15851596
iter->buf=create_toast_buffer(toast_pointer.va_rawsize, false);
1597+
1598+
if (type==JSONX_POINTER_DIFF)
1599+
iter->orig_buf=create_toast_buffer(toast_pointer.va_rawsize, false);
1600+
else
1601+
iter->orig_buf=iter->buf;
15861602
}
15871603
else
15881604
{
15891605
iter->compressed= false;
15901606
iter->compression_method=TOAST_INVALID_COMPRESSION_ID;
15911607

15921608
/* point the buffer directly at the raw data */
1593-
iter->buf=iter->fetch_datum_iterator->buf;
1609+
iter->buf=iter->orig_buf=iter->fetch_datum_iterator->buf;
1610+
}
1611+
1612+
if (type==JSONX_POINTER_DIFF)
1613+
{
1614+
varatt_external_diff*diff= (varatt_external_diff*)inline_data;
1615+
1616+
iter->diff.inline_data=inline_data;
1617+
iter->diff.inline_size=inline_size;
1618+
iter->diff.size=inline_size- offsetof(varatt_external_diff,va_diff_data);
1619+
iter->diff.offset=diff->va_diff_offset;
1620+
iter->diff.data=diff->va_diff_data;/* FIXME MemoryContext */
15941621
}
15951622

15961623
returniter;
@@ -1605,7 +1632,8 @@ jsonx_create_detoast_iterator(struct varlena *attr)
16051632
iter->gen.free_callback.func= (void (*)(void*))jsonx_free_detoast_iterator_internal;
16061633

16071634
/* This is an externally stored datum --- initialize fetch datum iterator */
1608-
iter->fetch_datum_iterator=fetch_iter=jsonx_create_fetch_datum_iterator(attr,InvalidOid,JSONX_PLAIN_JSONB,NULL,0);
1635+
iter->fetch_datum_iterator=fetch_iter=
1636+
jsonx_create_fetch_datum_iterator(attr,InvalidOid,JSONX_PLAIN_JSONB,NULL,0);
16091637
VARATT_EXTERNAL_GET_POINTER(toast_pointer,attr);
16101638

16111639
if (VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer))
@@ -1614,15 +1642,15 @@ jsonx_create_detoast_iterator(struct varlena *attr)
16141642
iter->compression_method=VARATT_EXTERNAL_GET_COMPRESS_METHOD(toast_pointer);
16151643

16161644
/* prepare buffer to received decompressed data */
1617-
iter->buf=create_toast_buffer(toast_pointer.va_rawsize, false);
1645+
iter->buf=iter->orig_buf=create_toast_buffer(toast_pointer.va_rawsize, false);
16181646
}
16191647
else
16201648
{
16211649
iter->compressed= false;
16221650
iter->compression_method=TOAST_INVALID_COMPRESSION_ID;
16231651

16241652
/* point the buffer directly at the raw data */
1625-
iter->buf=fetch_iter->buf;
1653+
iter->buf=iter->orig_buf=fetch_iter->buf;
16261654
}
16271655
returniter;
16281656
}
@@ -1660,7 +1688,7 @@ jsonx_create_detoast_iterator(struct varlena *attr)
16601688
buf->limit= (char*)buf->capacity;
16611689

16621690
/* prepare buffer to received decompressed data */
1663-
iter->buf=create_toast_buffer(TOAST_COMPRESS_EXTSIZE(attr)+VARHDRSZ, false);
1691+
iter->buf=iter->orig_buf=create_toast_buffer(TOAST_COMPRESS_EXTSIZE(attr)+VARHDRSZ, false);
16641692

16651693
returniter;
16661694
}
@@ -1669,10 +1697,61 @@ jsonx_create_detoast_iterator(struct varlena *attr)
16691697
returnNULL;
16701698
}
16711699

1700+
staticvoid
1701+
toast_apply_diff_internal(structvarlena*result,constchar*diff_data,
1702+
int32diff_offset,int32diff_length,
1703+
int32slice_offset,int32slice_length)
1704+
{
1705+
if (diff_offset >=slice_offset)
1706+
{
1707+
if (diff_offset<slice_offset+slice_length)
1708+
memcpy((char*)result/*VARDATA(result)*/+diff_offset,
1709+
diff_data,
1710+
Min(diff_length,slice_offset+slice_length-diff_offset));
1711+
}
1712+
else
1713+
{
1714+
if (slice_offset<diff_offset+diff_length)
1715+
memcpy((char*)result/*VARDATA(result)*/+slice_offset,
1716+
diff_data+slice_offset-diff_offset,
1717+
Min(slice_length,diff_offset+diff_length-slice_offset));
1718+
}
1719+
}
1720+
1721+
#if0
1722+
staticvoid
1723+
toast_apply_diff(structvarlena*attr,structvarlena*result,
1724+
int32sliceoffset,int32slicelength)
1725+
{
1726+
if (VARATT_IS_EXTERNAL_ONDISK_INLINE_DIFF(attr))
1727+
{
1728+
structvaratt_external_versionedtoast_pointer;
1729+
structvaratt_external_diffdiff;
1730+
constchar*inline_data=VARDATA_EXTERNAL_INLINE(attr);
1731+
/* Must copy to access aligned fields */
1732+
int32inline_size=VARATT_EXTERNAL_INLINE_GET_POINTER(toast_pointer,attr);
1733+
int32attrsize=VARATT_EXTERNAL_GET_EXTSIZE(toast_pointer.va_external);
1734+
Sizedata_offset= offsetof(varatt_external_diff,va_diff_data);
1735+
Sizediff_size=inline_size-data_offset;
1736+
constchar*diff_data=inline_data+data_offset;
1737+
1738+
memcpy(&diff,inline_data,data_offset);
1739+
1740+
if (slicelength<0)
1741+
slicelength=attrsize-sliceoffset;
1742+
1743+
toast_apply_diff_internal(result,diff_data,
1744+
diff.va_diff_offset,diff_size,
1745+
sliceoffset,slicelength);
1746+
}
1747+
}
1748+
#endif
1749+
16721750
void
16731751
jsonx_detoast_iterate(JsonxDetoastIteratordetoast_iter,constchar*destend)
16741752
{
16751753
JsonxFetchDatumIteratorfetch_iter=detoast_iter->fetch_datum_iterator;
1754+
constchar*old_limit=detoast_iter->buf->limit;
16761755

16771756
Assert(detoast_iter!=NULL&& !detoast_iter->done);
16781757

@@ -1692,10 +1771,40 @@ jsonx_detoast_iterate(JsonxDetoastIterator detoast_iter, const char *destend)
16921771
jsonx_fetch_datum_iterate(fetch_iter,-1);
16931772

16941773
if (detoast_iter->compressed)
1695-
toast_decompress_iterate(fetch_iter->buf,detoast_iter->buf,
1774+
toast_decompress_iterate(fetch_iter->buf,detoast_iter->orig_buf,
16961775
detoast_iter->compression_method,
16971776
&detoast_iter->decompression_state,
1698-
destend);
1777+
detoast_iter->orig_buf->buf+ (destend-detoast_iter->buf->buf));
1778+
1779+
if (detoast_iter->diff.data)
1780+
{
1781+
int32slice_offset;
1782+
int32slice_length;
1783+
1784+
/* copy original data to output buffer */
1785+
if (detoast_iter->compressed)
1786+
{
1787+
intdst_limit=detoast_iter->buf->limit-detoast_iter->buf->buf;
1788+
intsrc_limit=detoast_iter->orig_buf->limit-detoast_iter->orig_buf->buf;
1789+
1790+
if (dst_limit<src_limit)
1791+
{
1792+
memcpy(detoast_iter->buf->limit,
1793+
detoast_iter->orig_buf->buf+dst_limit,
1794+
src_limit-dst_limit);
1795+
detoast_iter->buf->limit+=src_limit-dst_limit;
1796+
}
1797+
}
1798+
1799+
slice_offset=old_limit-detoast_iter->buf->buf;
1800+
slice_length=detoast_iter->buf->limit-old_limit;
1801+
1802+
toast_apply_diff_internal((structvarlena*)detoast_iter->buf->buf,
1803+
detoast_iter->diff.data,
1804+
detoast_iter->diff.offset,
1805+
detoast_iter->diff.size,
1806+
slice_offset,slice_length);
1807+
}
16991808

17001809
if (detoast_iter->buf->limit==detoast_iter->buf->capacity)
17011810
{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp