Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
StackExchange.Redis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
tsai
StackExchange.Redis
Commits
e06768d8
Commit
e06768d8
authored
Apr 30, 2017
by
Marc Gravell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
reduce allocations by pre-boxing the keys and interning the literals as pre-encoded chunks
parent
9c98b5e3
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
78 additions
and
39 deletions
+78
-39
Client.cs
NRediSearch/Client.cs
+26
-19
LiteralCache.cs
NRediSearch/LiteralCache.cs
+32
-0
Query.cs
NRediSearch/Query.cs
+15
-15
Schema.cs
NRediSearch/Schema.cs
+5
-5
No files found.
NRediSearch/Client.cs
View file @
e06768d8
...
...
@@ -8,9 +8,15 @@ namespace NRediSearch
{
public
sealed
class
Client
{
internal
static
readonly
LiteralCache
Literals
=
new
LiteralCache
();
[
Flags
]
public
enum
IndexOptions
{
/// <summary>
/// All options disabled
/// </summary>
None
=
0
,
/// <summary>
/// Set this to tell the index not to save term offset vectors. This reduces memory consumption but does not
/// allow performing exact matches, and reduces overall relevance of multi-term queries
...
...
@@ -35,23 +41,24 @@ private static void SerializeRedisArgs(IndexOptions flags, List<object> args)
{
if
((
flags
&
IndexOptions
.
UseTermOffsets
)
==
0
)
{
args
.
Add
(
"NOOFFSETS"
);
args
.
Add
(
Literals
[
"NOOFFSETS"
]
);
}
if
((
flags
&
IndexOptions
.
KeepFieldFlags
)
==
0
)
{
args
.
Add
(
"NOFIELDS"
);
args
.
Add
(
Literals
[
"NOFIELDS"
]
);
}
if
((
flags
&
IndexOptions
.
UseScoreIndexes
)
==
0
)
{
args
.
Add
(
"NOSCOREIDX"
);
args
.
Add
(
Literals
[
"NOSCOREIDX"
]
);
}
}
IDatabase
_db
;
public
RedisKey
IndexName
{
get
;
}
private
object
_boxedIndexName
;
public
RedisKey
IndexName
=>
(
RedisKey
)
_boxedIndexName
;
public
Client
(
RedisKey
indexName
,
IDatabase
db
)
{
_db
=
db
;
IndexName
=
indexName
;
_boxedIndexName
=
indexName
;
// only box once, not per-command
}
/// <summary>
...
...
@@ -64,9 +71,9 @@ public bool CreateIndex(Schema schema, IndexOptions options)
{
var
args
=
new
List
<
object
>();
args
.
Add
(
IndexName
);
args
.
Add
(
_boxed
IndexName
);
SerializeRedisArgs
(
options
,
args
);
args
.
Add
(
"SCHEMA"
);
args
.
Add
(
Literals
[
"SCHEMA"
]
);
foreach
(
var
f
in
schema
.
Fields
)
{
...
...
@@ -84,7 +91,7 @@ public bool CreateIndex(Schema schema, IndexOptions options)
public
SearchResult
Search
(
Query
q
)
{
var
args
=
new
List
<
object
>();
args
.
Add
(
IndexName
);
args
.
Add
(
_boxed
IndexName
);
q
.
SerializeRedisArgs
(
args
);
var
resp
=
(
RedisResult
[])
_db
.
Execute
(
"FT.SEARCH"
,
args
.
ToArray
());
...
...
@@ -102,23 +109,23 @@ public SearchResult Search(Query q)
/// <param name="payload">if set, we can save a payload in the index to be retrieved or evaluated by scoring functions on the server</param>
public
bool
AddDocument
(
string
docId
,
double
score
,
Dictionary
<
string
,
RedisValue
>
fields
,
bool
noSave
,
bool
replace
,
byte
[]
payload
)
{
var
args
=
new
List
<
object
>
{
IndexName
,
docId
,
score
};
var
args
=
new
List
<
object
>
{
_boxed
IndexName
,
docId
,
score
};
if
(
noSave
)
{
args
.
Add
(
"NOSAVE"
);
args
.
Add
(
Literals
[
"NOSAVE"
]
);
}
if
(
replace
)
{
args
.
Add
(
"REPLACE"
);
args
.
Add
(
Literals
[
"REPLACE"
]
);
}
if
(
payload
!=
null
)
{
args
.
Add
(
"PAYLOAD"
);
args
.
Add
(
Literals
[
"PAYLOAD"
]
);
// TODO: Fix this
args
.
Add
(
payload
);
}
args
.
Add
(
"FIELDS"
);
args
.
Add
(
Literals
[
"FIELDS"
]
);
foreach
(
var
ent
in
fields
)
{
args
.
Add
(
ent
.
Key
);
...
...
@@ -150,11 +157,11 @@ public bool AddDocument(string docId, Dictionary<string, RedisValue> fields)
/// <returns>true on success</returns>
public
bool
AddHash
(
string
docId
,
double
score
,
bool
replace
)
{
var
args
=
new
List
<
object
>
{
IndexName
,
docId
,
score
};
var
args
=
new
List
<
object
>
{
_boxed
IndexName
,
docId
,
score
};
if
(
replace
)
{
args
.
Add
(
"REPLACE"
);
args
.
Add
(
Literals
[
"REPLACE"
]
);
}
return
(
string
)
_db
.
Execute
(
"FT.ADDHASH"
,
args
.
ToArray
())
==
"OK"
;
...
...
@@ -168,7 +175,7 @@ public bool AddHash(string docId, double score, bool replace)
public
Dictionary
<
string
,
RedisValue
>
GetInfo
()
{
var
res
=
(
RedisValue
[])
_db
.
Execute
(
"FT.INFO"
,
IndexName
);
var
res
=
(
RedisValue
[])
_db
.
Execute
(
"FT.INFO"
,
_boxed
IndexName
);
var
info
=
new
Dictionary
<
string
,
RedisValue
>();
for
(
int
i
=
0
;
i
<
res
.
Length
;
i
+=
2
)
{
...
...
@@ -186,7 +193,7 @@ public bool AddHash(string docId, double score, bool replace)
/// <returns>true if it has been deleted, false if it did not exist</returns>
public
bool
DeleteDocument
(
string
docId
)
{
long
r
=
(
long
)
_db
.
Execute
(
"FT.DEL"
,
IndexName
,
docId
);
long
r
=
(
long
)
_db
.
Execute
(
"FT.DEL"
,
_boxed
IndexName
,
docId
);
return
r
==
1
;
}
...
...
@@ -196,7 +203,7 @@ public bool DeleteDocument(string docId)
/// <returns>true on success</returns>
public
bool
DropIndex
()
{
return
(
string
)
_db
.
Execute
(
"FT.DROP"
,
IndexName
)
==
"OK"
;
return
(
string
)
_db
.
Execute
(
"FT.DROP"
,
_boxed
IndexName
)
==
"OK"
;
}
/// <summary>
...
...
@@ -204,7 +211,7 @@ public bool DropIndex()
/// </summary>
public
long
OptimizeIndex
()
{
long
ret
=
(
long
)
_db
.
Execute
(
"FT.OPTIMIZE"
,
IndexName
);
long
ret
=
(
long
)
_db
.
Execute
(
"FT.OPTIMIZE"
,
_boxed
IndexName
);
return
ret
;
}
}
...
...
NRediSearch/LiteralCache.cs
0 → 100644
View file @
e06768d8
using
StackExchange.Redis
;
using
System.Collections
;
namespace
NRediSearch
{
// encode and box literals once only
internal
sealed
class
LiteralCache
{
private
static
Hashtable
_boxed
=
new
Hashtable
();
public
object
this
[
string
value
]
{
get
{
if
(
value
==
null
)
return
""
;
object
boxed
=
_boxed
[
value
];
if
(
boxed
==
null
)
{
lock
(
_boxed
)
{
boxed
=
_boxed
[
value
];
if
(
boxed
==
null
)
{
boxed
=
(
RedisValue
)
value
;
_boxed
.
Add
(
value
,
boxed
);
}
}
}
return
boxed
;
}
}
}
}
NRediSearch/Query.cs
View file @
e06768d8
...
...
@@ -60,7 +60,7 @@ RedisValue FormatNum(double num, bool exclude)
// need to add leading bracket
return
"("
+
num
.
ToString
(
"G17"
,
NumberFormatInfo
.
InvariantInfo
);
}
args
.
Add
(
"FILTER"
);
args
.
Add
(
Client
.
Literals
[
"FILTER"
]
);
args
.
Add
(
Property
);
args
.
Add
(
FormatNum
(
min
,
exclusiveMin
));
args
.
Add
(
FormatNum
(
max
,
exclusiveMax
));
...
...
@@ -86,7 +86,7 @@ public GeoFilter(string property, double lon, double lat, double radius, GeoUnit
internal
override
void
SerializeRedisArgs
(
List
<
object
>
args
)
{
args
.
Add
(
"GEOFILTER"
);
args
.
Add
(
Client
.
Literals
[
"GEOFILTER"
]
);
args
.
Add
(
Property
);
args
.
Add
(
lon
);
args
.
Add
(
lat
);
...
...
@@ -94,10 +94,10 @@ internal override void SerializeRedisArgs(List<object> args)
switch
(
unit
)
{
case
GeoUnit
.
Feet
:
args
.
Add
(
"ft"
);
break
;
case
GeoUnit
.
Kilometers
:
args
.
Add
(
"km"
);
break
;
case
GeoUnit
.
Meters
:
args
.
Add
(
"m"
);
break
;
case
GeoUnit
.
Miles
:
args
.
Add
(
"mi"
);
break
;
case
GeoUnit
.
Feet
:
args
.
Add
(
Client
.
Literals
[
"ft"
]
);
break
;
case
GeoUnit
.
Kilometers
:
args
.
Add
(
Client
.
Literals
[
"km"
]
);
break
;
case
GeoUnit
.
Meters
:
args
.
Add
(
Client
.
Literals
[
"m"
]
);
break
;
case
GeoUnit
.
Miles
:
args
.
Add
(
Client
.
Literals
[
"mi"
]
);
break
;
default
:
throw
new
InvalidOperationException
(
$"Unknown unit:
{
unit
}
"
);
}
}
...
...
@@ -175,45 +175,45 @@ internal void SerializeRedisArgs(List<object> args)
if
(
Verbatim
)
{
args
.
Add
(
"VERBATIM"
);
args
.
Add
(
Client
.
Literals
[
"VERBATIM"
]
);
}
if
(
NoContent
)
{
args
.
Add
(
"NOCONTENT"
);
args
.
Add
(
Client
.
Literals
[
"NOCONTENT"
]
);
}
if
(
NoStopwords
)
{
args
.
Add
(
"NOSTOPWORDS"
);
args
.
Add
(
Client
.
Literals
[
"NOSTOPWORDS"
]
);
}
if
(
WithScores
)
{
args
.
Add
(
"WITHSCORES"
);
args
.
Add
(
Client
.
Literals
[
"WITHSCORES"
]
);
}
if
(
WithPayloads
)
{
args
.
Add
(
"WITHPAYLOADS"
);
args
.
Add
(
Client
.
Literals
[
"WITHPAYLOADS"
]
);
}
if
(
Language
!=
null
)
{
args
.
Add
(
"LANGUAGE"
);
args
.
Add
(
Client
.
Literals
[
"LANGUAGE"
]
);
args
.
Add
(
Language
);
}
if
(
_fields
!=
null
&&
_fields
.
Length
>
0
)
{
args
.
Add
(
"INFIELDS"
);
args
.
Add
(
Client
.
Literals
[
"INFIELDS"
]
);
args
.
Add
(
_fields
.
Length
);
args
.
AddRange
(
_fields
);
}
if
(
Payload
!=
null
)
{
args
.
Add
(
"PAYLOAD"
);
args
.
Add
(
Client
.
Literals
[
"PAYLOAD"
]
);
args
.
Add
(
Payload
);
}
if
(
_paging
.
Offset
!=
0
||
_paging
.
Count
!=
10
)
{
args
.
Add
(
"LIMIT"
);
args
.
Add
(
Client
.
Literals
[
"LIMIT"
]
);
args
.
Add
(
_paging
.
Offset
);
args
.
Add
(
_paging
.
Count
);
}
...
...
NRediSearch/Schema.cs
View file @
e06768d8
...
...
@@ -31,13 +31,13 @@ internal Field(string name, FieldType type)
internal
virtual
void
SerializeRedisArgs
(
List
<
object
>
args
)
{
string
GetForRedis
(
FieldType
type
)
object
GetForRedis
(
FieldType
type
)
{
switch
(
type
)
{
case
FieldType
.
FullText
:
return
"TEXT"
;
case
FieldType
.
Geo
:
return
"GEO"
;
case
FieldType
.
Numeric
:
return
"NUMERIC"
;
case
FieldType
.
FullText
:
return
Client
.
Literals
[
"TEXT"
]
;
case
FieldType
.
Geo
:
return
Client
.
Literals
[
"GEO"
]
;
case
FieldType
.
Numeric
:
return
Client
.
Literals
[
"NUMERIC"
]
;
default
:
throw
new
ArgumentOutOfRangeException
(
nameof
(
type
));
}
}
...
...
@@ -57,7 +57,7 @@ internal override void SerializeRedisArgs(List<object> args)
base
.
SerializeRedisArgs
(
args
);
if
(
Weight
!=
1.0
)
{
args
.
Add
(
"WEIGHT"
);
args
.
Add
(
Client
.
Literals
[
"WEIGHT"
]
);
args
.
Add
(
Weight
);
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment