Shop OBEX P1 Docs P2 Docs Learn Events
v2.0.2 of Memory Storage Management Released — Parallax Forums

v2.0.2 of Memory Storage Management Released

Bobb FwedBobb Fwed Posts: 1,119
edited 2011-02-18 11:28 in Propeller 1
This is the largest single update since release. It was originally going to be a minor update and then a major, but a lingering bug held off the minor update.

Download the heavyweight and welterweight versions here: http://obex.parallax.com/objects/493/

Here are the key updates (from 1.3.3 to 2.0.0):
Fixed a bug that would make values become unset if name hashes collided and the first values set were renamed. Because of this bug, I highly encourage everyone who uses this object to update immediately.
Deleting no longer means wasting space. The software now "reserves" the name and data space used by deleted values, so they can be used when a new item of the same type is created.
Hash algorithm has been optimized in both speed and results. Reducing the likelihood of collision between consecutive naming. The new hash also allows for non-power-of-two table sizes (for added flexibility in working around existing code).
Added methods to allow arrays to be larger than the previous 255 byte limit (strings can be stored as arrays to allow for longer than 255 byte strings).
Changed some method names for terminology and logical reasons.
Optimizations in many of the methods.

Changes in 2.0.1:
Added a method to retrieve names with a wild card.
Fixed a couple minor name listing bugs.
Added a method to allow retrieving just specific parts of a stored array, so there is no need to cycle through the entire array to get one small portion of it.
And a couple other minor changes.

Changes in 2.0.2:
Name list can now be sorted alphabetically.
Added a method to get values of a specified type.

Post any questions, comments, suggestions, feature requests, or bugs on here. There were quite a few changes, and I think I've tested everything pretty thoroughly, but please post anything that does not function as one would expect, and I will look into it.
«1

