|
|
Comments and Discussions
|
|
 |

|
Mehdi,
I really like the performance of your project. Would like to use it on multiple mobile devices. Have you considered creating a PCL solution? Has anyone tried this yet?
Thanks,
Mark
|
|
|
|

|
Thanks Mark!
The key/value store should be portable (currently works on monodroid), I haven't tested it on other device mostly because I don't have access to test devices.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
|

|
It's very hard to understand what you mean, but if you mean query from a key to a key then you can use Enumerate(fromkey) and handle the exit yourself (i.e. check tokey reached).
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
|

|
I am using RaptorDB for a project that inserts a few million records (both keys and values are typically close to 100 bytes or more) and I have been getting OutOfMemory exceptions. I've played with various options to control memory usage (decreasing PageItemCount/SaveTimerSeconds, and setting both FreeBitMapMemoryOnSave and FlushStorageFileImmediatley to true), but none of them seem to have any effect on how much memory is used. In particular, I would think that setting FlushStorageFileImmediatley to true would minimize memory usage, if data is not buffered for long before being written to disk.
Any ideas what I might be missing?
Thanks!
|
|
|
|

|
Currently there is no memory limiting in RaptorDB (this could be done by freeing pages in memory but I have not gotten round to that yet).
However you can compile to 64bit and run on the 64bit .net which is not limited to ~2gb memory limit (you get OutOfMemory exceptions on the 32bit framework).
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I made a small insert test. Using esent for compare, I found the result is not same.
Raptor DB was inserted 3221327 strings, but esent was inserted 3222542 strings.
While, the speed of Raptor is faster.Cost about 20 minutes, but esent is 4 hours.
|
|
|
|

|
There is a unit test which inserts 10 million items in under a minute on my old laptop so you should be getting around the same time not 20 minutes.
The same unit test reads and verifies the data, please send me the source code you are using so I can check.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Sorry for said easily misunderstand words.
I mean using my application to test.
While, I test the bplusTest.
The result is below:
set time=139.3103184
get time=242.3384656
It's fast.
|
|
|
|

|
When I inserted several times, including opening and closing the database I found missing pages contain items.
I do not know why what happened so confused in the slippage is not. The type of Database is KeyValue with Key is long type.
|
|
|
|

|
Please show your code.
Note : make sure you shutdown the db when done.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
This is my test code: public void Test2() { string sDatabasePath = @"C:\Testdb\Testdb";
var imagedb = RaptorDB<long>.Open(sDatabasePath, false); string key; string val; int iCount = 0; int n1 = 13434; int n2 = 32143; for (long l = 0; l < n1; l++) { imagedb.Set(l, BitConverter.GetBytes(l)); } imagedb.Shutdown(); imagedb = RaptorDB<long>.Open(sDatabasePath, false); for (long l = n1; l < n2; l++) { imagedb.Set(l, BitConverter.GetBytes(l)); } imagedb.Shutdown(); imagedb = RaptorDB<long>.Open(sDatabasePath, false); for (long l = 0; l < n2; l++) { if (!imagedb.Get(l, out val)) { iCount++; } } imagedb.Shutdown(); Console.WriteLine(String.Format("- Keys not found: {0}", iCount)); }
-- modified 21 Mar '13 - 0:48.
|
|
|
|

