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

Commit3307c9a

Browse files
committed
Switch to varchar keys and arbitrary-length values in raftable.
1 parent2159e69 commit3307c9a

File tree

2 files changed

+221
-54
lines changed

2 files changed

+221
-54
lines changed

‎contrib/raftable/raftable--1.0.sql‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@
22
\echo Use"CREATE EXTENSION raftable" to load this file. \quit
33

44
-- get
5-
CREATEFUNCTIONraftable(keyint)
5+
CREATEFUNCTIONraftable(keyvarchar(64))
66
RETURNStext
77
AS'MODULE_PATHNAME','raftable_sql_get'
88
LANGUAGE C;
99

1010
-- set
11-
CREATEFUNCTIONraftable(keyint, valuetext)
11+
CREATEFUNCTIONraftable(keyvarchar(64), valuetext)
1212
RETURNS void
1313
AS'MODULE_PATHNAME','raftable_sql_set'
1414
LANGUAGE C;
1515

1616
-- list
1717
CREATEFUNCTIONraftable()
18-
RETURNS table (keyint, valuetext)
18+
RETURNS table (keyvarchar(64), valuetext)
1919
AS'MODULE_PATHNAME','raftable_sql_list'
2020
LANGUAGE C;

‎contrib/raftable/raftable.c‎

Lines changed: 218 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,36 @@
1616

1717
#include"raftable.h"
1818

19-
#defineRAFTABLE_SHMEM_SIZE (16 * 1024)
19+
#defineRAFTABLE_KEY_LEN (64)
20+
#defineRAFTABLE_BLOCK_LEN (256)
21+
#defineRAFTABLE_BLOCKS (4096)
22+
#defineRAFTABLE_BLOCK_MEM (RAFTABLE_BLOCK_LEN * (RAFTABLE_BLOCKS - 1) + sizeof(RaftableBlockMem))
2023
#defineRAFTABLE_HASH_SIZE (127)
21-
#defineRAFTABLE_VALUE_LEN 64
24+
#defineRAFTABLE_SHMEM_SIZE ((1024 * 1024) + RAFTABLE_BLOCK_MEM)
25+
26+
typedefstructRaftableBlock
27+
{
28+
structRaftableBlock*next;
29+
chardata[RAFTABLE_BLOCK_LEN-sizeof(void*)];
30+
}RaftableBlock;
31+
32+
typedefstructRaftableKey
33+
{
34+
chardata[RAFTABLE_KEY_LEN];
35+
}RaftableKey;
36+
37+
typedefstructRaftableEntry
38+
{
39+
RaftableKeykey;
40+
intlen;
41+
RaftableBlock*value;
42+
}RaftableEntry;
43+
44+
typedefstructRaftableBlockMem
45+
{
46+
RaftableBlock*free_blocks;
47+
RaftableBlockblocks[1];
48+
}RaftableBlockMem;
2249

2350
void_PG_init(void);
2451
void_PG_fini(void);
@@ -29,53 +56,183 @@ PG_FUNCTION_INFO_V1(raftable_sql_get);
2956
PG_FUNCTION_INFO_V1(raftable_sql_set);
3057
PG_FUNCTION_INFO_V1(raftable_sql_list);
3158

32-
staticHTAB*data;
33-
staticLWLockIddatalock;
59+
staticHTAB*hashtable;
60+
staticLWLockIdhashlock;
61+
62+
staticRaftableBlockMem*blockmem;
63+
staticLWLockIdblocklock;
64+
3465
staticshmem_startup_hook_typePreviousShmemStartupHook;
3566

