-
Notifications
You must be signed in to change notification settings - Fork 11
/
db_drop.c
99 lines (66 loc) · 2.35 KB
/
db_drop.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include "base64.h"
#include "db.h"
DbMap memMap[1];
// drop an arena given its r/b entry
// and recursively its children
void dropArenaDef(DbMap *db, ArenaDef *arenaDef, bool dropDefs, char *path, uint32_t pathLen) {
uint32_t len, count;
PathStk pathStk[1];
RedBlack *entry;
// drop our children
lockLatch (arenaDef->nameTree->latch);
// enumerate child nameTree
if ((entry = rbStart (db, pathStk, arenaDef->nameTree))) do {
ArenaDef *childDef = (ArenaDef *)(entry + 1);
len = addPath(path, pathLen, rbkey(entry), entry->keyLen, childDef->nxtVer);
atomicOr8(childDef->dead, KILL_BIT);
// delete our name from parent's nameList
if (dropDefs)
rbDel(db, arenaDef->nameTree, entry);
dropArenaDef(db, childDef, dropDefs, path, pathLen + len);
} while ((entry = rbNext(db, pathStk)));
path[pathLen] = 0;
unlockLatch(arenaDef->nameTree->latch);
// see if all handles have unbound
lockLatch(arenaDef->hndlArray->latch);
count = disableHndls(arenaDef->hndlArray);
unlockLatch(arenaDef->hndlArray->latch);
if (!count)
deleteMap(path);
}
// drop an arena and all of its children
// optionally, remove arenadef from parent childlist
DbStatus dropMap(DbMap *map, bool dropDefs) {
uint64_t id = map->arenaDef->id;
char path[MAX_path];
DbMap *ourDb;
// are we deleting a db from the catalog?
if (*map->arena->type == Hndl_database) {
ourDb = map->parent;
dropDefs = false;
} else
ourDb = map->db;
// are we already dropped?
if (atomicOr8(map->drop, KILL_BIT) & KILL_BIT)
return DB_ERROR_arenadropped;
atomicOr8((volatile uint8_t *)map->arena->mutex, KILL_BIT);
// remove id from parent's childMap list
lockLatch(map->parent->childMaps->latch);
// skipDel(memMap, map->parent->childMaps, id);
unlockLatch(map->parent->childMaps->latch);
// delete our r/b entry from parent's child nameList
// or kill our name tree from our surviving arenaDef
if (dropDefs) {
lockLatch (map->parent->arenaDef->nameTree->latch);
atomicOr8(map->arenaDef->dead, KILL_BIT);
rbDel(ourDb, map->parent->arenaDef->nameTree, map->rbEntry);
unlockLatch (map->parent->arenaDef->nameTree->latch);
}
memcpy (path, map->arenaPath, map->pathLen);
dropArenaDef(map->db, map->arenaDef, dropDefs, path, map->pathLen);
// when all of our children are unmapped
// we can unmap ourselves
if (!*map->openCnt)
closeMap(map);
return DB_OK;
}