MOO-cows Mailing List Archive


RE: server wish list: renumber

My short answer is that if you're going to add an extra argument, have
it be an objectid (i.e., something invalid to reinstantiate) rather than
a flag.  There are times you really want a specific object number.

There also needs to be a "find me the smallest invalid objectid that
doesn't own anything".  max_object()+1 isn't always guaranteed to be it.

In more detail, I'll spew part of my previous posting on the subject
(skip to "PROPOSALS" if you don't care about the rationale):

 = = = = = = = = = = = = = =
There are, to my mind, two valid reasons to care about the specific
object numbers used on creation and why you'd even want to use something
like renumber() at all:

(1) There are existing references to a currently-invalid objectid
    and you want the object you're creating to either avoid
    OR SATISFY these references.  

(2) The objectid table takes up space.  E.g., in order to create
    #2147483647, you need to create table slots for #0..#2147483646;
    at 4 bytes each this comes out to about 8Gbytes, even if
    these objects are never instantiated.  Thus, it is best
    to always use the lowest number available when creating.

For (2), the question of what "available" means depends entirely on what
you're creating.  While the the condition that the objectid is not
already the owner of something may be necessary, it is not always
sufficient.  There may well be other stuff in the db referencing the
objectid.  Say you have some additional condition, e.g., no references
anywhere in $registration_db/$player_db) and, say, the lowest hundred of
the invalid objectids are all unsuitable --- should one have to do
create()+renumber() 101 times?  (and then re-recycle the 100 objects you
don't use?  bleah).

And from (1), we see that though it's probably a good default, it's not
ALWAYS the case that you want a fresh owner.  Consider how you recover
if some idiot does `recycle($hacker)'.

It also worth noting that the usual #(max_object()+1) is NOT even
guaranteed to be a fresh owner, seeing as one can do
  bogus = create(...)
One could then argue that create() needs to grovel the DB the way
renumber() does, or that there's no point to having renumber() do so.  I
would only argue that it would be useful to separate the grovel-the-DB
functionality from the idea of assigning a new number to an object.

The first two should be minor patches.
The third is probably for the next maintainer.

I.  create (PARENT [, OWNER [, OBJECTID]]).

OBJECTID must be invalid, defaulting to #(max_object()+1) (*).
Stuff previously owned by OBJECTID will be owned by the new object.
Only wizards can specify non-default OWNER/OBJECTID.

II.  renumber (OBJECT [, OBJECTID])

(... for backward compatibility, since (I) takes care of most uses
     of renumber() that I know about...)
OBJECTID must be invalid, defaulting to the lowest non-negative invalid
objectid (*).  This grovels the DB and swaps ownerships between OBJECT

III.  is_non_owner(OBJECTID)

If not-already-owning-stuff is deemed a necessary "available" condition
for a fresh object, then we need to be able to get at this quickly.

 => TRUE only if OBJECTID (valid or invalid)
    is not present in any object/verb/property ownership slot.
 => FALSE means that the objectid MIGHT be present in some
    ownership slot.

 => lowest nonnegative invalid objectid satisfying is_non_owner().
   sweeps the DB and possibly increases the number of objects
   satisfying is_non_owner().
   This would also be done implicitly on server startup.

The idea here is to have a new flag on objects that gets set anytime
someone does a successful
add_property/set_property_info/add_verb/set_verb_info or .owner change. 
There would also be two possible entries in the object table for invalid
objects (INVALID_OWNER or INVALID_NON_OWNER); recycling an object sets
the object-table entry as appropriate.

Why should this be in the server?  Speed, mainly.  While this is do-able
in-db with wrappers, coding it in the face of suspensions is not
entirely trivial.  Also, given that the server goes to some trouble to
ensure that invalid objects are not assigned as owners, it stands to
reason that the machinery to track who actually *is* an owner should be
there as well.

(*) With is_non_owner() available,
  renumber() should default to min_non_owner() and 
  reset_max_object() should reset to the highest objectid for which
      valid(OBJID) || !is_non_owner(OBJID).

renumber(OBJ,NEWID) would also be a LOT faster if both OBJ and NEWID are

Home | Subject Index | Thread Index