Forum Discussion

qqdixf5_74186's avatar
qqdixf5_74186
Icon for Nimbostratus rankNimbostratus
May 27, 2009

v10 class feature

We are migrating our iRules to v10 and need to change the way we access datagroups. First, thank you for the detailed explanation about the new class feature(http://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=2309).

 

 

So now we have two approaches to get the data. We can use the various class commands to access the elements within a datagroup directly , or get the data back as a list and use tcl list commands. Which approach do you recommend? Is one better than the other?

 

 

Thanks!
  • I'd turn timing on and find out which was most efficient, and go with that version. I would think direct access would be quicker than multiple operations, but testing will prove that out.
  • Have a question on the new [class] commands.

     

     

    My test datagroup contains elements like below.

     

    {

     

    {vip1_a 123.4.5.6}{}

     

    {vip2_a 123.4.5.7}{}

     

    {vip3_a 123.4.5.8}{}

     

    {vip1_b 123.4.5.9}{}

     

    }

     

     

    Here is my little iRule to figure out how many vips are for "a" and for "b". I only care about the names of the elements in this case.

     

     

    set vipsForA [class names -nocase myDataGroup *_a*]

     

    set vipsForB [class names -nocase myDataGroup *_b*]

     

    log local1. "vipsForA = $vipsForA" --- this gives me "{vip2_a 123.4.5.7} {vip1_a 123.4.5.6} {vip3_a 123.4.5.8}"

     

    log local1. "vipsForB = $vipsForB" --- this gives me "vip1_b 123.4.5.9"

     

    log local1. "size of vipsForA = [llength $vipsForA]" --- this gives me 3

     

    log local1. "size of vipsForB = [llength $vipsForB]" --- this gives me 2

     

     

    Should the last statement be 1 instead?
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    I basically agree with citizen_elah. Accessing the data via the class command is almost certainly going to be faster than first turning it into a list and then accessing the list. You could use the timing commands if you want to check for sure.
  • spark_86682's avatar
    spark_86682
    Historic F5 Account
    Given the way the class command currently operates, no. If you look carefully, the vipsForA variable is a list with 3 elements. However, the vipsForB variable is a string with two words in it. When you do an llength of it, it treats it as a list, and gives you the correct answer that there are two items there. (I'm being a little fuzzy here, since Tcl doesn't have strictly typed variables)

    There's no super elegant way around this. The best way is probably to make your class key names list elements if they have spaces in them. For your example, that would look like:

     
     class myDataGroup { 
     {"{vip1_a 123.4.5.6}"}{} 
     {"{vip2_a 123.4.5.7}"}{} 
     {"{vip3_a 123.4.5.8}"}{} 
     {"{vip1_b 123.4.5.9}"}{} 
     } 
     

    Now that I implement this, though, I notice that it is displayed incorrectly in the GUI; I'll file a bug for that shortly. Anyway, this gives you consistent behavior:

     
     set resultA [class names -nocase myDataGroup *_a*] 
     set resultB [class names -nocase myDataGroup *_b*] 
     log local0. "resultA: $resultA  countA: [llength $resultA]" 
     log local0. "resultB: $resultB  countB: [llength $resultB]" 
     

    gives:

     
     resultA: {{vip1_a 123.4.5.6}} {{vip2_a 123.4.5.7}} {{vip3_a 123.4.5.8}}  countA: 3 
     resultB: {vip1_b 123.4.5.9}  countB: 1 
     

    If you don't want to go that route for whatever reason, then you need to workaround Tcl's "spaces delimit list elements" behavior, and do something like:

     
     set result [class names -nocase myDataGroup *_a*] 
     if { $result contains "{" } { 
       set length [llength $result] 
     } else { 
       set length 1 
     } 
     log local0. "result: $result  length: $length" 
     

    Hope this helps.