Dalvik VM Hash - implementation

原创 2012年03月30日 00:27:28

Dalvik虚拟机 之 哈希表实现篇

前面两篇分别介绍了dvm里哈希表的接口和使用。下面我们来看看dvm里哈希表是怎么实现的。

 

数据结构

/*

* One entry in the hash table. "data" values are expected to be (or have

* the same characteristics as) valid pointers. In particular, a NULL

* value for "data" indicates an empty slot, and HASH_TOMBSTONE indicates

* a no-longer-used slot that must be stepped over during probing.

*

* Attempting to add a NULL or tombstone value is an error.

*

* When an entry is released, we will call (HashFreeFunc)(entry->data).

*/

struct HashEntry {

u4 hashValue;

void* data;

};

该结构表示一个哈希单元。它由两部分,一个四字节空间的哈希值和一个不定长的真正的数据部分。在该单元被清理时,该数据部分所占据的内存会被函数调用(HashFreeFunc)(entry->data)清理掉。该清理函数是在哈希表创建时传入的(dvmHashTableCreate()的第二个参数)。

/*

* Expandable hash table.

*

* This structure should be considered opaque.

*/

struct HashTable {

int tableSize; /* must be power of 2 */

int numEntries; /* current #of "live" entries */

int numDeadEntries; /* current #of tombstone entries */

HashEntry* pEntries; /* array on heap */

HashFreeFunc freeFunc;

pthread_mutex_t lock;

};

该结构表示一个哈希表。其成员变量分别是

tableSize: 哈希表的大小,必须是2的幂次。

numEntries: 当前哈希表用于的有效单元数量

numDeadEntries: 改哈希表拥有的无效单元数量。

pEntries: 表示指向该哈希表单元数据的指针

freeFunc: 哈希表单元释放函数

lock:用于同步访问该哈希表的锁。

 

我们后面会看到,哈希表实现中对于无效单元只是简单的将其哈希值表示为一个常量,而没有调用释放函数:

#define HASH_TOMBSTONE ((void*) 0xcbcacccd) // invalid ptr value

哈希表创建

/*

* Create and initialize a hash table.

*/

HashTable* dvmHashTableCreate(size_t initialSize, HashFreeFunc freeFunc)

{

HashTable* pHashTable;

 

assert(initialSize > 0);

 

pHashTable = (HashTable*) malloc(sizeof(*pHashTable));

if (pHashTable == NULL)

return NULL;

 

dvmInitMutex(&pHashTable->lock);

 

pHashTable->tableSize = dexRoundUpPower2(initialSize);

pHashTable->numEntries = pHashTable->numDeadEntries = 0;

pHashTable->freeFunc = freeFunc;

pHashTable->pEntries =

(HashEntry*) malloc(pHashTable->tableSize * sizeof(HashEntry));

if (pHashTable->pEntries == NULL) {

free(pHashTable);

return NULL;

}

 

memset(pHashTable->pEntries, 0, pHashTable->tableSize * sizeof(HashEntry));

return pHashTable;

}

 

首先用断言检查传入的初始大小必须大于0。然后用malloc分配本地内存最为哈希表的空间。由于分配的是本地内存,该哈希表不会被垃圾收集,并且需要在不使用时调用free()来显式的释放空间,否则将引起内存泄露。接下来初始化访问锁。随后调用dexRoundUpPower2来保证初始大小为2幂次方对齐。将有效单元数量和无效单元数量初始化为0。将参数传入的释放函数存放在freeFunc变量里。接着调用malloc为单元指针分配空间。 最后memset整个单元后返回改哈希表结构指针。

 

 

哈希表清理

 

/*

* Clear out all entries.

*/

void dvmHashTableClear(HashTable* pHashTable)

{

HashEntry* pEnt;

int i;

 

pEnt = pHashTable->pEntries;

for (i = 0; i < pHashTable->tableSize; i++, pEnt++) {

if (pEnt->data == HASH_TOMBSTONE) {

// nuke entry

pEnt->data = NULL;

} else if (pEnt->data != NULL) {

// call free func then nuke entry

if (pHashTable->freeFunc != NULL)

(*pHashTable->freeFunc)(pEnt->data);

pEnt->data = NULL;

}

}

 

pHashTable->numEntries = 0;

pHashTable->numDeadEntries = 0;

}

