[Gene Kraybill]
> create a large application structure to hold the configuration
> settings for each customer.
I've done several sets of similar systems in the past. What follows has
worked for me, but I am also interested in hearing what others have done.
When you are going to be using deep levels of structures/arrays/etc, I find
its easiest to create shortcuts (references) to them, which makes the code a
bit easier to read. Since structures are always passed by reference unless
you explicitly copy them, it's also pretty efficient. For example:
<CFSET Config=Application.Str_ConfigCust>
I also like to use the word 'This' to denote local references to objects
that I'm going to be using alot. So, if you are working with a singe
customer over the entire page, you could create ThisCustomer:
<CFSET ThisCustomer=Config[CustomerID]>
To me, this is infinitely easier to read and remember than traipsing down
the object heirarchy each time. Also, I imagine it's probably more
efficient. (I've never done tests on this, tho, has anyone else?) To get
to that Customer's config options, you could then use:
<CFSET ThisOption=ThisCustomer[OptionID]>
By the way, you may already be aware of this, but you don't have to convert
numbers to strings to make CF happy. Dereferencing a struct as ["1"] or [1]
both work just fine. :) Also, if you have a static string for a key (you
know what its name will always be) you don't have to deref it as a string.
Like so:
<!--- Sure, this works ... --->
<CFSET ThisSomeQuery=ThisCustomer["SomeQuery"]>
<!--- But so do these ... --->
<CFSET ThisSomeQuery=Application.Str_ConfigCust[1].SomeQuery>
<CFSET ThisSomeQuery=ThisCustomer.SomeQuery>
<CFSET
ThisFormElement=Application.Str_ConfigCust[1].Form[2].FormItemsArray[5][8]>
I tend to prefer doing it this way, as I come from a C/Perl background and
that just seems more natural to me. :) But, each to their own.
> We also need to hold the order form data, and there can be multiple forms]
I'm working on a similar system this week, as a matter of fact. And yep,
your idea is right:
<CFSET ThisForm=ThisCustomer.Form[FormID]>
<!--- Watch out for this one ... --->
<CFSET TheseItems=ThisForm.FormItemsArray>
However, you need to be wary of arrays. Arrays *copy* instead of reference
by default. So, if you are going to be changing data, you can't do this:
<!--- Wrong! This is a local copy! --->
<CFSET TheseItems[5][8]="foo">
<!--- The right way is the long way --->
<CFSET ThisForm.FormItemsArray[5][8]="foo">
<!--- or, in combination with the first line: --->
<CFSET TheseItems[5][8]="foo">
<CFSET TheseItems[5][9]="bar">
<CFSET TheseItems[5][10]="baz">
<CFSET TheseItems[5][11]="quux">
<CFSET ThisForm.FormItemsArray=TheseItems>
I'd use that last one if you are going to be doing lots of updates to the
form data. That way you aren't having to make CF walk the object tree every
time you do an update. You *really* need to be conscious of which elements
of your object tree are arrays and which are structures. They may be
accessed the same, but since one copies and one references, you can get
yourself into alot of trouble. (I fell into this trap on Monday, as a
matter of fact, and about kicked myself when I figured out what I was
doing.)
> I've never attempted to use arrays, structs and queries to this
> level of complexity, or mix and match them like this in the same
> structure.
Fun, eh? :)
> The advantage it seems to offer is that all config data will be
> held in a single structure, and it'll be easy to reference it by
> customer number and loop over it when needed.
Oh yeah. And when you really start using it for serious in-memory caching
it will dramatically speed up your pages. I use it to eliminate as many db
queries per page as possible. With OLEDB or Native access it may not matter
so much, but every little bit helps. Especially if you're just doing lots
and lots of reads and very few writes.
> But it's also rather complex and the var references are long
> and unwieldy,
Try the system that I use, with the local references. I think that this
will really help. It lets you think about small pieces of code (just the
things that pertain to ThisCustomer or TheseItems) and not have to think
about the entire object tree.
> I need to figure out whether storing all this config data in
> an application structure will cause memory problems.
I haven't had *any* memory problems with the systems I've developed. I'm
actually inclined to think that in certain cases it can actually take up
less memory than hitting the db all the time. This might be rare, but
unless you are storing several hundred or thousand sets of objects, it
really shouldn't be an issue. You said you were doing a couple dozen?
Pfft. No problem.
> And how could we roughly estimate how much memory a complex
> structure like this will require?
I've oft wondered this myself. The closest I can do is look at the memory
usage, initialize the application and load all of the data, and then look
again. If there is a better way I'd love to know it.
Now, let's talk about locking for a moment, since that seems to be such a
hot topic of debate. However, I may be doing it wrong so I'd love to hear
what others have to say. I'm not too bothered by locking, as I just do it
at the most granular level that I can. That is, if I'm working on a
customer, then I create a lock for just that customer:
<CFLOCK NAME="Customer#CustomerID#" ...>
<CFSET ThisCustomer=Config[CustomerID]>
<!--- Do whatever ... --->
<CFSET ThisCustomer="">
</CFLOCK>
Again, for a system that is mostly reads and adds (not inserts and updates)
this works wonderfully. However, you have to be wary about being too
granular in a system that is constantly being updated. For example, I
wouldn't want to lock on a TheseItems level in a system where the entire
customer may concurrently be deleted from the system. (At which point I
would be working on data that either no longer existed or wasn't relevant.)
In such a case, you may want to lock on the entire customer level. (Which
has the added advantage that even if the customer has 15 browser windows
open at the same time, his access is still single-threaded for all intents
and purposes.)
Again, this is just what I've done, and I haven't had any problems with it.
I'd also like to hear what others have done.
-Rick
------------------------------------------------------------------------------
Archives: http://www.mail-archive.com/[email protected]/
To Unsubscribe visit
http://www.houseoffusion.com/index.cfm?sidebar=lists&body=lists/cf_talk or send a
message to [EMAIL PROTECTED] with 'unsubscribe' in the body.