Archives for: September 2005, 14

14/09/05

Permalink 04:41:15 pm
Categories: General, Programming, .NET

LINQ resources

Just to pass on another piece of news from PDC, here's a list of information resources about LINQ, which is a fantastic extension to common programming models that we have today. Problem is, it seems to be quite a while away :-)

Permalink 04:38:02 pm
Categories: General

New Office 12 gui

Among the news coming from PDC are reports from the first public presentation of Office 12. Lots of gui changes is the most obvious thing to know about that. They replaced the menu bar with the ribbon... hm :-) Go have a look!

Permalink 10:32:05 am
Categories: General

Project challenge expo in London

It's next week and I'm going to be there. Registration is free, so if you're at all interested in project management or anything that has remotely to do with it, be sure to check out the website and consider coming!

Permalink 10:14:55 am
Categories: General, Best text editor

No time for text editor tests

I just thought it might be a good idea to write a post for my text editor category again - the problem is, I don't currently have the time to do more tests. I haven't lost interest in this, so rest assured there will be more tests as soon as my time allows it!

Permalink 10:12:01 am
Categories: General, Programming, .NET

Object pooling, part 5

This is the fifth article in my mini series about object pooling. Be sure to read part 1, part 2, part 3 and part 4 first.

This part is going to make some modifications to the code in the GetObject() method to implement various alternative behaviours there. Think about it: what do you want to happen if there's no free object to be had in the pool? I came up with the following possible options:

  1. Return null. In this case, the caller would have to deal with the problem further if it can't get a pool object.
  2. Throw an exception. Really just a variant of (1), because it also pushes the problem out to the caller.
  3. Try again. Because objects are being used and returned to the pool all the time, it might make sense just to wait a bit and try to allocate an object one more time... or two more times, even. A maximum number of tries would be good, I guess.
  4. Extend the pool. The general growing/shrinking discussion hasn't taken place yet in these articles, but possibly the case where no more objects are available would be a good place to grow the pool.

Consider this changed code for the GetObject() method:

public T GetObject( ) {
  int tryNo = 1;

  while(tryNo <= maxGetObjectTries) {
    lock (poolLock) {
      Slot unusedSlot = pool.Find(delegate(Slot slot) {
        return !slot.InUse;
      });
      if (unusedSlot != null) {
        unusedSlot.Occupy( );
        return unusedSlot.PoolObject;
      }
    }

    switch (outOfObjectsBehaviour) {
      case OutOfObjectsBehaviour.ReturnNull:
        return default(T);
      case OutOfObjectsBehaviour.ThrowException:
        throw new OutOfObjectsException( );
      case OutOfObjectsBehaviour.WaitAndRetry:
        Thread.Sleep(retryWaitTime);
        break;
      case OutOfObjectsBehaviour.ExtendPool:
        ExtendPool( );
        break;
    }
  }

  throw new OutOfObjectsException( );
}

As you can see, the whole getting-an-object algorithms is potentially repeated multiple times now, possibly sleeping or trying pool extension in between. Finally, when a specific maximum number of retries has run out, an exception is thrown. I've specifically decided to do this instead of returning null - I'm assuming there might be no special code to handle null returns on the caller side, otherwise the pool could have been configured to return null in the first place.

The next interesting thing is the ExtendPool() method, which looks like this:

  /// 
  /// Extends the pool by a number of objects that's specified by the PoolExtensionBatchSize
  /// and the PoolExtensionBatchSizeIsPercent properties.
  /// 
  void ExtendPool( ) {
    lock (poolLock) {
      int newObjects = poolExtensionBatchSizeIsPercent ? 
        pool.Count * poolExtensionBatchSize / 100 : poolExtensionBatchSize;
      ExtendPoolBy(newObjects);
    }
  }

Several properties have been added to the pool to support the new functionality and there's also an enum for the out of objects behaviour. If you've been following the articles closely, you may have noticed that the maxPoolSize had already creapt in to the ExtendPoolBy() method last time, although I hadn't introduced it yet :-) Here it is now:

