Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - hamlet

Pages: [1]
1
Code Vault / unique ids
« on: January 01, 2010, 12:44:53 pm »
I needed unique (persistent) ids for something I was making, so I threw this code together.  Should provide unique ids "forever" within the limits of memory.  Thought other people might have a use for it.  Part of my reason for posting this is selfish... if you see something wrong, I want to know!  It has that "that was too easy" feeling.  No, I don't want to hear about the use of MAX_INT... yes, that could be done more intelligently, but, again, I wrote this because I needed it for something else.  Attention span problems.

Code: [Select]
/* Hamlet Jan 2010                               
   Hands out unique ids, which can be fetched as either arrays of ints,
   strings, or single ints.                                           
                                                                       
   The single int is "faster and easier", but may have roll-over.     
   You cannot make an assumption about the size of the array or string,
   but there will be no roll-over.                                     
                                                                       
   The returned values are "fetched" in batches of ID_BLOCK_SIZE, so   
   a reboot will mean there are some gaps in the numbering.           
*/                                                                     

/* Making ID_BLOCK_SIZE absurdly large is a bad idea.  Code assumes it will be
   "reasonable".  A smaller size means more saves, though.                   
*/                                                                           
#define ID_BLOCK_SIZE 1024                                                   
#define SAVE_FILE "/save/id"                                                 

#define MAX_INT 2147483647

nosave int *ID = ({ -1 });
int *NEXT_ID_BLOCK = ({ 0 });

private varargs int *increment(int *id, int amt);
int compare(int *a, int *b);                     

/* returns the full id as an array of ints */
int *get_id() {                             
  int *ret = copy(ID);                       
  if(compare(ID, NEXT_ID_BLOCK) == 0) {     
    NEXT_ID_BLOCK = increment(NEXT_ID_BLOCK, ID_BLOCK_SIZE);
    save_object(SAVE_FILE);                                 
  }                                                         
  ID = increment(ID);                                       
                                                           
  return ret;                                               
}                                                           

/* Returns just the last int of the id.  Unique until you overflow the int */
int get_int_id() {                                                           
  int *id = get_id();                                                       
  return id[<1];                                                             
}                                                                           

/* Returns a string representation of an item's id.  Easier for comparisons,
   guaranteed to be unique.  Hex because it doesn't matter.                 
*/                                                                         
string get_string_id() {                                                   
  string ret;                                                               
  int *id = get_id();                                                       
  int i;                                                                   
                                                                           
  ret = sprintf("%x", id[0]); // we don't want leading zeroes!             
                                                                           
  for(i=1; i < sizeof(id); i++)                                             
    ret += sprintf("%08x", id[i]);                                         
                                                                           
  return ret;                                                               
}                                                                           

/* Standard compare... 0 means equivalent.  < 0 means a is less.
   > 0 means b is less.                                         
*/                                                             
int compare(int *a, int *b) {                                   
  int i;                                                       
                                                               
  if(sizeof(a) != sizeof(b))                                   
    return sizeof(a) - sizeof(b);                               
                                                               
  for(i=0; i < sizeof(a); i++)                                 
    if(a[i] != b[i])                                           
      return a[i] - b[i];                                       
                                                               
  return 0;                                                     
}                                                               

private varargs int *increment(int *in_id, int amt) {
  int oldval;                                       
  int *id = copy(in_id); // not sure this is necessary
  int pos = sizeof(id) - 1;                           
                                                     
  if(amt < 0)                                         
    return 0;                                         
                                                     
  if(!amt)                                           
    amt = 1;

  oldval = id[pos];
  id[pos] += amt;

  while(id[pos] < oldval) { /* we've rolled */
    id[pos] -= MAX_INT; /* signed ints! */
    id[pos] -= 1;

    pos--;

    if(pos < 0)
      break;

    oldval = id[pos];
    id[pos]++;
  }

  if(pos == -1) { /* add another digit */
    id = ({ 1 }) + id;
  }

  return id;
}

private void create() {
  seteuid(getuid());
  restore_object(SAVE_FILE);
  ID = NEXT_ID_BLOCK;
}

void dest_me() {
//  save_object(SAVE_FILE);
  destruct(this_object());
}

2
Drivers / terminal_colour()
« on: April 23, 2008, 10:59:28 pm »
I was displeased with the terminal_colour() efun adding a RESET at the end of each line, so here's a patch to make it stop doing that.

http://www.cs.brown.edu/~icharles/terminal_colour_reset.diff

It may not be perfect, but it was quick to fix!

For those not in the know, terminal_colour()s syntax is:

varargs string terminal_colour(string str, mapping m, int wrap, int indent);

wrap and indent are optional.

To plagiarize discworld's help system:

It replaces each occurrence of %^key%^ in 'str' with 'value', where 'key' and 'value' are the elements of the mapping 'm'.
'wrap' is the optional column number to wrap at, and 'indent' is the amount to indent the second and following lines.
codes are assumed to change terminal state, but not generate printable characters.

Pages: [1]