Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 2572fe3

Browse files
committedJun 20, 2014
Comments and readme.
1 parent e730520 commit 2572fe3

File tree

2 files changed

+95
-3
lines changed

2 files changed

+95
-3
lines changed
 

‎README.hstore_ops

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
hstore_ops - fast wildcard search for LIKE operator
2+
3+
hstore_ops extension provides another implementation of GIN index (opclass)
4+
for hstore. It provides smaller index and faster @> operator queries than
5+
default GIN opclass. However, queries containing ?, ?|, ?& operators could
6+
become a little slower.
7+
8+
Idea of this opclass is to use composite GIN key which consists of hashes
9+
of hstore key and value. Thus, search for @> operator is possible as simple
10+
match for each queried key-value pair. Search for @>, ?, ?|, ?& is possible
11+
as partial match for each queried hstore key. Recheck is essential for
12+
every kind of search, because of possible hash collision. Hashing provides
13+
small size of index, mixing key and value into same GIN key provides high
14+
performance for @> search operator.
15+
16+
Authors
17+
18+
* Alexander Korotkov <aekorotkov@gmail.com>, Intaro Soft Ltd., Moscow, Russia
19+
* Oleg Bartunov <oleg@sai.msu.su>, Moscow University, Moscow, Russia
20+
21+
License
22+
23+
Development version, available on github, released under the
24+
GNU General Public License, version 2 (June 1991).
25+
26+
Downloads
27+
28+
Stable version of hstore_ops is available from
29+
https://github.com/akorotkov/hstore_ops
30+
31+
Installation
32+
33+
hstore_ops is regular PostgreSQL extension depending on hstore contrib.
34+
To build and install it you should ensure in following:
35+
36+
* You have development package of PostgreSQL installed or you built
37+
PostgreSQL from source.
38+
* Your PATH variable configured so that pg_config command available.
39+
* You did "CREATE EXTENSION hstore;" before "CREATE EXTENSION hstore_ops;".
40+
41+
Typical installation procedure may look like this:
42+
43+
$ git clone https://github.com/akorotkov/hstore_ops.git
44+
$ cd hstore_ops
45+
$ make USE_PGXS=1
46+
$ sudo make USE_PGXS=1 install
47+
$ make USE_PGXS=1 installcheck
48+
$ psql DB -c "CREATE EXTENSION hstore_ops;"
49+
50+
Usage
51+
52+
Just create index on hstore column using following command.
53+
54+
CREATE INDEX index_name ON table_name USING GIN (column_name gin_hstore_hash_ops);
55+
56+
Index will be automatically used for search on @>, ?, ?|, ?& operators
57+
on this column.

‎hstore_ops.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1-
/*
2-
* contrib/hstore/hstore_gin.c
1+
/*-------------------------------------------------------------------------
2+
*
3+
* hstore_ops.c
4+
* Definitions of gin_hstore_hash_ops operator class for hstore.
5+
*
6+
* Copyright (c) 2014, PostgreSQL Global Development Group
7+
* Author: Alexander Korotkov <aekorotkov@gmail.com>
8+
*
9+
* IDENTIFICATION
10+
* contrib/hstore_ops/hstore_ops.c
11+
*
12+
* GIN keys in this opclass are 64-bit integers where higher 32-bits are hash
13+
* of hstore key and lower 32-bits are hash of hstore value.
14+
*
15+
*-------------------------------------------------------------------------
316
*/
417
#include "postgres.h"
518

@@ -15,6 +28,10 @@ PG_MODULE_MAGIC;
1528
PG_FUNCTION_INFO_V1(gin_compare_hstore_hash);
1629
Datum gin_compare_hstore_hash(PG_FUNCTION_ARGS);
1730

31+
/*
32+
* GIN comparison function: compare keys as _unsigned_ 64-bit integers. So, keys
33+
* with same higher 32-bits will be together.
34+
*/
1835
Datum
1936
gin_compare_hstore_hash(PG_FUNCTION_ARGS)
2037
{
@@ -35,6 +52,9 @@ gin_compare_hstore_hash(PG_FUNCTION_ARGS)
3552
PG_FUNCTION_INFO_V1(gin_compare_partial_hstore_hash);
3653
Datum gin_compare_partial_hstore_hash(PG_FUNCTION_ARGS);
3754

55+
/*
56+
* GIN comparison function: select GIN keys with same hash of hstore key.
57+
*/
3858
Datum
3959
gin_compare_partial_hstore_hash(PG_FUNCTION_ARGS)
4060
{
@@ -57,6 +77,9 @@ gin_compare_partial_hstore_hash(PG_FUNCTION_ARGS)
5777
PG_RETURN_INT32(result);
5878
}
5979

80+
/*
81+
* Get hashed representation of key-value pair.
82+
*/
6083
static uint64
6184
get_entry_hash(HEntry *hsent, char *ptr, int i)
6285
{
@@ -70,6 +93,9 @@ get_entry_hash(HEntry *hsent, char *ptr, int i)
7093
return result;
7194
}
7295

96+
/*
97+
* Get hstore key hash in same format as hash of key-value pair.
98+
*/
7399
static uint64
74100
get_key_hash(text *key)
75101
{
@@ -83,6 +109,9 @@ get_key_hash(text *key)
83109
PG_FUNCTION_INFO_V1(gin_extract_hstore_hash);
84110
Datum gin_extract_hstore_hash(PG_FUNCTION_ARGS);
85111

112+
/*
113+
* Split hstore into hashes of key-value pairs.
114+
*/
86115
Datum
87116
gin_extract_hstore_hash(PG_FUNCTION_ARGS)
88117
{
@@ -107,6 +136,9 @@ gin_extract_hstore_hash(PG_FUNCTION_ARGS)
107136
PG_FUNCTION_INFO_V1(gin_extract_hstore_query_hash);
108137
Datum gin_extract_hstore_query_hash(PG_FUNCTION_ARGS);
109138

139+
/*
140+
* Provide relevant hashes for either hstore, key or array of keys.
141+
*/
110142
Datum
111143
gin_extract_hstore_query_hash(PG_FUNCTION_ARGS)
112144
{
@@ -118,7 +150,7 @@ gin_extract_hstore_query_hash(PG_FUNCTION_ARGS)
118150

119151
if (strategy == HStoreContainsStrategyNumber)
120152
{
121-
/* Query is an hstore, so just apply gin_extract_hstore... */
153+
/* Query is an hstore, so just apply gin_extract_hstore_hash... */
122154
entries = (Datum *)
123155
DatumGetPointer(DirectFunctionCall2(gin_extract_hstore_hash,
124156
PG_GETARG_DATUM(0),
@@ -180,6 +212,9 @@ gin_extract_hstore_query_hash(PG_FUNCTION_ARGS)
180212
PG_FUNCTION_INFO_V1(gin_consistent_hstore_hash);
181213
Datum gin_consistent_hstore_hash(PG_FUNCTION_ARGS);
182214

215+
/*
216+
* Consistent
217+
*/
183218
Datum
184219
gin_consistent_hstore_hash(PG_FUNCTION_ARGS)
185220
{

0 commit comments

Comments
 (0)
Please sign in to comment.