Skip to content

Commit 561d620

Browse files
committed
MoveTo Next/Prev Dups return only value
Closes #41
1 parent 4873f97 commit 561d620

File tree

4 files changed

+114
-166
lines changed

4 files changed

+114
-166
lines changed

src/LightningDB.Tests/CursorTests.cs

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -253,39 +253,5 @@ public void ShouldPutMultiple()
253253
for (var i = 0; i < values.Length; i++)
254254
Assert.AreEqual(values[i], pairs[i].Value);
255255
}
256-
257-
[Test]
258-
public void CursorShouldPutDupValues()
259-
{
260-
261-
var db2 = _txn.OpenDatabase("dup",
262-
DatabaseOpenFlags.Create | DatabaseOpenFlags.DuplicatesSort
263-
| DatabaseOpenFlags.DuplicatesFixed | DatabaseOpenFlags.IntegerDuplicates);
264-
265-
using (var cur = _txn.CreateCursor(db2))
266-
{
267-
var keys = Enumerable.Range(1, 50000).ToArray();
268-
foreach (var k in keys)
269-
{
270-
cur.Put(Encoding.UTF8.GetBytes("key"), k, CursorPutOptions.None);
271-
}
272-
// overwrite
273-
foreach (var k in keys)
274-
{
275-
cur.Put(Encoding.UTF8.GetBytes("key"), k, CursorPutOptions.None);
276-
}
277-
278-
var kvp = cur.MoveToFirst();
279-
kvp = cur.MoveNextDuplicate();
280-
kvp = cur.MoveNextDuplicate();
281-
kvp = cur.MoveToFirstDuplicate(); // cancel the moves above and start from the beginning
282-
foreach (var k in keys)
283-
{
284-
//var kvp = cur.GetCurrent();
285-
Assert.AreEqual(k, BitConverter.ToInt32(kvp.Value.Value, 0));
286-
kvp = cur.MoveNextDuplicate();
287-
}
288-
}
289-
}
290256
}
291257
}

