Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
PL/SQL and radix tree structure
1. In-Memory Computation
with Oracle PL/SQL
Use a Radix Tree structure
to determine International Calling Codes.
● Statement of a problem
● Long Distance Codes in a few words
● Reasons to move from SQL to PL/SQL in computations
● Radix Tree: Definition, implementation and results
2. Statement of a problem
What does a service provider, when processes requests
from subscribers for outgoing calls ?
Every time when the caller dials the phone number...
...something like +35621316599, the operator is
required to determine the direction of the call, to
connect the calling and called party.
Information about the direction of the call is International Calling Code
(АКА Long Distance Code, AKA Dial Prefix).
3. Despite the presence of technical recommendations, such as
ITU-T Recommendations E.164 and E.123, reference used by
operators contain Long Distance Codes in an unstructured way,
without a separating code fields by Country and Region code,
Trunk code, etc.
Long Distance Codes in a few words
Thus, for the Dial 79654012345 the direction of the
call will be a string from the reference table maximally
coinciding with the beginning of a Dial string, i.e.
796540.
This is one and only rule to find the Long Distance
Code within Dial string.
It should also be taken into account: we have several upstream service providers
for outgoing calls.
4. Try to search with SQL
Collect statistics about SQL request for the Dial prefix in production
environment:
● Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit
Production
● Database server with Intel(R) Xeon(R) CPU E5620 2.40GHz stepping
02, 32 GB RAM
● Number of the unique prefixes 19 278
● MAX length of the prefix 11 characters
5. Try to search with SQL
Grab 28 219 phone numbers from accounting data, pass it into the below query:
SELECT /*+ GATHER_PLAN_STATISTICS */ tpc_phone_prefix
FROM (
SELECT tpc_phone_prefix
FROM tplan_provider_cost
WHERE :P1 LIKE tpc_phone_prefix || '%'
ORDER BY LENGTHC(tpc_phone_prefix) DESC
) WHERE ROWNUM < 2
...then take a look at V$SQLAREA and access plan for the query
6. Try to search with SQL
INDEX FAST FULL SCAN with AVG_ELAPSED about ~0.08 sec. per execution
● EXECUTIONS: 28 219
● DISK_READS: 3 904
● BUFFER_GETS: 111 235 752
● AVG_CPU (per exec): 0.076 584
● AVG_ELAPSED (per exec): 0.076 704
7. What's wrong ?
We scan too wide range of the values with SQL LIKE condition,
whereas real statistics show the following:
The most used prefixes have a length in the range of 3-5 characters.
Definitely, we need another method to search the prefix...
8. Move from SQL to PL/SQL
Reasons to Move:
● OLTP behavior in the Calls processing, every request
processed individually;
● Context switching between SQL and PL/SQL has a value,
especially with a large number of short queries;
● There is no concurrent issues to access PGA memory after its
allocation to session, contrary to shared data buffers in SGA;
9. Radix Tree as a solution of the issue
Citation from Wikipedia:
In computer science, a radix tree (also radix trie or
compact prefix tree) is a data structure that represents
a space-optimized trie in which each node that is the
only child is merged with its parent.
It's looks like similarly as a set of prefixes
from page 3, isn't it?
10. We will be guided by the following rules:
● Searching for a prefix terminates when leaf
node was reached;
● Searching for a prefix terminates within a
node that has no transition for the next
symbol of a dialed phone number.
Radix Tree as a solution of the issue
Now we need to define a structure to organize the data as a trie
in a memory of PL/SQL.
13. Radix Tree MethodsBulk load the whole set of Radix Tree data.
PROCEDURE BulkLoad(
tData IN OUT NOCOPY RXT_WBM.RXT_TAB
, sClearStored IN SIGNTYPE
DEFAULT STD.STATE_OK
);
Scan and Validate the Tree for absence of a loose path, i.e. path without root Node in the its start.
FUNCTION ChkTree RETURN BINARY_INTEGER;
Returns the RXT_PREFIX_REC structure for the Key maximally coinciding with the beginning of the
vKey parameter. Also returns the Key itself in a second IN OUT parameter.
FUNCTION GetPrefix(
vKey IN OUT NOCOPY RXT_WBM.RXT_KEY_REG
, recPrefix IN OUT NOCOPY RXT_WBM.RXT_PREFIX_REC
, PBitMap IN RXT_WBM.RXT_BIT_MAP_REG
) RETURN RXT_WBM.RXT_KEY;
TYPE RXT_PREFIX_REC IS RECORD (
ID POSITIVE
, Prefix RXT_KEY_PREFIX
, AllBlocked SIGNTYPE
);
Returns count of members in a Tree nested table container.
FUNCTION TreeSize RETURN BINARY_INTEGER;
Accept the Node ID, find it in a Tree and restore value of associated Key by traversal to the root Node.
FUNCTION ID_TO_KEY(
iID IN POSITIVEN
) RETURN RXT.RXT_KEY;
14. Radix Tree performance testing
Bulk load whole Tree via BulkLoad() ~0.08 sec.
Validate Tree via ChkTree () ~2.8 sec.
Set of single executions of GetPrefix() in anonymous PL/SQL block
Execution time varies from value of vKey parameter.
Elapsed time in range ~0.000 037 - 0.000 043 sec.
Batch execution of GetPrefix()
Batch testing with 33 953 unique Phone Numbers successfully
dialed in a Production environment.
Average time per execution ~0.000 011 sec.