Dalvik VM hash-unit test

Source: Internet
Author: User
Unit Test of Dalvik Virtual Machine hash table

 

Source code in DVM
Dalvik/Vm/test/testhash. cpp is a built-in ut test case of DVM. Its implementation is intuitive. Let's analyze it briefly:

 

Test cases:

All tests are performed in the dvmtesthash () function. The test procedure is as follows.

 

 

The first round is basic API testing, including creating, inserting, searching, traversing, and releasing hash tables.

Create a hash table for the first test:

Logv ("testhash begin ");

// Rambo: allocate 12 but insert more, to let hash to extend
PTAB = dvmhashtablecreate (dvmhashsize (12), free );
If (PTAB = NULL)
Return false;

 

Add a hash unit to the table. The unit value is the string "entry xx" XX, which is an integer from 1 to knumtestentries. The Unit Key is calculated using the dvmcomputeutf8hash function.

Dvmhashtablelock (PTAB );

/* Add some entries */
For (I = 0; I <knumtestentries; I ++ ){
Sprintf (tmpstr, "entry % d", I );
Hash = dvmcomputeutf8hash (tmpstr );
Dvmhashtablelookup (PTAB, hash, strdup (tmpstr ),
(Hashcomparefunc) strcmp, true );
}

Dvmhashtableunlock (PTAB );

 

Then, you can search for all the units you just added:

 

/* Make sure we can find all entries */
For (I = 0; I <knumtestentries; I ++ ){
Sprintf (tmpstr, "entry % d", I );
Hash = dvmcomputeutf8hash (tmpstr );
STR = (const char *) dvmhashtablelookup (PTAB, hash, tmpstr,
(Hashcomparefunc) strcmp, false );
If (STR = NULL ){
LogE ("testhash: Failure: cocould not find '% S'", tmpstr );
/* Return false */
}
}

 

Then try to search for a nonexistent unit:

/* Make sure it behaves correctly when entry not found and! Doadd */
Sprintf (tmpstr, "entry % d", 17 );
Hash = dvmcomputeutf8hash (tmpstr );
STR = (const char *) dvmhashtablelookup (PTAB, hash, tmpstr,
(Hashcomparefunc) strcmp, false );
If (STR = NULL ){
/* GOOD */
} Else {
LogE ("testhash found nonexistent string (improper add ?) ");
}

 

Call dumpforeach (PTAB) to test the dvmhashforeach function.

Static void dumpforeach (hashtable * PTAB)
{
Int COUNT = 0;

// Printf ("print from foreach: \ n ");
Dvmhashforeach (PTAB, printfunc, & COUNT );
If (count! = Knumtestentries ){
LogE ("testhash foreach test failed ");
Assert (false );
}
}

The input traversal execution function is printfunc. It traverses a hash table and simply increases the number of units:

Static int printfunc (void * data, void * Arg)
{
// Printf ("'% s' \ n", (const char *) data );
// (Shocould verify strings)

Int * COUNT = (int *) ARG;
(* Count) ++;
Return 0;
}

Dumpforeach is used to test whether the number of units is correct after dvmhashforeach traversal.

 

Call dumpiterator (PTAB) to check whether the hash table traversal tool works normally. The implementation is to simply traverse the Left and Right units and check whether the number of units is correct.

Static void dumpiterator (hashtable * PTAB)
{
Int COUNT = 0;

// Printf ("print from iterator: \ n ");
Hashiter ITER;
For (dvmhashiterbegin (PTAB, & ITER );! Dvmhashiterdone (& ITER );
Dvmhashiternext (& ITER ))
{
// Const char * STR = (const char *) dvmhashiterdata (& ITER );
// Printf ("'% s' \ n", STR );
// (Shocould verify strings)
Count ++;
}
If (count! = Knumtestentries ){
LogE ("testhash iterator test failed ");
Assert (false );
}
}

 

Call dvmhashtablefree to release the hash table. The first round of test is complete.

/* Make sure they all get freed */
Dvmhashtablefree (PTAB)

 

The second round of tests is used to test "unconventional" scenarios:

First, create a hash table with the initial capacity of only two units:

PTAB = dvmhashtablecreate (dvmhashsize (2), free );
If (PTAB = NULL)
Return false;

 

Then, try to insert two units with the same hash value!

Hash = 0;

/* Two entries, same hash, different values */
Const char * str1;
Str1 = (char *) dvmhashtablelookup (PTAB, hash, strdup ("one "),
(Hashcomparefunc) strcmp, true );
Assert (str1! = NULL );
STR = (const char *) dvmhashtablelookup (PTAB, hash, strdup ("two "),
(Hashcomparefunc) strcmp, true );

 

Then, remove the first unit:

/* Remove the first one */
If (! Dvmhashtableremove (PTAB, hash, (void *) str1 ))
LogE ("testhash failed to delete item ");
Else
Free (void *) str1); // "Remove" doesn't call the free func

 

Check whether there is only one unit in the hash table:

/* Make sure iterator doesn't supported ded deleted entries */
Int COUNT = 0;
Hashiter ITER;
For (dvmhashiterbegin (PTAB, & ITER );! Dvmhashiterdone (& ITER );
Dvmhashiternext (& ITER ))
{
Count ++;
}
If (count! = 1 ){
LogE ("testhash wrong number of entries (% d)", count );
}

Then check that the removed unit cannot be searched, but the second unit can:

/* See if we can find them */
STR = (const char *) dvmhashtablelookup (PTAB, hash, (void *) "one ",
(Hashcomparefunc) strcmp, false );
If (STR! = NULL)
LogE ("testhash deleted entry has returned! ");
STR = (const char *) dvmhashtablelookup (PTAB, hash, (void *) "two ",
(Hashcomparefunc) strcmp, false );
If (STR = NULL)
LogE ("testhash entry vanished ");

 

Next, check and insert 17 units into the hash table to check whether the automatic expansion of the hash table is correct:

/* Force a table realloc to exercise tombstone removal */
For (I = 0; I <20; I ++ ){
Sprintf (tmpstr, "entry % d", I );
STR = (const char *) dvmhashtablelookup (PTAB, hash, strdup (tmpstr ),
(Hashcomparefunc) strcmp, true );
Assert (STR! = NULL );
}

Finally, release the hash table. The test is complete.

Dvmhashtablefree (PTAB );
Logv ("testhash end ");

Return true

 

Test execution

Hash ut can be executed during DVM initialization, provided that the debug switch is Enabled:

 

// Dalvik/Vm/init. cpp

STD: String dvmstartup (INT argc, const char * const argv [],
Bool ignoreunrecognized, jnienv * penv)
{

...

 

# Ifndef ndebug
// Rambo: perform quick UT
If (! Dvmtesthash ())
LogE ("dvmtesthash failed ");

...
# Endif

...

}

 

To enable the debug switch, we can specify

 

// Dalvik/Vm/DVM. mk

# Make a debugging version when building the simulator (if not told
# Otherwise) And when explicitly asked.
Dvm_make_debug_vm: = false
Ifneq ($ (Strip $ (debug_dalvik_vm )),)
Dvm_make_debug_vm: =$ (debug_dalvik_vm)
Endif

Ifeq ($ (dvm_make_debug_vm), true)

...

Local_cflags + =-undebug-ddebug = 1-dlog_ndebug = 1-dwith_dalvik_assert

Else

...

Endif #! Dvm_make_debug_vm

 

For more information about DVM compiling scripts, see
Dalvik
VM make file config and source tree.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.