36-
typedefstructRaftableEntry
67+
staticRaftableBlock*block_alloc(void)
3768
{
38-
intkey;
39-
charvalue[RAFTABLE_VALUE_LEN];
40-
}RaftableEntry;
69+
RaftableBlock*result;
70+
71+
LWLockAcquire(blocklock,LW_EXCLUSIVE);
72+
73+
result=blockmem->free_blocks;
74+
if (result==NULL)
75+
elog(ERROR,"raftable memory limit hit");
76+
77+
78+
blockmem->free_blocks=blockmem->free_blocks->next;
79+
result->next=NULL;
80+
LWLockRelease(blocklock);
81+
returnresult;
82+
}
83+
84+
staticvoidblock_free(RaftableBlock*block)
85+
{
86+
RaftableBlock*new_free_head=block;
87+
Assert(block!=NULL);
88+
while (block->next!=NULL) {
89+
block=block->next;
90+
}
91+
LWLockAcquire(blocklock,LW_EXCLUSIVE);
92+
block->next=blockmem->free_blocks;
93+
blockmem->free_blocks=new_free_head;
94+
LWLockRelease(blocklock);
95+
}
96+
97+
98+
statictext*entry_to_text(RaftableEntry*e)
99+
{
100+
char*cursor,*buf;
101+
RaftableBlock*block;
102+
text*t;
103+
intlen;
104+
105+
buf=palloc(e->len+1);
106+
cursor=buf;
107+
108+
block=e->value;
109+
len=e->len;
110+
while (block!=NULL)
111+
{
112+
inttocopy=len;
113+
if (tocopy>sizeof(block->data))
114+
tocopy=sizeof(block->data);
115+
116+
memcpy(cursor,block->data,tocopy);
117+
cursor+=tocopy;
118+
len-=tocopy;
119+
120+
Assert(cursor-buf <=e->len);
121+
block=block->next;
122+
}
123+
Assert(cursor-buf==e->len);
124+
*cursor='\0';
125+
t=cstring_to_text_with_len(buf,e->len);
126+
pfree(buf);
127+
returnt;
128+
}
129+
130+
staticvoidtext_to_entry(RaftableEntry*e,text*t)
131+
{
132+
char*buf,*cursor;
133+
intlen;
134+
RaftableBlock*block;
135+
136+
buf=text_to_cstring(t);
137+
cursor=buf;
138+
len=strlen(buf);
139+
e->len=len;
140+
141+
if (e->len>0)
142+
{
143+
if (e->value==NULL)
144+
e->value=block_alloc();
145+
Assert(e->value!=NULL);
146+
}
147+
else
148+
{
149+
if (e->value!=NULL)
150+
{
151+
block_free(e->value);
152+
e->value=NULL;
153+
}
154+
}
155+
156+
block=e->value;
157+
while (len>0)
158+
{
159+
inttocopy=len;
160+
if (tocopy>sizeof(block->data))
161+
{
162+
tocopy=sizeof(block->data);
163+
if (block->next==NULL)
164+
block->next=block_alloc();
165+
}
166+
else
167+
{
168+
if (block->next!=NULL)
169+
{
170+
block_free(block->next);
171+
block->next=NULL;
172+
}
173+
}
174+
175+
memcpy(block->data,cursor,tocopy);
176+
cursor+=tocopy;
177+
len-=tocopy;
178+
179+
block=block->next;
180+
}
181+
182+
pfree(buf);
183+
Assert(block==NULL);
184+
}
41185

42186
Datum
43187
raftable_sql_get(PG_FUNCTION_ARGS)
44188
{
45189
RaftableEntry*entry;
46-
intkey=PG_GETARG_INT32(0);
190+
RaftableKeykey;
191+
text_to_cstring_buffer(PG_GETARG_TEXT_P(0),key.data,sizeof(key.data));
47192

48-
LWLockAcquire(datalock,LW_SHARED);
49-
entry=hash_search(data,&key,HASH_FIND,NULL);
193+
LWLockAcquire(hashlock,LW_SHARED);
194+
entry=hash_search(hashtable,&key,HASH_FIND,NULL);
50195

51196
if (entry)
52197
{
53-
text*t=cstring_to_text(entry->value);
54-
LWLockRelease(datalock);
198+
text*t=entry_to_text(entry);
199+
LWLockRelease(hashlock);
55200
PG_RETURN_TEXT_P(t);
56201
}
57202
else
58203
{
59-
LWLockRelease(datalock);
204+
LWLockRelease(hashlock);
60205
PG_RETURN_NULL();
61206
}
62207
}
63208

64209
Datum
65210
raftable_sql_set(PG_FUNCTION_ARGS)
66211
{
67-
intkey=PG_GETARG_INT32(0);
212+
RaftableKeykey;
213+
text_to_cstring_buffer(PG_GETARG_TEXT_P(0),key.data,sizeof(key.data));
68214

69-
LWLockAcquire(datalock,LW_EXCLUSIVE);
215+
LWLockAcquire(hashlock,LW_EXCLUSIVE);
70216
if (PG_ARGISNULL(1))
71-
hash_search(data,&key,HASH_REMOVE,NULL);
217+
{
218+
RaftableEntry*entry=hash_search(hashtable,key.data,HASH_FIND,NULL);
219+
if ((entry!=NULL)&& (entry->len>0))
220+
block_free(entry->value);
221+
hash_search(hashtable,key.data,HASH_REMOVE,NULL);
222+
}
72223
else
73224
{
74-
RaftableEntry*entry=hash_search(data,&key,HASH_ENTER,NULL);
75-
entry->key=key;
76-
text_to_cstring_buffer(PG_GETARG_TEXT_P(1),entry->value,sizeof(entry->value));
225+
boolfound;
226+
RaftableEntry*entry=hash_search(hashtable,key.data,HASH_ENTER,&found);
227+
if (!found)
228+
{
229+
entry->key=key;
230+
entry->value=NULL;
231+
entry->len=0;
232+
}
233+
text_to_entry(entry,PG_GETARG_TEXT_P(1));
77234
}
78-
LWLockRelease(datalock);
235+
LWLockRelease(hashlock);
79236

80237
PG_RETURN_VOID();
81238
}
@@ -96,12 +253,15 @@ raftable_sql_list(PG_FUNCTION_ARGS)
96253
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
97254

