Generic Database #37
Aliases: Generic Database
19 verbs · 7 properties · 4 children
Verbs
| Verb | Spec | Flags | Definer | Lines |
|---|---|---|---|---|
find find_key | this none this | rxd | #37 | 30 |
find_exact | this none this | rxd | #37 | 14 |
find_all find_all_keys | this none this | rxd | #37 | 27 |
_only | this none this | rxd | #37 | 40 |
_every | this none this | rxd | #37 | 12 |
_every_key | this none this | rxd | #37 | 14 |
insert | this none this | rxd | #37 | 71 |
delete | this none this | rxd | #37 | 43 |
delete2 | this none this | rxd | #37 | 50 |
set_node | this none this | rxd | #37 | 1 |
make_node | this none this | rxd | #37 | 2 |
kill_node | this none this | rxd | #37 | 2 |
clearall | this none this | rxd | #37 | 25 |
clearall_big | this none this | rxd | #37 | 5 |
_kill_subtrees | this none this | rxd | #37 | 16 |
depth | this none this | rxd | #37 | 14 |
count_entries | this none this | rxd | #37 | 10 |
count_chars | this none this | rxd | #37 | 13 |
count | any in/inside/into this | rd | #37 | 10 |
Properties
| Property | Definer | Flags | Owner | Value |
|---|---|---|---|---|
node_perms | #37 | rc | #36 | "r" |
data | #37 | r | #36 | 4 |
| #37 | | #36 | {"", "", {}, {}} |
key | #1 | c | #36 | <clear> |
aliases | #1 | rc | #36 | {"Generic Database"} |
description | #1 | rc | #36 | "A generic `database' (well, really more like a string-indexed array if you want the truth...). See `help $generic_db' for details." |
object_size | #1 | r | #36 | {17177, -1090650497} |
Ancestry
Ancestors (nearest first): #1 Root Class
Children: #16 Registration Database, #25 Site DB, #39 Player Database, #78 Mail Name DB
Call graph
Source
find find_key
Referenced by
- #6:@registerme line 58:
$registration_db:find - #20:match_player line 30:
$player_db:find - #88:check_name line 4:
$player_db:find - #100:@update-reg*istration line 21:
$registration_db:find - #100:@update-reg*istration line 38:
$registration_db:find
Source
1"find(string[,n]) => datum corresponding to string with the search starting at node \" \"+string[1..n], n defaults to 0 (root node), $ambiguous_match or $failed_match"; 2"find_key(string[,n]) is like :find but returns the full string key rather than the associated datum. Note that if several string keys present in the db share a common prefix, :find_key(prefix) will return $ambiguous_match, but if there is a unique datum associated with all of these strings :find(prefix) will return it rather than $ambiguous_match."; 3"Assumes n<=length(string)"; 4{search, ?sofar = 0} = args; 5rest = search; 6prefix = search[1..sofar]; 7rest[1..sofar] = ""; 8info = this.(" " + prefix); 9data = (verb == "find") ? this.data | 3; 10if (i = search in info[3]) 11"...exact match for one of the strings in this node..."; 12return info[data][i]; 13elseif (index(info[1], rest) == 1) 14"...ambiguous iff there's more than one object represented in this node.."; 15return this:_only(prefix, data); 16elseif (index(rest, info[1]) != 1) 17"...search string doesn't agree with common portion..."; 18return $failed_match; 19elseif (index(info[2], search[nsofar = (sofar + length(info[1])) + 1])) 20"...search string follows one of continuations leading to other nodes..."; 21return this:(verb)(search, nsofar); 22else 23"...search string may partially match one of the strings in this node..."; 24for i in [1..length(exacts = info[3])] 25if (index(exacts[i], search) == 1) 26return info[data][i]; 27endif 28endfor 29return $failed_match; 30endif
find_exact
Referenced by
- #6:@addalias*# line 83:
$player_db:find_exact - #10:_match_player line 9:
$player_db:find_exact - #16:add line 6:
this:find_exact - #16:suspicious_address line 17:
this:find_exact - #16:suspicious_address line 34:
this:find_exact - #16:prune line 10:
this:find_exact - #24:show_netwho_from_listing line 18:
$site_db:find_exact - #24:do_make_player line 11:
$registration_db:find_exact - #25:add line 8:
this:find_exact - #25:add line 26:
this:find_exact - #25:prune line 13:
this:find_exact - #25:prune_fixup line 5:
this:find_exact - #37:find_exact line 11:
this:find_exact - #39:load line 15:
this:find_exact - #39:load line 28:
this:find_exact - #39:available line 10:
this:find_exact - #39:why_bad_name line 20:
$player_db:find_exact - #88:check_name line 2:
$player_db:find_exact
Source
1{search, ?sofar = 0} = args; 2rest = search; 3prefix = search[1..sofar]; 4rest[1..sofar] = ""; 5info = this.(" " + prefix); 6if (i = search in info[3]) 7return info[this.data][i]; 8elseif ((length(rest) <= (common = length(info[1]))) || (rest[1..common] != info[1])) 9return $failed_match; 10elseif (index(info[2], search[(sofar + common) + 1])) 11return this:find_exact(search, (sofar + common) + 1); 12else 13return $failed_match; 14endif
find_all find_all_keys
Referenced by
- #16:suspicious_address line 23:
this:find_all_keys - #16:prune line 9:
this:find_all_keys - #24:show_netwho_from_listing line 12:
$site_db:find_all_keys - #25:prune line 12:
this:find_all_keys - #46:match_failed line 8:
$player_db:find_all - #56:player_match_result line 37:
$player_db:find_all - #100:@update-reg*istration line 5:
$registration_db:find_all - #100:@update-reg*istration line 8:
$registration_db:find_all_keys - #100:@update-reg*istration line 18:
$registration_db:find_all_keys
Source
1":find_all(string [,n=0])"; 2"assumes n <= length(string)"; 3{search, ?sofar = 0} = args; 4rest = search; 5prefix = search[1..sofar]; 6rest[1..sofar] = ""; 7info = this.(" " + prefix); 8data = (verb == "find_all") ? this.data | 3; 9if (index(info[1], rest) == 1) 10"...return entire subtree."; 11return this:((data == 3) ? "_every_key" | "_every")(prefix); 12elseif (index(rest, info[1]) != 1) 13"...common portion doesn't agree."; 14return {}; 15elseif (index(info[2], rest[1 + (common = length(info[1]))])) 16"...matching strings are in a subnode."; 17return this:(verb)(search, (sofar + common) + 1); 18else 19"...matching string is in info[3]. length(rest) > common,"; 20"...so there will be at most one matching string."; 21for i in [1..length(info[3])] 22if (index(info[3][i], search) == 1) 23return {info[data][i]}; 24endif 25endfor 26return {}; 27endif
_only
Referenced by
Source
1":_only(prefix,data) => if all strings in this node have the same datum, return it, otherwise, return $ambiguous_match."; 2if (caller != this) 3raise(E_PERM); 4endif 5{prefix, data} = args; 6info = this.(" " + prefix); 7if (data == 3) 8"... life is much simpler if there's no separate datum."; 9"... if there's more than one string here, we barf."; 10if (info[2] || (length(info[3]) > 1)) 11return $ambiguous_match; 12elseif (info[3]) 13return info[3][1]; 14else 15"..this can only happen with the root node of an empty db."; 16return $failed_match; 17endif 18elseif (info[2]) 19what = this:_only(tostr(prefix, info[1], info[2][1]), data); 20if (what == $ambiguous_match) 21return what; 22endif 23elseif (info[data]) 24what = info[data][1]; 25info[data] = listdelete(info[data], 1); 26else 27"..this can only happen with the root node of an empty db."; 28return $failed_match; 29endif 30for x in (info[data]) 31if (what != x) 32return $ambiguous_match; 33endif 34endfor 35for i in [2..length(info[2])] 36if (what != this:_only(tostr(prefix, info[1], info[2][i]), data)) 37return $ambiguous_match; 38endif 39endfor 40return what;
_every
Referenced by
- #37:_every line 8:
this:_every
Source
1if (caller != this) 2raise(E_PERM); 3endif 4info = this.(" " + args[1]); 5prefix = args[1] + info[1]; 6r = $list_utils:remove_duplicates(info[4]); 7for i in [1..length(branches = info[2])] 8for new in (this:_every(prefix + branches[i])) 9r = setadd(r, new); 10endfor 11endfor 12return r;
_every_key
Referenced by
- #37:_every_key line 8:
this:_every_key
Source
1if (caller != this) 2raise(E_PERM); 3endif 4info = this.(" " + args[1]); 5prefix = args[1] + info[1]; 6r = info[3]; 7for i in [1..length(branches = info[2])] 8for new in (this:_every_key(prefix + branches[i])) 9r = setadd(r, new); 10(ticks_left() < 3600) && suspend(0); 11endfor 12(seconds_left() < 4) && suspend(0); 13endfor 14return r;
insert
Referenced by
- #16:add line 8:
this:insert - #16:add line 10:
this:insert - #16:add line 12:
this:insert - #16:prune line 31:
this:insert - #25:add line 10:
this:insert - #25:add line 12:
this:insert - #25:add line 27:
this:insert - #25:add line 37:
this:insert - #25:prune line 26:
this:insert - #25:prune_fixup line 25:
this:insert - #37:insert line 48:
this:insert - #39:insert line 3:
pass( - #78:add line 9:
this:insert - #78:add line 13:
this:insert - #78:add line 16:
this:insert - #78:remove line 13:
this:insert
Source
1":insert([n,]string,datum) -- inserts <string,datum> correspondence into tree starting at node \" \"+string[1..n], n defaulting to 0 (root node)."; 2"Assumes length(string) >= n"; 3"Returns {old_datum} (or 1) if there was a <string,old_datum> correspondence there before, otherwise returns 0"; 4if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 5return E_PERM; 6endif 7has_datum = this.data > 3; 8if (typeof(sofar = args[1]) == INT) 9search = args[2]; 10datum = has_datum ? args[3] | 0; 11else 12search = sofar; 13sofar = 0; 14datum = has_datum ? args[2] | 0; 15endif 16prefix = search[1..sofar]; 17info = this.(" " + prefix); 18if (i = search in info[3]) 19"... exact match ..."; 20if (has_datum) 21previous = {info[this.data][i]}; 22info[this.data][i] = datum; 23this:set_node(prefix, @info); 24return previous; 25else 26return 1; 27endif 28endif 29rest = search; 30rest[1..sofar] = ""; 31if (index(rest, info[1]) != 1) 32"... find where new string disagrees with common portion..."; 33c = $string_utils:common(rest, info[1]) + 1; 34"... make a new node with a shorter common portion...."; 35this:make_node(prefix + info[1][1..c], @listset(info, info[1][c + 1..$], 1)); 36this:set_node(prefix, info[1][1..c - 1], info[1][c], {search}, @has_datum ? {{datum}} | {}); 37return 0; 38elseif (rest == info[1]) 39".. new string == common portion, insert..."; 40info[3] = {@info[3], search}; 41if (has_datum) 42info[this.data] = {@info[this.data], datum}; 43endif 44this:set_node(prefix, @info); 45return 0; 46elseif (index(info[2], search[nsofar = (sofar + length(info[1])) + 1])) 47"... new string matches pre-existing continuation. insert in subnode...."; 48return this:insert(nsofar, search, datum); 49else 50"... new string may blow away one of the exact matches (i.e., matches one of them up to the first character beyond the common portion) in which case we need to create a new subnode...."; 51s = search[1..nsofar]; 52for m in (info[3]) 53if (index(m, s) == 1) 54i = m in info[3]; 55"... we know m != search ..."; 56"... string m has been blown away. create new node ..."; 57cbegin = cafter = length(s) + 1; 58cend = $string_utils:common(search, m); 59this:make_node(s, m[cbegin..cend], "", {search, m}, @has_datum ? {{datum, info[this.data][i]}} | {}); 60this:set_node(prefix, info[1], info[2] + s[nsofar], listdelete(info[3], i), @has_datum ? {listdelete(info[this.data], i)} | {}); 61return 0; 62endif 63endfor 64"... new string hasn't blown away any of the exact matches, insert it as a new exact match..."; 65info[3] = {search, @info[3]}; 66if (has_datum) 67info[this.data] = {datum, @info[this.data]}; 68endif 69this:set_node(prefix, @info); 70return 0; 71endif
delete
Referenced by
- #6:set_name line 22:
$player_db:delete - #16:prune line 28:
this:delete - #25:prune line 22:
this:delete - #25:prune_fixup line 20:
this:delete - #37:delete line 21:
this:delete - #100:@update-reg*istration line 29:
$registration_db:delete
Source
1":delete(string[,n]) deletes any <string,something> pair from the tree starting at node \" \"+string[1..n], n defaulting to 0 (root node)"; 2"Returns {something} if such a pair existed, otherwise returns 0"; 3"If that node is not the root node and ends up containing only one string and no subnodes, we kill it and return {something,string2,something2} where <string2,something2> is the remaining pair."; 4if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 5return E_PERM; 6endif 7{search, ?sofar = 0} = args; 8rest = search; 9prefix = search[1..sofar]; 10rest[1..sofar] = ""; 11info = this.(" " + prefix); 12if (i = search in info[3]) 13previous = {info[this.data][i]}; 14info[3] = listdelete(info[3], i); 15if (this.data > 3) 16info[this.data] = listdelete(info[this.data], i); 17endif 18elseif ((rest == info[1]) || ((index(rest, info[1]) != 1) || (!index(info[2], search[d = (sofar + length(info[1])) + 1])))) 19"... hmm string isn't in here..."; 20return 0; 21elseif ((previous = this:delete(search, d)) && (length(previous) > 1)) 22i = index(info[2], search[d]); 23info[2][i..i] = ""; 24info[3] = {previous[2], @info[3]}; 25if (this.data > 3) 26info[this.data] = {previous[3], @info[this.data]}; 27endif 28previous = previous[1..1]; 29else 30return previous; 31endif 32if ((!prefix) || ((length(info[3]) + length(info[2])) != 1)) 33this:set_node(prefix, @info); 34return previous; 35elseif (info[3]) 36this:kill_node(prefix); 37return {@previous, info[3][1], info[this.data][1]}; 38else 39sub = this.(" " + (p = tostr(prefix, info[1], info[2]))); 40this:kill_node(p); 41this:set_node(prefix, @listset(sub, tostr(info[1], info[2], sub[1]), 1)); 42return previous; 43endif
delete2
Referenced by
- #6:set_aliases line 35:
$player_db:delete2 - #24:unset_player line 23:
$player_db:delete2 - #24:unset_player line 25:
$player_db:delete2 - #37:delete2 line 28:
this:delete2 - #78:remove line 8:
this:delete2 - #78:remove line 11:
this:delete2 - #100:@update-reg*istration line 11:
$registration_db:delete2 - #100:@update-reg*istration line 13:
$registration_db:delete2 - #100:@update-reg*istration line 15:
$registration_db:delete2
Source
1":delete2(string,datum[,n]) deletes the pair <string,datum> from the tree starting at node \" \"+string[1..n], n defaulting to 0 (root node)"; 2"Similar to :delete except that if the entry for that string has a different associated datum, it will not be removed. "; 3":delete2(string,datum) is equivalent to "; 4" "; 5" if(this:find_exact(string)==datum) "; 6" this:delete(string); "; 7" endif"; 8if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 9return E_PERM; 10endif 11{search, datum, ?sofar = 0} = args; 12rest = search; 13prefix = search[1..sofar]; 14rest[1..sofar] = ""; 15info = this.(" " + prefix); 16if (i = search in info[3]) 17previous = {info[this.data][i]}; 18if (previous[1] != datum) 19return previous; 20endif 21info[3] = listdelete(info[3], i); 22if (this.data > 3) 23info[this.data] = listdelete(info[this.data], i); 24endif 25elseif ((rest == info[1]) || ((index(rest, info[1]) != 1) || (!index(info[2], search[d = (sofar + length(info[1])) + 1])))) 26"... hmm string isn't in here..."; 27return 0; 28elseif ((previous = this:delete2(search, datum, d)) && (length(previous) > 1)) 29i = index(info[2], search[d]); 30info[2][i..i] = ""; 31info[3] = {previous[2], @info[3]}; 32if (this.data > 3) 33info[this.data] = {previous[3], @info[this.data]}; 34endif 35previous = previous[1..1]; 36else 37return previous; 38endif 39if ((!prefix) || ((length(info[3]) + length(info[2])) != 1)) 40this:set_node(prefix, @info); 41return previous; 42elseif (info[3]) 43this:kill_node(prefix); 44return {@previous, info[3][1], info[this.data][1]}; 45else 46sub = this.(" " + (p = tostr(prefix, info[1], info[2]))); 47this:kill_node(p); 48this:set_node(prefix, @listset(sub, tostr(info[1], info[2], sub[1]), 1)); 49return previous; 50endif
set_node
Referenced by
- #37:insert line 23:
this:set_node - #37:insert line 36:
this:set_node - #37:insert line 44:
this:set_node - #37:insert line 60:
this:set_node - #37:insert line 69:
this:set_node - #37:delete line 33:
this:set_node - #37:delete line 41:
this:set_node - #37:delete2 line 40:
this:set_node - #37:delete2 line 48:
this:set_node - #37:clearall line 13:
this:set_node - #37:clearall line 15:
this:set_node
Source
1return (caller != this) ? E_PERM | (this.(" " + args[1]) = listdelete(args, 1));
make_node
Referenced by
- #37:insert line 35:
this:make_node - #37:insert line 59:
this:make_node
Source
1"WIZARDLY"; 2return (caller != this) ? E_PERM | add_property(this, " " + args[1], listdelete(args, 1), {$generic_db.owner, this.node_perms});
kill_node
Referenced by
- #37:delete line 36:
this:kill_node - #37:delete line 40:
this:kill_node - #37:delete2 line 43:
this:kill_node - #37:delete2 line 47:
this:kill_node - #37:_kill_subtrees line 14:
this:kill_node
Source
1"WIZARDLY"; 2return (caller != this) ? E_PERM | delete_property(this, " " + args[1]);
clearall
Referenced by
- #16:init_for_core line 3:
this:clearall - #25:load line 10:
this:clearall - #25:init_for_core line 3:
this:clearall - #37:clearall_big line 5:
this:clearall - #39:load line 9:
this:clearall - #78:init_for_core line 3:
this:clearall
Source
1"WIZARDLY"; 2if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 3return E_PERM; 4endif 5if (args && ((d = args[1]) in {3, 4})) 6this.data = d; 7endif 8root = {"", "", {}, @(this.data > 3) ? {{}} | {}}; 9"...since the for loop contains a suspend, we want to keep people"; 10"...from getting at properties which are now garbage but which we"; 11"...haven't had a chance to wipe yet. Somebody might yet succeed"; 12"...in adding something; thus we have the outer while loop."; 13this:set_node("", 37); 14while (this.(" ") != root) 15this:set_node("", @root); 16for p in (properties(this)) 17if ((p[1] == " ") && (p != " ")) 18delete_property(this, p); 19endif 20"...Bleah; db is inconsistent now...."; 21"...At worst someone will add something that references an"; 22"...existing property. He will deserve to die..."; 23$command_utils:suspend_if_needed(0); 24endfor 25endwhile
clearall_big
Referenced by
none
Source
1if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 2return E_PERM; 3endif 4this:_kill_subtrees("", 0); 5this:clearall(@args);
_kill_subtrees
Referenced by
- #37:clearall_big line 4:
this:_kill_subtrees - #37:_kill_subtrees line 13:
this:_kill_subtrees
Source
1":_kill_subtree(node,count)...wipes out all subtrees"; 2"...returns count + number of nodes removed..."; 3if (!($perm_utils:controls(caller_perms(), this) || (caller == this))) 4return E_PERM; 5endif 6info = this.(" " + (prefix = args[1])); 7count = args[2]; 8if ((ticks_left() < 500) || (seconds_left() < 2)) 9player:tell("...", count); 10suspend(0); 11endif 12for i in [1..length(info[2])] 13count = this:_kill_subtrees(n = tostr(prefix, info[1], info[2][i]), count) + 1; 14this:kill_node(n); 15endfor 16return count;
depth
Referenced by
- #37:depth line 9:
this:depth
Source
1info = this.(" " + (prefix = (args || {""})[1])); 2depth = 0; 3string = prefix; 4if ((ticks_left() < 500) || (seconds_left() < 2)) 5player:tell("...", prefix); 6suspend(0); 7endif 8for i in [1..length(info[2])] 9if ((r = this:depth(tostr(prefix, info[1], info[2][i])))[1] > depth) 10depth = r[1]; 11string = r[2]; 12endif 13endfor 14return {depth + 1, string};
count_entries
Referenced by
- #37:count_entries line 8:
this:count_entries - #37:count line 5:
this:count_entries
Source
1info = this.(" " + (prefix = args[1])); 2count = length(info[3]) + args[2]; 3if ((ticks_left() < 500) || (seconds_left() < 2)) 4player:tell("...", count); 5suspend(0); 6endif 7for i in [1..length(info[2])] 8count = this:count_entries(tostr(prefix, info[1], info[2][i]), count); 9endfor 10return count;
count_chars
Referenced by
- #37:count_chars line 11:
this:count_chars - #37:count line 7:
this:count_chars
Source
1info = this.(" " + (prefix = args[1])); 2count = args[2]; 3for s in (info[3]) 4count = count + length(s); 5endfor 6if ((ticks_left() < 500) || (seconds_left() < 2)) 7player:tell("...", count); 8suspend(0); 9endif 10for i in [1..length(info[2])] 11count = this:count_chars(tostr(prefix, info[1], info[2][i]), count); 12endfor 13return count;
count
Referenced by
none
Source
1"count [entries|chars] in <db>"; 2" reports on the number of distinct string keys or the number of characters"; 3" in all string keys in the db"; 4if (index("entries", dobjstr) == 1) 5player:tell(this:count_entries("", 0), " strings in ", this.name, "(", this, ")"); 6elseif (index("chars", dobjstr) == 1) 7player:tell(this:count_chars("", 0), " chars in ", this.name, "(", this, ")"); 8else 9player:tell("Usage: ", verb, " entries|chars in <db>"); 10endif