trie: implement clone() method (#852)
* Add Clone() for StringMap * Fix for std::string addition * trie: broken return key. * clonetrie: correct handle leakage. Co-authored-by: Kyle Sanderson <kyle.leet@gmail.com>
This commit is contained in:
parent
b8ae4e617b
commit
5fa25e70ad
@ -636,6 +636,56 @@ static cell_t GetTrieSnapshotKey(IPluginContext *pContext, const cell_t *params)
|
||||
return written;
|
||||
}
|
||||
|
||||
static cell_t CloneTrie(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
HandleError err;
|
||||
HandleSecurity sec = HandleSecurity(pContext->GetIdentity(), g_pCoreIdent);
|
||||
|
||||
CellTrie *pOldTrie;
|
||||
if ((err = handlesys->ReadHandle(params[1], htCellTrie, &sec, (void **)&pOldTrie))
|
||||
!= HandleError_None)
|
||||
{
|
||||
return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[1], err);
|
||||
}
|
||||
|
||||
CellTrie *pNewTrie = new CellTrie;
|
||||
Handle_t hndl = handlesys->CreateHandle(htCellTrie, pNewTrie, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
if (!hndl)
|
||||
{
|
||||
delete pNewTrie;
|
||||
return hndl;
|
||||
}
|
||||
|
||||
for (StringHashMap<Entry>::iterator it = pOldTrie->map.iter(); !it.empty(); it.next())
|
||||
{
|
||||
const char *key = it->key.c_str();
|
||||
StringHashMap<Entry>::Insert insert = pNewTrie->map.findForAdd(key);
|
||||
if (pNewTrie->map.add(insert, key))
|
||||
{
|
||||
StringHashMap<Entry>::Result result = pOldTrie->map.find(key);
|
||||
if (result->value.isCell())
|
||||
{
|
||||
insert->value.setCell(result->value.cell());
|
||||
}
|
||||
else if (result->value.isString())
|
||||
{
|
||||
insert->value.setString(result->value.c_str());
|
||||
}
|
||||
else if (result->value.isArray())
|
||||
{
|
||||
insert->value.setArray(result->value.array(), result->value.arrayLength());
|
||||
}
|
||||
else
|
||||
{
|
||||
handlesys->FreeHandle(hndl, NULL);
|
||||
return pContext->ThrowNativeError("Unhandled data type encountered, file a bug and reference pr #852");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hndl;
|
||||
}
|
||||
|
||||
REGISTER_NATIVES(trieNatives)
|
||||
{
|
||||
{"ClearTrie", ClearTrie},
|
||||
@ -666,6 +716,7 @@ REGISTER_NATIVES(trieNatives)
|
||||
{"StringMap.SetValue", SetTrieValue},
|
||||
{"StringMap.Size.get", GetTrieSize},
|
||||
{"StringMap.Snapshot", CreateTrieSnapshot},
|
||||
{"StringMap.Clone", CloneTrie},
|
||||
|
||||
{"StringMapSnapshot.Length.get", TrieSnapshotLength},
|
||||
{"StringMapSnapshot.KeyBufferSize", TrieSnapshotKeyBufferSize},
|
||||
|
@ -52,6 +52,14 @@ methodmap StringMap < Handle
|
||||
// The StringMap must be freed via delete or CloseHandle().
|
||||
public native StringMap();
|
||||
|
||||
// Clones a string map, returning a new handle with the same size and data.
|
||||
// This should NOT be confused with CloneHandle. This is a completely new
|
||||
// handle with the same data but no relation to the original. It should be
|
||||
// closed when no longer needed with delete or CloseHandle().
|
||||
//
|
||||
// @return New handle to the cloned string map
|
||||
public native StringMap Clone();
|
||||
|
||||
// Sets a value in a hash map, either inserting a new entry or replacing an old one.
|
||||
//
|
||||
// @param key Key string.
|
||||
|
@ -48,7 +48,7 @@ enum NodeType
|
||||
* @brief DEPRECATED. This class scales extremely poorly; insertion scales
|
||||
* quadratic (O(n^2)) with respect to the number of elements in the table.
|
||||
* Only use this class if you have less than 200 elements or so. Otherwise,
|
||||
* use StringHashMap in sm_hashtable.h which scales linearly and has comparable
|
||||
* use StringHashMap in sm_stringhashmap.h which scales linearly and has comparable
|
||||
* retrievable performance.
|
||||
*
|
||||
* See bug 5878 for more detail.
|
||||
|
Loading…
Reference in New Issue
Block a user