dvmHashTableClear实现。它遍历每个单元,对于无效的单元,简单的将该单元数据区置为NULL。对有效单元调用释放函数后将数据区置为NULL。

 

 

哈希表释放

/*

* Free the table.

*/

void dvmHashTableFree(HashTable* pHashTable)

{

if (pHashTable == NULL)

return;

dvmHashTableClear(pHashTable);

free(pHashTable->pEntries);

free(pHashTable);

}

首先调用dvmHashTableClear清理多有单元数据,然后free掉哈希表结构中为单元指针分配的内存,最后free掉该哈希表本身占据的内存。

 

 

哈希表查找和插入单元

哈希表查找,插入新单元是被放到同一个函数dvmHashTableLookup里实现的。用最后一个参数doAdd来区分开来。

首次是查找的实现,它从第一个单元开始遍历,如果该单元满足下面的条件

“pEntry->data != HASH_TOMBSTONE  && pEntry->hashValue == itemHash && (*cmpFunc)(pEntry->data, item) == 0”

也就是说必须 不能使无效单元,而且哈希值相等,并且调用比较函数的结果相符(返回值为0)。

如果doAdd为1,则进行插入操作。再插入之前,需要判断当前表示空间是否足够容纳新插入一个单元,不够的话需要扩展空间。

 

哈希表删除

和查找类似,也是根据哈希值找到第一个单元后,比较该单元的数值指针的值和带比较的是否一致。一致的话就表示该单元哈希值为常量HASH_TOMBSTONE。

 

 

 

 

 

 

 

 

 

JVM、DVM(Dalvik VM)和ART虚拟机对比

本文在于帮助大家快速的有一定深度的了解Android虚拟机。如果读者期望更加深入的了解相关的内容,可以根据文末给出的参考资料继续往下学习。如果觉得文中内容有什么错误,欢迎读者朋友指正,同时如需要转载请...
  • evan_man
  • evan_man
  • 2016年09月02日 15:31
  • 3407

dalvik VM的解释器分析

以KK的dalvik源码为基础来解析。 使用的源码基于https://github.com/AOKP/dalvik, 可以从https://github.com/AOKP/dalvik/archive...
  • doon
  • doon
  • 2016年07月25日 17:29
  • 1706

深入理解Android之Java虚拟机Dalvik

一、背景这个选题很大,但并不是一开始就有这么高大上的追求。最初之时,只是源于对Xposed的好奇。Xposed几乎是定制ROM的神器软件技术架构或者说方法了。它到底是怎么实现呢?我本意就是想搞明白Xp...
  • Innost
  • Innost
  • 2015年12月22日 09:55
  • 32404

Dalvik vm Hash interface

Dalvik VM 哈希表 之 接口篇   几乎在所有的高级语言中都有哈希表(hashmap)的支持。它已经成为很多语言内建的数据类型。但是C语言创建较早,没有内建的哈希表类型的支持。我们只能通过...
  • rambo2188
  • rambo2188
  • 2012年03月30日 00:24
  • 2342

Dalvik VM——Research and Implement on Elastos.ppt

  • 2010年04月17日 17:26
  • 541KB
  • 下载

Dalvik VM Instruction Formats

  • 2011年12月02日 14:05
  • 76KB
  • 下载

Dalvik VM 簡介

  • 2012年05月02日 13:44
  • 2.43MB
  • 下载

Analysis-of-Dalvik-VM

  • 2010年09月16日 22:03
  • 709KB
  • 下载

JAVA implementation for Locality Sensitive Hash

private int dimention; //维度大小,例如对于sift特征来说就是128private int max; //所需向量中元素可能的上限,譬如对于RGB来说,就是255privat...
  • coffeefeel
  • coffeefeel
  • 2011年04月04日 16:03
  • 373

An ASIC Design for a High Speed Implementation of the Hash Function SHA-256

  • 2017年12月02日 21:39
  • 225KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Dalvik VM Hash - implementation
举报原因:
原因补充:

(最多只允许输入30个字)