|
Excellent article. One thing that was lacking was byte-valued keys. Here ya' go: ByteKey gist[^]
He who asks a question is a fool for five minutes. He who does not ask a question remains a fool forever. [Chinese Proverb]
Jonathan C Dickinson (C# Software Engineer)
|
|
|
|

|
Nice!
The only comment I have is that there is a 255 byte limit to key sizes in the index files.
Thanks Jonathan!
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi Mehdi,
I am evaluating RaptorDB and I have to say it works very well!
However, when I use it on a server with a slow disk there is a big degradation in performance, especially in throughput (20K reads/sec with a 20M data set).
Is there a way to load the entire DB into memory?
Thanks,
Alex.
|
|
|
|

|
Generally only the indexes are in memory as a memory/performance compromise.
The OS filesystem cache should help if you have enough memory (I guess if the disk is slow then that's it).
Currently I don't have plans for an all memory mode.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Should these handlers(double_handler,byte_handler,float_handler...) in DataTypes.cs be singleton instance?
|
|
|
|

|
Singleton are not needed but it could be a static class instead, I would have to test the performance difference.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
There are some helper methods in "SafeDictionary.cs",for example,ToInt32.
In .Net,"System.BitConverter" can do the same thing.
Why do you implement them by yourself?
|
|
|
|

|
The helper code are the same as BitConverter without some checking code which makes it faster.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
There is a way to list all the value ?
|
|
|
|

|
Kind of, you can use Enumerate(key) which will enumerate from the key provided.
I will add a Enumerate() method to do the same from the start of the dictionary.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I found "RaptorDB-The Key Value Store V2" and "
RaptorDB - the Document Store",
what is the diffrence between two project?
Thank you.
|
|
|
|

|
One is a key value store like a dictionary of things, the other is a document store much like a "normal" database engine, the articles on both should be explanatory.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I'm interested in trying this DB out; it looks like it's well implemented, and well supported. However, I'm ideally trying to find a solution that will work across a variety of .NET platforms, specifically Windows, Windows RT, and Windows Phone. Does RaptorDB support usage on Windows RT and/or Windows Phone? I'm not seeing any documentation that says it does, but figured it couldn't hurt to ask. If not, do you plan to add this support? Regardless, nice job!
Jamie Nordmeyer Portland, Oregon, USA
|
|
|
|

|
Thanks Jamie!
I haven't really tested on WinRT/Phone yet, but probably it should be fine and work.
I don't have the devices to test on so it would not be on my todo list in the near future.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi Mehdi,
Really great piece of code! I have a situation where I'm currently using a Dictionary with 10 milion items in it. The problem with this is the population of the Dictionary (can take a while).
RaptorDB could be a great to solve this start up time. However, everytime I open the DB, it's going to rebuild all indexes (even if I'm only using it for reading). With this 10 milion items, it takes about an minute.
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| Current Count = 9,999,872
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| Checking Index state...
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| Rebuilding index...
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| last index count = 0
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| data items count = 9999872
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| 100,000 items re-indexed
2012-12-22 04:47:18|DEBUG|10|RaptorDB.KeyStore`1|| 100,000 items re-indexed
Is there anything that I can do to prevent this?
Thanks,
Danny
|
|
|
|

|
Thanks Danny!
Make sure the engine shutdowns cleanly, and the rebuilding should not kick in to correct things.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Ah, I missed the Shutdown method. That works, thanks!
|
|
|
|

|
How we can make foreach enumeration on all keys?
foreach(var key in storage){
var itemContent = raptor.Get(key)....
//do something with value
//delete key
}
or
foreach(var item in storage){
var itemContent = item.Value;
//do something with value
//delete key
}
I want to store logs in raptorDB and later with Quartz to check if there is any keys and if any, copy to original DB.
Still amater
|
|
|
|

|
Can you please also tell us how to construct our schema? Currently im testing as static variable
public static RaptorDB.RaptorDB<int> raptor = RaptorDB.RaptorDB<int>.Open(raptorPath, 200, false);
and in every function i use this static variable
public bool Something(){
string some = string.empty;
raptor.get(1,out some);
}
But i noticed that i cant remove key and also everytime i check for keys count, it getting duplicated like 2,4,8,16...
I have two functions, one with just Set() and another one with Get() and RemoveKey()
Still amater
|
|
|
|

|
here are some screenshots
EnumerateStorageFile= http://prntscr.com/m4l39.
totalCount = http://prntscr.com/m4l8g
removeKey - dont work
Count - looks like give me *2 of total
Still amater
|
|
|
|

|
You should use the Enumerate() method instead of EnumerateStorageFile().
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Count() currently returns the storage file contents and RaptorDB does not delete data when you call RemoveKey(), so a "deleted" record is added to the storage file hence you get the sequence you referred to.
I'm changing the Count() method to use the index file instead so you will get a more accurate result.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
To enumerate you can use the Enumerate(T fromkey) method and supply a starting point.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Hi,
Thank you for this amazing library, I'm currently porting it to Windows CE (certainly will let you know how it helps us)
While reading the code of Helper.CompareMemCmp in SafeDictionary I've noticed that the return value of this function may not be the result of a general comparison function. As an example the following compare will return true, which is obviously not right. Can you confirm whether it is a bug or a particular optimization in your code based on usage pattern ?
byte[] left = new byte[] {1, 2, 3, 4, 5};
byte[] right = new byte[] {1, 2, 3};
int res = Helper.CompareMemCmp(left, right);
res will be 0 while I expected it to be +1 !
Regards,
|
|
|
|

|
Interesting... the function used is p-invoking the windows api.
I will run some tests on it and try to get a valid response from it.
Thanks!
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Excellent project. But I have one question. What is the easiest way to get maximum key from RaptorDB?
|
|
|
|

|
Interesting question...
There is no method to do this efficiently at the moment I will try to put it in.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Btw. Is raptorDB manage database file space effectively? I ask because I want use raptorDB to implement simple embedded persistent queue. Do you have in plan implement shrink-like or compact-like methods to prevent grow up database file infinitely - is this methods will be necessary?
|
|
|
|

|
I will probably add a "compacting" feature in the future.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I want to use RaptorDB with MONO on Linux. It works prefect with only minimal changes.
The only thing is to replace the hard-coded path-seperator "\\" with the .NET path field
"Path.DirectorySeparatorChar" in the following files.
BitmapIndex.cs
MGIndex.cs
KeyStore.cs
mylogger.cs
So in a few minutes the RaptorDB is cross-platform ready with MONO. Maybe you can change this in the next version of RaptorDB.
br,
Alex
|
|
|
|

|
Yes, that is about it although in the Doc version I had to change codedom code to Reflection.Emit also (I was really chuffed when it worked on my Asus TF700).
I will update the KV version soon as there a couple of enhancements and fixes for it.
Thanks Alex!
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
I have a scenario where I just need to test for the existence of a key in the index. Here is an addition to the KeyStore.cs file to just return if a key exists.
public bool Exists( T key ) {
lock ( _lock ) {
int off;
return _index.Get( key, out off );
}
}
Thoughts?
|
|
|
|

|
Absolutely spot on! I will add this in the next release. Its the man, not the machine - Chuck Yeager If at first you don't succeed... get a better publicist If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Can more processes (on the same host) open and read/write the same database?
Thanks.
|
|
|
|

|
No, the database files can only be opened by one process. You can however have a service like host which you can connect to via TCP and have multiple processes work with (this is implemented in the document version but not here).
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|

|
Why max cpu usage is 25% even on read and write as exe.
I tested on SSD, Raid5 and RamDisk, all benchmarks have similar time.
10 millions : ~25 sec set, ~45 sec get
Isn't it supposed to use max cpu and why there is no difference on ssd, raid5 and ramdisk?
Cpu is I5 2500, Quad core 3.3 Ghz
Raptor 2.5 version
Still amater
|
|
|
|

|
RaptorDB has been designed to be sensitive to your CPU and mostly your RAM speed not the storage speed.
You will get better performance mostly if you upgrade your memory say from DDR2 to DDR3 etc.
The storage speed only comes into play when the engine is storing to disk and this is mainly done in the background so you wouldn't notice (it will become markedly apparent when you shutdown).
This would also be dependent on the amount of data you are storing (in the main storage file) so in the test program we are storing small ~30 bytes per record so the OS and harddisk caches also smooth this out.
Its the man, not the machine - Chuck Yeager
If at first you don't succeed... get a better publicist
If the final destination is death, then we should enjoy every second of the journey.
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
|
Even faster Key/Value store nosql embedded database engine utilizing the new MGIndex data structure with MurMur2 Hashing and WAH Bitmap indexes for duplicates. (with MonoDroid support)
| Type | Article |
| Licence | CPOL |
| First Posted | 18 Jan 2012 |
| Views | 130,816 |
| Downloads | 3,678 |
| Bookmarked | 125 times |
|
|