Raised This Month: $12 Target: $400
 3% 

Add two KeyValue files together


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Phil25
AlliedModders Donor
Join Date: Feb 2015
Old 04-30-2015 , 08:28   Add two KeyValue files together
Reply With Quote #1

Hello everyone!

I've been trying to figure out how to merge two files together using a clean and safe way, without destroying/replacing any keys or duplicating sections. For example:

File #1

File #2

Desired File


Any help with this greatly appreciated!
Phil25 is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 04-30-2015 , 10:55   Re: Add two KeyValue files together
Reply With Quote #2

The biggest issue you have is being insane enough to store stats in a kv instead of doing it the appropriate way (that is dbs).
My general advice.
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.
Dr. Greg House is offline
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
Old 04-30-2015 , 11:43   Re: Add two KeyValue files together
Reply With Quote #3

Here are the steps I would go about merging those:
  • Load the files into KeyValues handles A and B.
  • (Optional) Create another KeyValues handle for the merge if you need to keep the original handles intact.
  • Iterate over A keys using GotoFirstSubKey() and GotoNextKey(), grabbing the current key using GetSectionName()
  • Check if A's key exists in B.
    • If yes, grab B stats and store the sum in the output handle (or A's handle if no output handle).
    • If no and are using an output handle, store A's data in the output handle.
  • Iterate over B keys same method as A.
  • If B's key does not exist in A, store B into the output handle (or A's handle if no output handle).

And there you will have them merged.
__________________
No private work or selling mods.
Quote:
Originally Posted by xPaw View Post
I love you exolent!
Exolent[jNr] is offline
Phil25
AlliedModders Donor
Join Date: Feb 2015
Old 04-30-2015 , 13:51   Re: Add two KeyValue files together
Reply With Quote #4

Quote:
Originally Posted by Exolent[jNr] View Post
Here are the steps I would go about merging those:
  • Load the files into KeyValues handles A and B.
  • (Optional) Create another KeyValues handle for the merge if you need to keep the original handles intact.
  • Iterate over A keys using GotoFirstSubKey() and GotoNextKey(), grabbing the current key using GetSectionName()
  • Check if A's key exists in B.
    • If yes, grab B stats and store the sum in the output handle (or A's handle if no output handle).
    • If no and are using an output handle, store A's data in the output handle.
  • Iterate over B keys same method as A.
  • If B's key does not exist in A, store B into the output handle (or A's handle if no output handle).

And there you will have them merged.
Thank you for the plan, I guess I'll have a bit of a buisy night ;)


Quote:
Originally Posted by Dr. Greg House View Post
The biggest issue you have is being insane enough to store stats in a kv instead of doing it the appropriate way (that is dbs).
My general advice.
Yea, I thought this could be done a neater way, I just didn't know that yet. Seemed all right at the time when I started to write that plugin. We all had this young and crazy time... but on the upside, others can learn my mistakes. Would this be really such a pain in the future though? :s

And besides, although I'm trying to do this with files holding player statistics, I've never mentioned that in this thread (except for the examples). So it's kinda universal and might help others whatever they'll try to accomplish.
Phil25 is offline
Dr. Greg House
Professional Troll,
Part-Time Asshole
Join Date: Jun 2010
Old 04-30-2015 , 14:00   Re: Add two KeyValue files together
Reply With Quote #5

Quote:
Originally Posted by Phil25 View Post
Would this be really such a pain in the future though? :s
Yes.
__________________
Santa or Satan?

Watch out when you're paying people for private requests! Most stuff already exists and you can hardly assess the quality of what you'll get, and if it's worth the money.
Dr. Greg House is offline
Powerlord
AlliedModders Donor
Join Date: Jun 2008
Location: Seduce Me!
Old 04-30-2015 , 16:15   Re: Add two KeyValue files together
Reply With Quote #6

Even if you're using a SQLite database, it's still better than KeyValues.

Having said that, if this is for multiple servers (even on the same machine) you'll probably want a MySQL database. Unless the PostgreSQL driver is working these days... haven't looked at it lately.
__________________
Not currently working on SourceMod plugin development.
Powerlord is offline
Phil25
AlliedModders Donor
Join Date: Feb 2015
Old 05-02-2015 , 22:08   Re: Add two KeyValue files together
Reply With Quote #7

All right, so I've taken a little different approach than the one Exolent suggested.

I've created an enum with all the keys of the section including the section name itself and made it into two arrays:

Code:
enum _:KVKeys{     String:s_section[32],     i_score,     i_kills,     i_deaths, }; new array_a[16][KVKeys]; new array_b[16][KVKeys];

Then cached key values from two files I wanted to merge in them:

Code:
static String:KVPathA[PLATFORM_MAX_PATH]; static String:KVPathB[PLATFORM_MAX_PATH]; static String:KVPathC[PLATFORM_MAX_PATH]; public OnPluginStart(){     BuildPath(Path_SM, KVPathA, sizeof(KVPathA), "data/[FILENAME]_a.txt");     BuildPath(Path_SM, KVPathB, sizeof(KVPathB), "data/[FILENAME]_b.txt");     BuildPath(Path_SM, KVPathC, sizeof(KVPathC), "data/[FILENAME]_c.txt"); //'C' will be A and B merged     CacheFileA(); //Caching the A file     CacheFileB(); //Caching the B file     CreateFileC(); //Create the merged file }
CacheFileA()
CacheFileB()


And then created the final file using the two arrays:

CreateFileC()


NOTE: For some reason in the final file the root section is treated like a subsection. Meaning that at some point in the file there will something like:
I haven't looked into on how to fix it as the solution is to simply remove those lines and everything's good to go.

FINAL NOTE: Please don't hate on me for having player stats in a KV file, I'll port them to MySQL once I learn how everything works, I swear.. ;~;

Last edited by Phil25; 05-02-2015 at 22:12.
Phil25 is offline
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
Old 05-04-2015 , 11:38   Re: Add two KeyValue files together
Reply With Quote #8

That method is much slower and uses more memory as well. I don't see the reason to do it that way.
Also, you should use an if statement when jumping to keys in case it fails, even if you tell it to create the key when it doesn't exist.

Code:
if (KvJumpToKey(myKv, "Key", true)) {     KvSetNum(myKv, "stuff", 1);     KvGoBack(myKv); }

That way you don't "Go Back" when it never moved in the first place.
__________________
No private work or selling mods.
Quote:
Originally Posted by xPaw View Post
I love you exolent!
Exolent[jNr] is offline
Phil25
AlliedModders Donor
Join Date: Feb 2015
Old 05-04-2015 , 11:51   Re: Add two KeyValue files together
Reply With Quote #9

Quote:
Originally Posted by Exolent[jNr] View Post
That method is much slower and uses more memory as well. I don't see the reason to do it that way.
Also, you should use an if statement when jumping to keys in case it fails, even if you tell it to create the key when it doesn't exist.

That way you don't "Go Back" when it never moved in the first place.
Noted, I didn't use if statements only because I had some error before related to that part and I didn't add them again.

Other than that, I do understand that it uses more memory, but I didn't really mind since I was only to use it once.
Phil25 is offline
Potato Uno
Veteran Member
Join Date: Jan 2014
Location: Atlanta, Georgia
Old 05-04-2015 , 12:55   Re: Add two KeyValue files together
Reply With Quote #10

Is keyvalues really that much less efficient than databases in terms of data storage?

I figure adding something to RAM is faster than performing I/O, especially if you have no intention to store the data to disk (e.g. stats that are recorded during a round, and then are discarded on round finish).
Potato Uno is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 09:50.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode