Interpret DragAndDropRank

Document ID : KB000047752
Last Modified Date : 14/02/2018
Show Technical Document Details

Summary

How to interpret the 64-character of the field that holds the drag and drop Rank value, called DragAndDropRank.

Issue

A user would like to interpret the 64 char. value of DragAndDropRank and convert these 64 char. values into something numerical.

Resolution

Important: the method described below is for information purposes only and is NOT supported. It demonstrates a very rough approximation of the method CA Agile Central engineers used to make the ranks consistent after the old numeric Rank attribute was replaced with new alpha-numeric DragAndDropRank attribute. There are no guarantees that when this method is followed as described a complete match to the results of CA Agile Central's internal ranking algorithm can be achieved.

The rank values are base 94 values, using ASCII table but without the control characters (see the char[] digits array below). When we return WSAPI 1.x rank values we convert them to twelve digit decimals to simulate our old rank values. To do that we pull the 6 "most significant" characters from the left hand side and convert each value to long, pretty much like hexadecimal conversion. The customer could use a larger number of significant digits, but we found you need several million artifacts in a workspace before you start hitting collisions in this space.


Let's say WSAPI 2.x rank is:

,~~t~Bj^iEn{qqS5!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

We would use first 6 "most significant" characters from the left hand side:

,~~t~B

and it converts to 88068394267

If you query the same User Story in 2.x and 1.x and compare the DragAndDropRank vs the Rank value you can double check your calculations.

Here is some java code snippets to give the sense of how it works. It won't compile because some tweaking was done to them to have it make sense in this context. This code serve as illustration only.

The 6 character number above would become raw in the below method; essentially we calculate the numeric value of each letter than multiply it by the appropriate base.

public long convertToLong(String raw) {
??????? long ret = 0L;
??????? char[] chars = raw.toCharArray();
??????? int power = 0;
??????? for (int i = chars.length -1 ; i >=0; i--) {
??????????? long multiplier = (long) Math.pow(93, power);
??????????? long multiplicand = lookup.get(chars[i]);
??????????? ret +=(multiplicand * multiplier);
??????????? power++;
??????? }
??????? return ret;
??? }

protected static final char[] digits = {
??????????? '!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',
??????????? '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
??????????? ':', ';', '<', '=', '>', '?', '@',
??????????? 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
??????????? '[', '\\', ']', '^', '_', '`',
??????????? 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
??????????? '{','|','}','~'
??? };


private static Map<Character, Integer> lookup;
static {
??????? lookup = newHashMap();
??????? for (int i = 0; i < digits.length; i++) {
??????????? lookup.put(digits[i], i);
??????? }
??? }

//.............

EXAMPLE:

Let's say PortfolioItem/Feature query returns three objects. The query's fetch parameter included FromattedID and DragAndDropRank attributes:

Results:
[
{
FormattedID: F33,
DragAndDropRank: "P!!$(~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
},
{
FormattedID: F34,
DragAndDropRank: "P!!$)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
},
{
FormattedID: F35,
DragAndDropRank: "P!!$*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
}
]


The method below is an approximation. The precision will vary depending on the number of characters interpreted: the larger the number the closer it comes to being accurate.

Here is the array of characters that are used in DragAndDropRank. It is similar to ASCII table, but without the control characters

?'!', '"', '#', '$', '%', '&', '\'', '(', ')', '*', '+', ',', '-', '.', '/',? '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',? ':', ';', '<', '=', '>', '?', '@',? 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',? '[', '\\', ']', '^', '_', '`',? 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',? '{','|','}','~'


We will use base 94 and accumulate values from right to left. In this example we will start with the fifth character in the DragAndDropRank (fifth from the left) and go from right to left, but in many cases more precision is required.

This is an artificial example: only three features were created in the empty project, and we are going to interpret the initial DragAndDropRank values generated with the original revision of the artifacts.? Due to the contrived nature of this example? 5 characters is enough. Starting with the 6th character the values for rank are identical for all three features.

Here are the characters that happen to be used in the DragAndDropRank values in this exmaple:

'!' is at index 0
'$' is at index 3
'(' is at index 7
')' is at index 8
'*' is at index 9
'+' is at index 10
'P' is at index 47

Feature F35:

P!!$* resolves to 3669520403 based on these calculations:

character: *
(9 * (94^0=1)) = 9
accumulated = 9
character: $
(3 * (94^1=94)) = 282
accumulated = 291
character: !
(0 * (94^2=8836)) = 0
accumulated = 291
character: !
(0 * (94^3=830584)) = 0
accumulated = 291
character: P
(47 * (94^4=78074896)) = 3669520112
accumulated = 3669520403

Feature F34:

P!!$) resolves to 3669520402 based on these calculations:

character: )
(8 * (94^0=1)) = 8
accumulated = 8
character: $
(3 * (94^1=94)) = 282
accumulated = 290
character: !
(0 * (94^2=8836)) = 0
accumulated = 290
character: !
(0 * (94^3=830584)) = 0
accumulated = 290
character: P
(47 * (94^4=78074896)) = 3669520112
accumulated = 3669520402

Feature F33:

P!!$( resolves to 3669520401 based on these calculations:

character: (
(7 * (94^0=1)) = 7
accumulated = 7
character: $
(3 * (94^1=94)) = 282
accumulated = 289
character: !
(0 * (94^2=8836)) = 0
accumulated = 289
character: !
(0 * (94^3=830584)) = 0
accumulated = 289
character: P
(47 * (94^4=78074896)) = 3669520112
accumulated = 3669520401

If we stack the interpreted numeric values in ascending order they express the relative ranking, F35 being of highest rank and F33 being of lowest.

Feature F33: 3669520401
Feature F34: 3669520402
Feature F35: 3669520403