Comments

  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-01-27 18:12
    Wow, I was still digesting your v1.3.3 just 3 days ago ... Great.

    Just a minor note, in your "_README_.txt" file, you mentioned "memory_demo2.spin" but actual file is "memory_demo.spin"
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-01-27 18:53
    MacTuxLin wrote: »
    Wow, I was still digesting your v1.3.3 just 3 days ago ... Great.

    Just a minor note, in your "_README_.txt" file, you mentioned "memory_demo2.spin" but actual file is "memory_demo.spin"
    Yeah, I have the file names slightly different in my system than what I release them as. I didn't know anyone actually looked at the READMEs, it's generated automatically when you archive an object.

    I don't foresee any more updates to this object for a while (other than catching the lightweight version up to 2.0 and of course). I had to get the deletion feature in for a project I am working on, and I discovered the rename bug while working on that. So now I have both of those out of the way, I will be working on other things, like my 10Mb prop-to-prop communication object (possibly getting it to 20Mb!) -- either way, there are features I need to add (for this same project) and some functionality anomalies that need to be fixed -- I've been getting requests for this anyway.

    Please, let me know what you think of this object (and the added features).
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-01-27 19:22
    Yes, I've made it a point to read as much info as I can that are dished out especially when guys like you put in so much effort on these amazing objects that made my life a lot easier & proven Propeller is the right choice! Thanks again.

    I'll be studying & testing your v2.0.0 over the weekend as my current project badly need such features. Also, I've already starting working on multi-prop (got 2 to talk but hope to increase the bandwidth) so I'll definitely look into your next object next month. :lol:
  • HumanoidoHumanoido Posts: 5,770
    edited 2011-01-27 23:27
    You could also make the most simple demo program with the fewest code lines. It could be more challenging to do that, but it would be easier to understand and, at least for me, I could develop apps from it quicker.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-01-28 08:20
    Humanoido wrote: »
    You could also make the most simple demo program with the fewest code lines. It could be more challenging to do that, but it would be easier to understand and, at least for me, I could develop apps from it quicker.
    I can do that. The demo really is a script I use to test functionality and bug test, then modify so it is a little more readable. But it demonstrates the primary functions, storing data, recalling data, editing, renaming, etc. I could make a more simple one.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-01-31 00:40
    Hello Bobb,

    I've been reading & testing out your v2.0.0. I seems to get a hang of it & its real helpful. I have a request if it doesn't sounds silly.

    In MySQL, I usually could perform a query & store that to ram. E.g. select field from table where field like "LED_*". I'm thinking of using 1 EEPROM's upper 32k for storing all mounted prop's setup & pin assignments. I know I could write a query function to do that but thought you might have a better way of doing this. By doing this, I could query all "LED_*" pin assignment & send them over to LED module & query all "Servo_*" pin to Servo module in another prop etc.

    I've tried with output from PST:
    *** *** *** *** ***
    Storing Data
    *** *** *** *** ***
    LED_Pw = 10
    LED_3v3 = 11
    LED_DB1 = 12
    LED_DB2 = 13
    LED_DB3 = 14
    LED_DB4 = 15
    Servo_1 = 16
    Servo_2 = 17
    Servo_3 = 18
    Servo_4 = 19
    Servo_5 = 20
    Servo_6 = 21
    Servo_7 = 22
    *** *** *** *** ***
    Storing Data ... Completed
    *** *** *** *** ***
    LED_DB1 Pin is: 12
    Storing LED_DB3 string into stringAdd
    Now try retrieving it ... : 14
    
    

    Added: Hmm ... I think maybe I could use the create_array instead.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-01-31 08:31
    Well, that is quite possible. It won't be the fastest thing in the world, but it will be faster than you doing it externally. Already the get_name_list method works like NOT LIKE "~*".
    A wild card at the end will be fairly fast, a wild card at the beginning will be a bit slower, two wild cards (beginning and end) will be quite slow. And I don't really see being able to do more than that (no internal wild cards). I can write it up and see how it goes.

    Yes, storing the values as an array would be faster to store and access, and use less memory (because there is only one name being stored).

    Thanks for the input! Let me know any other ideas or problems.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-01-31 16:34
    Attached is my first crack at wild cards. It should get better than that. Currently the [new] get_pattern_name_list method only allows one wild card, and it must be at the beginning or the end.

    I'll work on getting an unlimited wild card system (as it should be).

    Let me know if that functions as you'd expect.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-01 01:42
    Fantastic! Thanks Bobb. Sadly, I'm currently traveling & will only be back home this Saturday (darn, should have brought my prop board with me, arhh!). I'll let you know by next Monday.

    Cheers!!
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-01 08:13
    MacTuxLin wrote: »
    Fantastic! Thanks Bobb. Sadly, I'm currently traveling & will only be back home this Saturday (darn, should have brought my prop board with me, arhh!). I'll let you know by next Monday.

    Cheers!!
    By then I will likely have a more functional version of the pattern method.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-01 16:49
    Here is a new version. It is my 2.0.1 release candidate #1. Here are changes since last stable release:

    Added get_pattern_name_list, which returns names based on a wild card (*) pattern. RC1 and newer allows unrestricted wild card use.
    Fixed bug where if you had deleted items and called get_full_name_list then get_name_list, items were in the name table twice
    Changed set_name_pointer so it doesn't call get_name_list, it just uses the last get_*name_list returned value as the maximum value (faster and more functional with the new get_*name_list method)..
    Added set_array_pointer to allow retrieving just specific parts of an array, without having to cycle through or read the entire array.
    Fixed overrun behavior in get_*_parts_array that occurred if you tried to access more elements than existed in an array.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-02 09:45
    Bobb Fwed wrote: »
    The lightweight version still has the renaming bug, I will be working on that. Be looking for the release of v1.3.4 for the bug fix.

    I forgot to mention, I have released version 1.3.4 of the lightweight branch. Download it here: http://obex.parallax.com/objects/671/
  • jeff-ojeff-o Posts: 181
    edited 2011-02-05 13:57
    I'm having a bit of trouble with the lightweight version. My project is basically a datalogger; I've got a timer IC activating a load switch every two hours. When the Propeller powers up, it does its thing, increments a few counters stored in EEPROM, and then sends a signal to the timer to reset.

    The issue I'm having is that the counter seems to skip forward to the next binary power once it reaches a certain number! So for instance, it will count 30,31,128,129,130...

    I set up a separate program to test this, which consists of an initialization of the names and then a loop that increments the counter. Disregard some of the extra comments and odd code in there; they are put in by 12blocks.
    pub _pub0'*(32,73):cognew($0,@_s$0)
     {Resets all of the permanent counter values to zero.}'*:{$}
     _eeprom.check_edit_create_long(string("count"),500)'*:_eeprom.check_edit_create_long($,$)
     _eeprom.check_edit_create_long(string("dry"),0)'*:_eeprom.check_edit_create_long($,$)
     _eeprom.check_edit_create_long(string("wet"),0)'*:_eeprom.check_edit_create_long($,$)
     _eeprom.check_edit_create_long(string("right"),0)'*:_eeprom.check_edit_create_long($,$)
     _eeprom.check_edit_create_long(string("darkness"),0)'*:_eeprom.check_edit_create_long($,$)
     {loops "moisture" and "light" readings so calibration of the potentiometer can be done.}'*:{$}
     _adc.start(13,12,11,10,2,2,12,1)'*:_adc.start($,$,$,$,$,$,$,$)
     repeat'*:repeat
      moisture:=_adc.getval(1)'* 1:$:=$
      light:=_adc.getval(0)'*:$:=$
      count:=_eeprom.get_dec(string("count"))'*:$:=$
      _bsl.pause(500)'*:_bsl.pause($)
      _eeprom.check_edit_create_long(string("count"),count+1)'*:_eeprom.check_edit_create_long($,$)
      _bsl.pause(500)'*:_bsl.pause($)
    

    I'm watching the count value on the terminal. The "jump point" also seems to depend on the values I plug into the object, I can make it jump at either 32 or 64. And yeah, my EEPROM chip is 64K so I've got lots of room to store 5 or 6 longs. I can write any number I want with no issue. I just can't figure out why it isn't incrementing properly.

    So what's going on here? Any ideas? Perhaps some weird interaction between 12blocks and this object?
  • kuronekokuroneko Posts: 3,623
    edited 2011-02-05 21:11
    jeff-o wrote: »
    So what's going on here? Any ideas? Perhaps some weird interaction between 12blocks and this object?
    Possibly. FWIW, I tested the increment loop (debug serial output) on my demo board and an incrementing loop is what I got. No skips whatsoever. I assume you initialise the object in some other method.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-07 02:17
    Hello Bobb,

    Using some command line code from SD2.0 to make your EEPROM DB looks like the ancient DBASE III+, your get_pattern_name_list() works GREAT!!!
    >_ select LED*
    EEPROMDB: select LED*
    LED_DB1
    LED_DB2
    LED_DB3
    LED_DB4
    LED_3v3
    LED_Pw
    >_ select Servo*
    EEPROMDB: select Servo*
    Servo_7
    Servo_6
    Servo_5
    Servo_4
    Servo_3
    Servo_2
    Servo_1
    >_ select *
    EEPROMDB: select *
    test223
    byte val1
    LED_DB1
    LED_DB2
    LED_DB3
    LED_DB4
    string test6
    string test3
    string test1
    word val2
    word val1
    long val2
    testing
    stringers
    bytearray
    stringers as
    LED_3v3
    longlongarray
    wordarray
    longarray
    Servo_7
    Servo_6
    Servo_5
    Servo_4
    Servo_3
    Servo_2
    Servo_1
    ~L00000
    test2
    test4
    LED_Pw
    ¼est1
    >_
    

    Thank you!!
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-07 09:00
    Glad to hear it.

    Any final bugs or [small] feature requests? If not, I will update the welterweight branch and release version 2.0.1 on the obex.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-07 19:57
    Got it, could you give me till end of today while I test it out? And ... if I'm asking too much, please pardon me & drop the idea but ... would it be possible to include an alphabetical sorting feature as well :tongue:?

    Thanks a lot!
  • jeff-ojeff-o Posts: 181
    edited 2011-02-07 20:31
    kuroneko wrote: »
    Possibly. FWIW, I tested the increment loop (debug serial output) on my demo board and an incrementing loop is what I got. No skips whatsoever. I assume you initialise the object in some other method.

    Ok, good to know. I'll do a comparison between my custom board and my propeller dev board to see if there's a difference.
  • jeff-ojeff-o Posts: 181
    edited 2011-02-07 20:47
    Now I'm unable to reproduce the issue I was having before. It's happily incrementing with no problems at all, no changes to hardware or software. I have no explanation for it.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-08 08:42
    MacTuxLin wrote: »
    Got it, could you give me till end of today while I test it out? And ... if I'm asking too much, please pardon me & drop the idea but ... would it be possible to include an alphabetical sorting feature as well :tongue:?

    Thanks a lot!
    I will look into this, it's likely to be some some brute force organization done after the call of the get_*name_list methods. I will ask the knowledge base on the forum to see how easy it may be.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-08 10:31
    Well, I have just released v2.0.1:
    Changes in 2.0.1:
    Added a method to retrieve names with a wild card.
    Fixed a couple minor name listing bugs.
    Added a method to allow retrieving just specific parts of a stored array, so there is no need to cycle through the entire array to get one small portion of it.
    And a couple other minor changes.

    @MacTuxLin: I didn't get any hits on pre-written sorting code, so I will have to write and test it, which will take a while since it's not overly easy sorting strings that only addresses can be stored in an array. There is always room for it in v2.0.2.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-08 18:13
    :smile: Thank you, Bobb. Yes, my way of using your object didn't seems to see any errors so far.

    So, v2.0.1 is working out great for me for now. I'm actually planning on writing up a mini-dBase-III+-like interface for accessing the EEPROM using your object partly for organizing my boards & also allowing our young users to tinker with simple database. Would it be ok if I know how I could send you the "wish-list" for your next versions? :tongue:
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-09 08:34
    Right here is a perfect place for feature requests. I can't say I will get to all of them, but I will try to determine what is important to the community (and my projects) and decide what is worth the time.

    Or just PM me.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-09 14:05
    MacTuxLin wrote: »
    ... would it be possible to include an alphabetical sorting feature as well
    I have completed this feature, but it is quite slow. [As far as I can tell] I am using the fastest possible method (insertion sorting) without pissing through obscene amounts of stack space.

    With the basic I2C driver (SPIN), running my testing demo (only 16 names), it takes over 39 million cycles just to sort (almost a half second at 80MHz).
    With the pasm I2C driver, running the same demo, it takes only 7.7 million cycles to sort.

    This massive difference is because the sort method must read through each name from the EEPROM a number of times. The only real way to speed this up would be to place the entire name space into RAM, but that will likely use up a large amount of RAM, though it really depends on how the program is setup in the final configuration. The default values would require 256 longs (1024 bytes).

    What are your thoughts? Is this too slow to use? Does anyone even use the PASM I2C (it sucks to burn a cog for EEPROM control)? How much name space do you use? Is it an option to place the entire name space into RAM?
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-09 19:50
    Certainly Bobb. Your current object is more than I need to do my projects for now. :smile:

    It might sound silly but may I know if it would be faster (or make sense) to load the PASM I2C at will? Meaning, if I need to sort, I'll load this to a cog, sort, then cogstop?

    Thanks a lot!

    Added: I've tested adding 120, which is what I'll need, and it worked out great enough for me.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-10 09:08
    MacTuxLin wrote: »
    It might sound silly but may I know if it would be faster (or make sense) to load the PASM I2C at will? Meaning, if I need to sort, I'll load this to a cog, sort, then cogstop?
    Loading PASM at will would work great, except the PASM driver doesn't have any way to stop the cog after it is started. Plus, having both objects included adds another 300 longs to the already quite large program space.

    And it doesn't appear that just adding a cogid/cogstop to the end of the PASM stopfunc routine, and removing the loop in SPIN does the trick. For some reason, with this setup, it doesn't sort at all. My guess is that it has something to do with the SPIN I2C. I issue the stop command, but that looks like the pins are being held high, even if they are set as input. Some conflict with the two cogs and the IOs.
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-10 15:36
    Bobb Fwed wrote: »
    With the basic I2C driver (SPIN), running my testing demo (only 16 names), it takes over 39 million cycles just to sort (almost a half second at 80MHz).
    With the pasm I2C driver, running the same demo, it takes only 7.7 million cycles to sort.
    I squeezed some more speed out of the string compare method (used extensively throughout all the sort methods). The current speed is now 29 million cycles for SPIN and 6.1 million cycles for PASM.

    I have been using insertion sorting, but after some testing, I have found that shell sorting may be faster. With integers, it is way faster, but with strings, it is [sometimes] only marginally faster. Though the testing was done without any EEPROM access, so it is possible that insertion sorting still reads from EEPROM less (or something). But I will have to test it to find out.

    It's amazing what a few hours of testing five different sorting methods will produce.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-10 19:35
    Wow, amazing! I can't wait to try them out :smile:
  • Bobb FwedBobb Fwed Posts: 1,119
    edited 2011-02-17 12:52
    So I know it's been a while. Longer than I was intending, but now I need your opinion/advice.
    I have two sorting methods and I am trying to figure out which to use. One is insertion sort, the second is shell sort.
    The relative speed of the two changes as the number of elements to sorts changes. Insertion sort is fast for small lists, shell sort is faster for long lists.

    Insertion is 40% faster than Shell at 17 entries. (0.46s vs. 0.76s)
    Insertion is 28% faster than Shell at 34 entries. (1.52s vs. 2.11s)
    Insertion is 7% slower than Shell at 60 entries. (4.26s vs. 3.96s)
    Insertion is 32% slower than Shell at 120 entries. (14.08s vs. 10.60s)

    Insertion goes up approximately 3.3 times every time the entry count doubles.
    Shell goes up approximately 2.7 times every time the entry count doubles.

    So the question is: which would you prefer? Either slightly slower when the times are short, or faster when the times are long? Either way, over a couple seconds seems like ages and maybe not practical on this microcontroller. With the PASM I2C the speeds are about 5 times faster.
  • MacTuxLinMacTuxLin Posts: 821
    edited 2011-02-18 02:16
    Hello Bobb,

    Yeap, I know, crazy week for me too. OK, I'm not sure about the rest of the members but a couple of seconds might seems a bit obvious at my end, though. Or how about this:

    1. select LED_GroupA*
    shows up 10 entries & just sort these 10?

    So at any one time, the number of entries to sort is less than 20? Would this work?
Sign In or Register to comment.