98255
tfc=get_call_result_type(fcinfo,NULL,&funcctx->tuple_desc);
99-
Assert(tfc==TYPEFUNC_COMPOSITE);
256+
if (tfc!=TYPEFUNC_COMPOSITE)
257+
{
258+
elog(ERROR,"raftable listing function should be composite");
259+
}
100260
funcctx->tuple_desc=BlessTupleDesc(funcctx->tuple_desc);
101261

102262
scan= (HASH_SEQ_STATUS*)palloc(sizeof(HASH_SEQ_STATUS));
103-
LWLockAcquire(datalock,LW_SHARED);
104-
hash_seq_init(scan,data);
263+
LWLockAcquire(hashlock,LW_SHARED);
264+
hash_seq_init(scan,hashtable);
105265

106266
MemoryContextSwitchTo(oldcontext);
107267

@@ -117,52 +277,59 @@ raftable_sql_list(PG_FUNCTION_ARGS)
117277
Datumvals[2];
118278
boolisnull[2];
119279

120-
vals[0]=Int32GetDatum(entry->key);
121-
vals[1]=CStringGetTextDatum(entry->value);
280+
vals[0]=CStringGetTextDatum(entry->key.data);
281+
vals[1]=PointerGetDatum(entry_to_text(entry));
122282
isnull[0]=isnull[1]= false;
123283

124284
tuple=heap_form_tuple(funcctx->tuple_desc,vals,isnull);
125285
SRF_RETURN_NEXT(funcctx,HeapTupleGetDatum(tuple));
126286
}
127287
else
128288
{
129-
LWLockRelease(datalock);
289+
LWLockRelease(hashlock);
130290
SRF_RETURN_DONE(funcctx);
131291
}
132292

133293
}
134294

135-
staticuint32raftable_hash_fn(constvoid*key,Sizekeysize)
136-
{
137-
return (uint32)*(int*)key;
138-
}
139-
140-
staticintraftable_match_fn(constvoid*key1,constvoid*key2,Sizekeysize)
141-
{
142-
return*(int*)key1!=*(int*)key2;
143-
}
144-
145295
staticvoidstartup_shmem(void)
146296
{
147-
HASHCTLinfo;
148-
149297
if (PreviousShmemStartupHook){
150298
PreviousShmemStartupHook();
151299
}
152300

153-
datalock=LWLockAssign();
301+
{
302+
HASHCTLinfo;
303+
hashlock=LWLockAssign();
154304

155-
info.keysize=sizeof(int);
156-
info.entrysize=sizeof(RaftableEntry);
157-
info.hash=raftable_hash_fn;
158-
info.match=raftable_match_fn;
305+
info.keysize=sizeof(RaftableKey);
306+
info.entrysize=sizeof(RaftableEntry);
159307

160-
data=ShmemInitHash(
161-
"raftable",
162-
RAFTABLE_HASH_SIZE,RAFTABLE_HASH_SIZE,
163-
&info,
164-
HASH_ELEM |HASH_FUNCTION |HASH_COMPARE
165-
);
308+
hashtable=ShmemInitHash(
309+
"raftable_hashtable",
310+
RAFTABLE_HASH_SIZE,RAFTABLE_HASH_SIZE,
311+
&info,HASH_ELEM
312+
);
313+
}
314+
315+
{
316+
boolfound;
317+
inti;
318+
319+
blocklock=LWLockAssign();
320+
321+
blockmem=ShmemInitStruct(
322+
"raftable_blockmem",
323+
RAFTABLE_BLOCK_MEM,
324+
&found
325+
);
326+
327+
for (i=0;i<RAFTABLE_BLOCKS-1;i++) {
328+
blockmem->blocks[i].next=blockmem->blocks+i+1;
329+
}
330+
blockmem->blocks[RAFTABLE_BLOCKS-1].next=NULL;
331+
blockmem->free_blocks=blockmem->blocks;
332+
}
166333
}
167334

168335
void
@@ -171,7 +338,7 @@ _PG_init(void)
171338
if (!process_shared_preload_libraries_in_progress)
172339
elog(ERROR,"please add 'raftable' to shared_preload_libraries list");
173340
RequestAddinShmemSpace(RAFTABLE_SHMEM_SIZE);
174-
RequestAddinLWLocks(1);
341+
RequestAddinLWLocks(2);
175342

176343
PreviousShmemStartupHook=shmem_startup_hook;
177344
shmem_startup_hook=startup_shmem;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp