OpenFlow Rule Metadata - opendaylight

I would like to understand how the Metadata are calculated in an Open Flow rule.
cookie=0x6900000, duration=228925.519s, table=17, n_packets=384, n_bytes=35436, priority=10,metadata=0xf30000000000/0xffffff0000000000 actions=write_metadata:0xc000f30000000000/0xfffffffffffffffe,goto_table:211
Example: I have a flow very similar to this.
How are exactly the Metadata are Calculated.
And how to Intrepret the Metadata Values and Mask
Some says
new_metadata = old_metadata & ~mask | value & Mask
Honestly i do not understand it, could some one explain it

The purpose of the value and metadata fields in the write_metadata action are explained in the Open vSwitch documentation:
write_metadata:value[/mask]
Updates the metadata field for the flow. If mask is omit‐
ted, the metadata field is set exactly to value; if mask
is specified, then a 1-bit in mask indicates that the
corresponding bit in the metadata field will be replaced
with the corresponding bit from value. Both value and
mask are 64-bit values that are decimal by default; use a
0x prefix to specify them in hexadecimal.
The preceding explanation is indeed equivalent to:
new_metadata = (old_metadata & ~mask) | (value & mask)
In other words, we first erase bits of the old metadata value set to 1 in the mask (old_metadata & ~mask) and then set to 1 the bits of the value that are also set to 1 in the mask (| (value & mask)).

Related

Change All Value Labels to Numerics in SPSS

I need to change all the value labels of all my variables in my spss file to be the value itself.
I first tried -
Value Labels ALL.
EXECUTE.
This removes the value labels, but also removes the value entirely. I need this to have a label of some sort as I am converting the file and when there is no values defined it turns the value into a numeric. Therefore, I need the all value labels changed into numbers so that each value's label is just the value - value = 1 then label = 1.
Any ideas to do this across all my variables??
Thanks in advance!!
Here is a solution to get you started:
get file="C:\Program Files\IBM\SPSS\Statistics\23\Samples\English\Employee data.sav".
begin program.
import spss, spssaux, spssdata
spss.Submit("set mprint on.")
vd=spssaux.VariableDict(variableType ="numeric")
for v in vd:
allvalues = list(set(item[0] for item in spssdata.Spssdata(v.VariableName, names=False).fetchall()))
if allvalues:
cmd="value labels " + v.VariableName + "\n".join([" %(i)s '%(i)s'" %locals() for i in allvalues if i <> None]) + "."
spss.Submit(cmd)
spss.Submit("set mprint off.")
end program.
You may want to read this to understand the behaviour of fetchall in reading date variables (or simply exclude date variables from having their values labelled also, if they cause no problems?)

Overlay char string with a pattern

I wanna add the missing spaces in a character variable.
For instance bu_partner is char10 and has the value 31. In a standard database table there is only the value 0000000031.
I tried the overlay command, but 31 is at the beginning and not at the end.
DATA: mask TYPE bu_partner VALUE '0000000000',
partner TYPE bu_partner.
partner = '31'.
OVERLAY partner WITH mask.
write partner.
Output:
3100000000
Is there any way to achieve 0000000031?
Use the appropriate conversion exit as designated by the domain:
DATA: some_value TYPE c LENGTH 10,
partner TYPE bu_partner.
some_value = '31'.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = some_value
IMPORTING
output = partner.
WRITE: / partner USING NO EDIT MASK.
Be aware that you need to WRITE ... USING NO EDIT MASK in this case - if you don't use this addition, the list processing will automatically invoke CONVERSION_EXIT_ALPHA_OUTPUT which will eliminate the leading zeroes.
Please check the conversion routine mapped to the domain of bu_partner. You can check that in the domain which is mapped to the data element of bu_partner. I am guessing it would be ALPHA. Which means you should use the FM CONVERSION_EXIT_ALPHA_INPUT to convert external data to internal format ( if you input 31 then you would get output as 0000000031 ) . If you want to convert internal to external then use the FM CONVERSION_EXIT_ALPHA_OUTPUT where appropriate.
After some digging, I found the command UNPACK.
DATA: lv_partner_leading_zeros(10) type c,
lv_partner TYPE bu_partner.
lv_partner = '31'.
UNPACK lv_partner to lv_partner_leading_zeros.

how bytes are used to store information in protobuf

i am trying to understand the protocol buffer here is the sample , what i am not be able to understand is how bytes are being used in following messages. i dont know what this number
1 2 3 is used for.
message Point {
required int32 x = 1;
required int32 y = 2;
optional string label = 3;
}
message Line {
required Point start = 1;
required Point end = 2;
optional string label = 3;
}
message Polyline {
repeated Point point = 1;
optional string label = 2;
}
i read following paragraph in google protobuf but not able to understand what is being said here , can anyone help me in understanding how bytes are being used to store info.
The " = 1", " = 2" markers on each element identify the unique "tag" that field uses in the binary encoding. Tag numbers 1-15 require one less byte to encode than higher numbers, so as an optimization you can decide to use those tags for the commonly used or repeated elements, leaving tags 16 and higher for less-commonly used optional element.
The general form of a protobuf message is that it is a sequence of pairs of the form:
field header
payload
For your question, we can largely forget about the payload - that isn't the bit that relates to the 1/2/3 and the <=16 restriction - all of that is in the field header. The field header is a "varint" encoded integer; "varint" uses the most-significant-bit as an optional continuation bit, so small values (<=127, assuming unsigned and not zig-zag) require one byte to encode - larger values require multiple bytes. Or in other words, you get 7 useful bits to play with before you need to set the continuation bit, requiring at least 2 bytes.
However! The field header itself is composed of two things:
the wire-type
the field-number / "tag"
The wire-type is the first 3 bits, and indicates the fundamental format of the payload - "length-delimited", "64-bit", "32-bit", "varint", "start-group", "end-group". That means that of the 7 useful bits we had, only 4 are left; 4 bits is enough to encode numbers <= 16. This is why field-numbers <= 16 are suggested (as an optimisation) for your most common elements.
In your question, the 1 / 2 / 3 is the field-number; at the time of encoding this is left-shifted by 3 and composed with the payload's wire-type; then this composed value is varint-encoded.
Protobuf stores the messages like a map from an id (the =1, =2 which they call tags) to the actual value. This is to be able to more easily extend it than if it would transfer data more like a struct with fixed offsets. So a message Point for instance would look something like this on a high level:
1 -> 100,
2 -> 500
Which then is interpreted as x=100, y=500 and label=not set. On a lower level, protobuf serializes this tag-value mapping in a highly compact format, which among other things, stores integers with variable-length encoding. The paragraph you quoted just highlights exactly this in the case of tags, which can be stored more compactly if they are < 16, but the same for instance holds for integer values in your protobuf definition.

Convert Enum to Binary (via Integer or something similar)

I have an Ada enum with 2 values type Polarity is (Normal, Reversed), and I would like to convert them to 0, 1 (or True, False--as Boolean seems to implicitly play nice as binary) respectively, so I can store their values as specific bits in a byte. How can I accomplish this?
An easy way is a lookup table:
Bool_Polarity : constant Array(Polarity) of Boolean
:= (Normal=>False, Reversed => True);
then use it as
B Boolean := Bool_Polarity(P);
Of course there is nothing wrong with using the 'Pos attribute, but the LUT makes the mapping readable and very obvious.
As it is constant, you'd like to hope it optimises away during the constant folding stage, and it seems to: I have used similar tricks compiling for AVR with very acceptable executable sizes (down to 0.6k to independently drive 2 stepper motors)
3.5.5 Operations of Discrete Types include the function S'Pos(Arg : S'Base), which "returns the position number of the value of Arg, as a value of type universal integer." Hence,
Polarity'Pos(Normal) = 0
Polarity'Pos(Reversed) = 1
You can change the numbering using 13.4 Enumeration Representation Clauses.
...and, of course:
Boolean'Val(Polarity'Pos(Normal)) = False
Boolean'Val(Polarity'Pos(Reversed)) = True
I think what you are looking for is a record type with a representation clause:
procedure Main is
type Byte_T is mod 2**8-1;
for Byte_T'Size use 8;
type Filler7_T is mod 2**7-1;
for Filler7_T'Size use 7;
type Polarity_T is (Normal,Reversed);
for Polarity_T use (Normal => 0, Reversed => 1);
for Polarity_T'Size use 1;
type Byte_As_Record_T is record
Filler : Filler7_T;
Polarity : Polarity_T;
end record;
for Byte_As_Record_T use record
Filler at 0 range 0 .. 6;
Polarity at 0 range 7 .. 7;
end record;
for Byte_As_Record_T'Size use 8;
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_As_Record_T,
Target => Byte_T);
function Convert is new Ada.Unchecked_Conversion
(Source => Byte_T,
Target => Byte_As_Record_T);
begin
-- TBC
null;
end Main;
As Byte_As_Record_T & Byte_T are the same size, you can use unchecked conversion to convert between the types safely.
The representation clause for Byte_As_Record_T allows you to specify which bits/bytes to place your polarity_t in. (i chose the 8th bit)
My definition of Byte_T might not be what you want, but as long as it is 8 bits long the principle should still be workable. From Byte_T you can also safely upcast to Integer or Natural or Positive. You can also use the same technique to go directly to/from a 32 bit Integer to/from a 32 bit record type.
Two points here:
1) Enumerations are already stored as binary. Everything is. In particular, your enumeration, as defined above, will be stored as a 0 for Normal and a 1 for Reversed, unless you go out of your way to tell the compiler to use other values.
If you want to get that value out of the enumeration as an Integer rather than an enumeration value, you have two options. The 'pos() attribute will return a 0-based number for that enumeration's position in the enumeration, and Unchecked_Conversion will return the actual value the computer stores for it. (There is no difference in the value, unless an enumeration representation clause was used).
2) Enumerations are nice, but don't reinvent Boolean. If your enumeration can only ever have two values, you don't gain anything useful by making a custom enumeration, and you lose a lot of useful properties that Boolean has. Booleans can be directly selected off of in loops and if checks. Booleans have and, or, xor, etc. defined for them. Booleans can be put into packed arrays, and then those same operators are defined bitwise across the whole array.
A particular pet peeve of mine is when people end up defining themselves a custom boolean with the logic reversed (so its true condition is 0). If you do this, the ghost of Ada Lovelace will come back from the grave and force you to listen to an exhaustive explanation of how to calculate Bernoulli sequences with a Difference Engine. Don't let this happen to you!
So if it would never make sense to have a third enumeration value, you just name objects something appropriate describing the True condition (eg: Reversed_Polarity : Boolean;), and go on your merry way.
It seems all I needed to do was pragma Pack([type name]); (in which 'type name' is the type composed of Polarity) to compress the value down to a single bit.

VB6: Surely this simple Hex addition is wrong?

I'm getting odd results in some VB6 code which I've narrowed to this:
Debug.Print Hex(&hEDB80000 + &h8300)
Shows EDB78300
That can't by right can it? Surely it should be EDB88300?
Am I going mad?
Don't forget how negative numbers are expressed in binary, and that VB6 and VB.NET interpret numbers like &h8300 differently.
Because &hEDB80000 doesn't fit in 16-bits, VB interprets it as a long (32-bits). Because the high bit is set, VB6 knows it's negative.
Let's undo the two's complement (in a 32-bit world) to figure out the decimal value
(~&hEDB80000 + 1) = &h1247FFFF + 1 = &h12480000 = 306708480
since the sign bit was set, that's -306708480
Because &h8300 fits in 16-bits, VB interprets it as an integer (16-bits). Because the high bit is set, VB6 knows that it's negative.
Let's undo the two's complement (in a 16-bit world)
(~&h8300 + 1) = &h7DFF + 1 = &h7D00 = 32000
since the sign bit was set, that's -32000. When the addition happens, both values are considered to be longs (32-bits).
(-306708480) + (-32000) = -306740480
Let's put that back into two's complement hex
~(306740480 - 1) = ~(&h12487D00 - 1) = ~(&h12487CFF) = &hEDB78300
So &hEDB78300 is the correct answer.
Notes:
I personally thing the confusion happens because of the following:
&h0004000 is interpreted as 16384 // Fits in 16-bits, sign bit is not set
&h0008000 is interpreted as -32768 // Fits in 16-bits, sign bit is set
&h0010000 is interpreted as 65536 // Requires 32-bits, sign bit is not set
as mentioned in the other post, you can get around this by explicitly marking values as longs
&h0004000& is interpreted as 16384
&h0008000& is interpreted as 32768
&h0010000& is interpreted as 65536
Fundementally because VB6 sees &h8300 as an integer having the value -32000. To get the results you were expecting you would need to explictly mark it as a Long:-
Debug.Print Hex(&hEDB80000 + &h8300&)
What your were doing was adding a Long to an Interger. To do that VB6 first extends the Integer to a Long, since &h8300 represents a negative number the Long it is converted to ends up with the value &hFFFF8300. Armed with that value you can see that the result returned by VB6 is correct.
FF + B8 = B7 with carry bit set
FF + ED + carry bit = ED

Resources