class Pool {
  . . .
  private int maxPoolSize;
  /// 
  /// Gets or sets a value indicating the maximum number of objects that the pool
  /// shall hold. The ExtendPoolBy() method won't extend the pool to a larger
  /// size than this.
  /// 
  public int MaxPoolSize {
    get {
      return maxPoolSize;
    }
    set {
      if (maxPoolSize != value) {
        maxPoolSize = value;
        lock (poolLock) {
          // This might be replaced by a call to the proper shrinking
          // method later.
          if (pool.Count > maxPoolSize)
            pool.RemoveRange(maxPoolSize, pool.Count - maxPoolSize);
        }
      }
    }
  }

  private int maxGetObjectTries;
  /// 
  /// Gets or sets a value that defines the maximum tries that are made 
  /// to acquire an object from the pool in the GetObject() method.
  /// 
  public int MaxGetObjectTries {
    get {
      return maxGetObjectTries;
    }
    set {
      if (maxGetObjectTries != value) {
        maxGetObjectTries = value;
      }
    }
  }

  private int poolExtensionBatchSize;
  /// 
  /// Gets or sets a value that defines the size of the batch when the pool is 
  ///  growing. This can be an absolute value or a percentage, which is 
  /// defined by the PoolExtensionBatchSizeIsPercent property.
  /// 
  public int PoolExtensionBatchSize {
    get {
      return poolExtensionBatchSize;
    }
    set {
      if (poolExtensionBatchSize != value) {
        poolExtensionBatchSize = value;
      }
    }
  }

  private bool poolExtensionBatchSizeIsPercent;
  /// 
  /// Gets or sets a flag that indicates whether the value given by 
  /// the PoolExtensionBatchSize property is an absolute value or a percentage.
  /// 
  public bool PoolExtensionBatchSizeIsPercent {
    get {
      return poolExtensionBatchSizeIsPercent;
    }
    set {
      if (poolExtensionBatchSizeIsPercent != value) {
        poolExtensionBatchSizeIsPercent = value;
      }
    }
  }

  private int retryWaitTime;
  /// 
  /// Gets or sets a value that defines the time to wait between tries
  /// to acquire a pool object in the GetObject() method. This is only 
  /// evaluated for OutOfObjectsBehaviour == WaitAndRetry.
  /// 
  public int RetryWaitTime {
    get {
      return retryWaitTime;
    }
    set {
      if (retryWaitTime != value) {
        retryWaitTime = value;
      }
    }
  }

  private OutOfObjectsBehaviour outOfObjectsBehaviour;
  /// 
  /// Gets or sets a value indicating the behaviour that the GetObject()
  /// method shows when a pool object isn't (immediately) available.
  /// 
  public OutOfObjectsBehaviour OutOfObjectsBehaviour {
    get {
      return outOfObjectsBehaviour;
    }
    set {
      if (outOfObjectsBehaviour != value) {
        outOfObjectsBehaviour = value;
      }
    }
  }
  . . .
}

/// 
/// Defines the possible behaviours that the GetObject()
/// method can shows when a pool object isn't (immediately) available.
/// 
public enum OutOfObjectsBehaviour {
  /// 
  /// Return null or the default value of the type.
  /// 
  ReturnNull,
  /// 
  /// Wait for a time specified by the Pool.RetryWaitTime property and try again.
  /// A maximum number of tries is specified by the Pool.MaxGetObjectTries
  /// property.
  /// 
  WaitAndRetry,
  /// 
  /// Throw an OutOfObjectsException.
  /// 
  ThrowException,
  /// 
  /// Extend the pool by a default batch as defined by the 
  /// Pool.PoolExtensionBatchSize and Pool.PoolExtensionBatchSizeIsPercent
  /// properties, then try again. A maximum number of tries is specified by 
  /// the Pool.MaxGetObjectTries property.
  /// 
  ExtendPool
}

Sorry I still didn't make it to the growing/shrinking, at least not completely. Well, next time!

Enter your email address:

Search

Oliver
MVP logo
September 2005
Sun Mon Tue Wed Thu Fri Sat
 << < Current> >>
        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