src/LightningDB/LightningCursor.cs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@ internal LightningCursor(LightningDatabase db, LightningTransaction txn, IntPtr
116116
/// Position at first data item of current key. Only for MDB_DUPSORT
117117
/// </summary>
118118
/// <returns>First data item of current key. Only for MDB_DUPSORT</returns>
119-
public KeyValuePair<byte[], byte[]>? MoveToFirstDuplicate()
119+
public byte[] MoveToFirstDuplicate()
120120
{
121-
return this.Get(CursorOperation.FirstDuplicate);
121+
return this.GetValue(CursorOperation.FirstDuplicate);
122122
}
123123

124124
/// <summary>
@@ -134,9 +134,9 @@ internal LightningCursor(LightningDatabase db, LightningTransaction txn, IntPtr
134134
/// Position at last data item of current key. Only for MDB_DUPSORT
135135
/// </summary>
136136
/// <returns>Last data item of current key</returns>
137-
public KeyValuePair<byte[], byte[]>? MoveToLastDuplicate()
137+
public byte[] MoveToLastDuplicate()
138138
{
139-
return this.Get(CursorOperation.LastDuplicate);
139+
return this.GetValue(CursorOperation.LastDuplicate);
140140
}
141141

142142
/// <summary>
@@ -244,6 +244,18 @@ public byte[] MoveNextMultiple()
244244
: new KeyValuePair<byte[], byte[]>(keyStruct.ToByteArray(res), valueStruct.ToByteArray(res));
245245
}
246246

247+
private byte[] GetValue(CursorOperation operation)
248+
{
249+
var keyStruct = new ValueStructure();
250+
var valueStruct = new ValueStructure();
251+
252+
var res = NativeMethods.Read(lib => lib.mdb_cursor_get(_handle, ref keyStruct, ref valueStruct, operation));
253+
254+
return res == NativeMethods.MDB_NOTFOUND
255+
? null
256+
: valueStruct.ToByteArray(res);
257+
}
258+
247259
/// <summary>
248260
/// Store by cursor.
249261
/// This function stores key/data pairs into the database.

src/LightningDB/LightningCursorMoveExtensions.cs

Lines changed: 50 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,18 @@
55

66
namespace LightningDB
77
{
8-
/// <summary>
9-
/// Extensions for LightningCursor's Move* methods
10-
/// </summary>
118
public static class LightningCursorMoveExtensions
129
{
1310
private static CursorGetByOperation CursorMoveBy(LightningCursor cur, Func<KeyValuePair<byte[], byte[]>?> mover)
1411
{
1512
return new CursorGetByOperation(cur, mover.Invoke());
1613
}
1714

15+
private static GetByOperation CursorMoveValueBy(LightningCursor cur, Func<byte[]> mover)
16+
{
17+
return new GetByOperation(cur.Database, mover.Invoke());
18+
}
19+
1820
private static bool CursorMove<TKey, TValue>(LightningCursor cur, Func<KeyValuePair<byte[], byte[]>?> mover, out KeyValuePair<TKey, TValue> pair)
1921
{
2022
var op = CursorMoveBy(cur, mover);
@@ -31,206 +33,131 @@ private static bool CursorMove<TKey, TValue>(LightningCursor cur, Func<KeyValueP
3133
}
3234
}
3335

34-
/// <summary>
35-
/// Position at first key/data item
36-
/// </summary>
37-
/// <returns>First key/data item</returns>
36+
private static bool CursorMoveValue<TValue>(LightningCursor cur, Func<byte[]> mover, out TValue value)
37+
{
38+
var op = CursorMoveValueBy(cur, mover);
39+
40+
if (op == null)
41+
{
42+
value = default(TValue);
43+
return false;
44+
}
45+
else
46+
{
47+
value = op.Value< TValue>();
48+
return true;
49+
}
50+
}
51+
3852
public static CursorGetByOperation MoveToFirstBy(this LightningCursor cur)
3953
{
4054
return CursorMoveBy(cur, cur.MoveToFirst);
4155
}
4256

43-
/// <summary>
44-
/// Position at first key/data item
45-
/// </summary>
46-
/// <returns>First key/data item</returns>
4757
public static bool MoveToFirst<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
4858
{
4959
return CursorMove<TKey, TValue>(cur, cur.MoveToFirst, out pair);
5060
}
51-
52-
/// <summary>
53-
/// Position at first data item of current key. Only for MDB_DUPSORT
54-
/// </summary>
55-
/// <returns>First data item of current key. Only for MDB_DUPSORT</returns>
56-
public static CursorGetByOperation MoveToFirstDuplicateBy(this LightningCursor cur)
57-
{
58-
return CursorMoveBy(cur, cur.MoveToFirstDuplicate);
59-
}
60-
61-
/// <summary>
62-
/// Position at first data item of current key. Only for MDB_DUPSORT
63-
/// </summary>
64-
/// <returns>First data item of current key. Only for MDB_DUPSORT</returns>
65-
public static bool MoveToFirstDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
66-
{
67-
return CursorMove<TKey, TValue>(cur, cur.MoveToFirstDuplicate, out pair);
68-
}
69-
70-
/// <summary>
71-
/// Position at last key/data item
72-
/// </summary>
73-
/// <returns>Last key/data item</returns>
61+
7462
public static CursorGetByOperation MoveToLastBy(this LightningCursor cur)
7563
{
7664
return CursorMoveBy(cur, cur.MoveToLast);
7765
}
7866

79-
/// <summary>
80-
/// Position at last key/data item
81-
/// </summary>
82-
/// <returns>Last key/data item</returns>
8367
public static bool MoveToLast<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
8468
{
8569
return CursorMove<TKey, TValue>(cur, cur.MoveToLast, out pair);
8670
}
87-
88-
/// <summary>
89-
/// Position at last data item of current key. Only for MDB_DUPSORT
90-
/// </summary>
91-
/// <returns>Last data item of current key</returns>
92-
public static CursorGetByOperation MoveToLastDuplicateBy(this LightningCursor cur)
93-
{
94-
return CursorMoveBy(cur, cur.MoveToLastDuplicate);
95-
}
96-
97-
/// <summary>
98-
/// Position at last data item of current key. Only for MDB_DUPSORT
99-
/// </summary>
100-
/// <returns>Last data item of current key</returns>
101-
public static bool MoveToLastDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
102-
{
103-
return CursorMove<TKey, TValue>(cur, cur.MoveToLastDuplicate, out pair);
104-
}
105-
106-
/// <summary>
107-
/// Return key/data at current cursor position
108-
/// </summary>
109-
/// <returns>Key/data at current cursor position</returns>
71+
11072
public static CursorGetByOperation GetCurrentBy(this LightningCursor cur)
11173
{
11274
return CursorMoveBy(cur, cur.GetCurrent);
11375
}
11476

115-
/// <summary>
116-
/// Return key/data at current cursor position
117-
/// </summary>
118-
/// <returns>Key/data at current cursor position</returns>
11977
public static bool GetCurrent<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
12078
{
12179
return CursorMove<TKey, TValue>(cur, cur.GetCurrent, out pair);
12280
}
123-
124-
/// <summary>
125-
/// Position at next data item
126-
/// </summary>
127-
/// <returns>Next data item</returns>
81+
12882
public static CursorGetByOperation MoveNextBy(this LightningCursor cur)
12983
{
13084
return CursorMoveBy(cur, cur.MoveNext);
13185
}
13286

133-
/// <summary>
134-
/// Position at next data item
135-
/// </summary>
136-
/// <returns>Next data item</returns>
13787
public static bool MoveNext<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
13888
{
13989
return CursorMove<TKey, TValue>(cur, cur.MoveNext, out pair);
14090
}
141-
142-
/// <summary>
143-
/// Position at next data item of current key. Only for MDB_DUPSORT
144-
/// </summary>
145-
/// <returns>Next data item of current key</returns>
91+
14692
public static CursorGetByOperation MoveNextDuplicateBy(this LightningCursor cur)
14793
{
14894
return CursorMoveBy(cur, cur.MoveNextDuplicate);
14995
}
15096

151-
/// <summary>
152-
/// Position at next data item of current key. Only for MDB_DUPSORT
153-
/// </summary>
154-
/// <returns>Next data item of current key</returns>
15597
public static bool MoveNextDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
15698
{
15799
return CursorMove<TKey, TValue>(cur, cur.MoveNextDuplicate, out pair);
158100
}
159-
160-
/// <summary>
161-
/// Position at first data item of next key. Only for MDB_DUPSORT.
162-
/// </summary>
163-
/// <returns>
164-
/// First data item of next key.
165-
/// </returns>
101+
166102
public static CursorGetByOperation MoveNextNoDuplicateBy(this LightningCursor cur)
167103
{
168104
return CursorMoveBy(cur, cur.MoveNextNoDuplicate);
169105
}
170106

171-
/// <summary>
172-
/// Position at first data item of next key. Only for MDB_DUPSORT.
173-
/// </summary>
174-
/// <returns>
175-
/// First data item of next key.
176-
/// </returns>
177107
public static bool MoveNextNoDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
178108
{
179109
return CursorMove<TKey, TValue>(cur, cur.MoveNextNoDuplicate, out pair);
180110
}
181-
182-
/// <summary>
183-
/// Position at previous data item.
184-
/// </summary>
185-
/// <returns>Previous data item.</returns>
111+
186112
public static CursorGetByOperation MovePrevBy(this LightningCursor cur)
187113
{
188114
return CursorMoveBy(cur, cur.MovePrev);
189115
}
190116

191-
/// <summary>
192-
/// Position at previous data item.
193-
/// </summary>
194-
/// <returns>Previous data item.</returns>
195117
public static bool MovePrev<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
196118
{
197119
return CursorMove<TKey, TValue>(cur, cur.MovePrev, out pair);
198120
}
199-
200-
/// <summary>
201-
/// Position at previous data item of current key. Only for MDB_DUPSORT.
202-
/// </summary>
203-
/// <returns>Previous data item of current key.</returns>
121+
204122
public static CursorGetByOperation MovePrevDuplicateBy(this LightningCursor cur)
205123
{
206124
return CursorMoveBy(cur, cur.MovePrevDuplicate);
207125
}
208126

209-
/// <summary>
210-
/// Position at previous data item of current key. Only for MDB_DUPSORT.
211-
/// </summary>
212-
/// <returns>Previous data item of current key.</returns>
213127
public static bool MovePrevDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
214128
{
215129
return CursorMove<TKey, TValue>(cur, cur.MovePrevDuplicate, out pair);
216130
}
217-
218-
/// <summary>
219-
/// Position at last data item of previous key. Only for MDB_DUPSORT.
220-
/// </summary>
221-
/// <returns>Previous data item of current key.</returns>
131+
222132
public static CursorGetByOperation MovePrevNoDuplicateBy(this LightningCursor cur)
223133
{
224134
return CursorMoveBy(cur, cur.MovePrevNoDuplicate);
225135
}
226136

227-
/// <summary>
228-
/// Position at last data item of previous key. Only for MDB_DUPSORT.
229-
/// </summary>
230-
/// <returns>Previous data item of current key.</returns>
231137
public static bool MovePrevNoDuplicate<TKey, TValue>(this LightningCursor cur, out KeyValuePair<TKey, TValue> pair)
232138
{
233139
return CursorMove<TKey, TValue>(cur, cur.MovePrevNoDuplicate, out pair);
234140
}
141+
142+
public static GetByOperation MoveToFirstDuplicateBy(this LightningCursor cur)
143+
{
144+
return CursorMoveValueBy(cur, cur.MoveToFirstDuplicate);
145+
}
146+
147+
public static bool MoveToFirstDuplicate<TValue>(this LightningCursor cur, out TValue value)
148+
{
149+
return CursorMoveValue<TValue>(cur, cur.MoveToFirstDuplicate, out value);
150+
}
151+
152+
public static GetByOperation MoveToLastDuplicateBy(this LightningCursor cur)
153+
{
154+
return CursorMoveValueBy(cur, cur.MoveToLastDuplicate);
155+
}
156+
157+
public static bool MoveToLastDuplicate<TValue>(this LightningCursor cur, out TValue value)
158+
{
159+
return CursorMoveValue<TValue>(cur, cur.MoveToLastDuplicate, out value);
160+
}
161+
235162
}
236163
}

0 commit comments

Comments
 (0)