text: #include "skynet.h"
  
  #include "skynet_handle.h"
  #include "skynet_server.h"
  #include "rwlock.h"
  
  #include <stdlib.h>
  #include <assert.h>
  #include <string.h>
  
  #define DEFAULT_SLOT_SIZE 4
  #define MAX_SLOT_SIZE 0x40000000
  #define HASH_HANDLE(s, handle) (handle & (s->slot_size-1))
  
  struct handle_name {
  	char * name;
  	uint32_t handle;
  };
  
  struct handle_storage {
  	struct rwlock lock;
  
  	uint32_t harbor;                /* toby@2022-03-02): 每个进程一个8bit的标志 用作集群节点 */
  	uint32_t handle_index;          /* toby@2022-03-02): 每个服务对应一个24位范围内的id 0 被保留*/
  	int slot_size;                  /* toby@2022-03-02): 可以容纳的服务数 */
  	struct skynet_context ** slot;  /* toby@2022-03-02): 服务的指针数组 */
  
  	int name_cap;
  	int name_count;
  	struct handle_name *name;       /* toby@2022-03-04): 名字数组，按字符串大小排序 */
  };
  
  static struct handle_storage *H = NULL;
  
  uint32_t
  skynet_handle_register(struct skynet_context *ctx) {
  	struct handle_storage *s = H;
  
  	rwlock_wlock(&s->lock);
  
  	for (;;) {
  		int i;
  		uint32_t handle = s->handle_index;
  		for (i=0;i<s->slot_size;i++,handle++) {
  			if (handle > HANDLE_MASK) {
  				// 0 is reserved
  				handle = 1;
  			}
              int hash = HASH_HANDLE(s, handle);
  			if (s->slot[hash] == NULL) {
  				s->slot[hash] = ctx;
  				s->handle_index = handle + 1;
  
  				rwlock_wunlock(&s->lock);
  
  				handle |= s->harbor;
  				return handle;
  			}
  		}
          //(toby@2022-03-01): id不够用了 按2倍扩展
  		assert((s->slot_size*2 - 1) <= HANDLE_MASK);
  		struct skynet_context ** new_slot = skynet_malloc(s->slot_size * 2 * sizeof(struct skynet_context *));
  		memset(new_slot, 0, s->slot_size * 2 * sizeof(struct skynet_context *));
  		for (i=0;i<s->slot_size;i++) {
  			int hash = skynet_context_handle(s->slot[i]) & (s->slot_size * 2 - 1);
  			assert(new_slot[hash] == NULL);
  			new_slot[hash] = s->slot[i];
  		}
  		skynet_free(s->slot);
  		s->slot = new_slot;
  		s->slot_size *= 2;
  	}
  }
  
  int
  skynet_handle_retire(uint32_t handle) {
  	int ret = 0;
  	struct handle_storage *s = H;
  
  	rwlock_wlock(&s->lock);
  
  	uint32_t hash = HASH_HANDLE(s, handle);
  	struct skynet_context * ctx = s->slot[hash];
  
  	if (ctx != NULL && skynet_context_handle(ctx) == handle) {
  		s->slot[hash] = NULL;
  		ret = 1;
  		int i;
  		int j=0, n=s->name_count;
  		for (i=0; i<n; ++i) {
  			if (s->name[i].handle == handle) {
  				skynet_free(s->name[i].name);
  				continue;
  			} else if (i!=j) {
                  /* toby@2022-03-02): 后面的值都向前移动 */
  				s->name[j] = s->name[i];
  			}
  			++j;
  		}
  		s->name_count = j;
  	} else {
  		ctx = NULL;
  	}
  
  	rwlock_wunlock(&s->lock);
  
  	if (ctx) {
  		// release ctx may call skynet_handle_* , so wunlock first.
  		skynet_context_release(ctx);
  	}
  
  	return ret;
  }
  
  void
  skynet_handle_retireall() {
  	struct handle_storage *s = H;
  	for (;;) {
  		int n=0;
  		int i;
  		for (i=0;i<s->slot_size;i++) {
  			rwlock_rlock(&s->lock);
  			struct skynet_context * ctx = s->slot[i];
  			uint32_t handle = 0;
  			if (ctx) {
  				handle = skynet_context_handle(ctx);
              }
  			rwlock_runlock(&s->lock);
  			if (handle != 0) {
  				if (skynet_handle_retire(handle)) {
  					++n;
  				}
  			}
  		}
  		if (n==0)
  			return;
  	}
  }
  
  struct skynet_context *
  skynet_handle_grab(uint32_t handle) {
  	struct handle_storage *s = H;
  	struct skynet_context * result = NULL;
  
  	rwlock_rlock(&s->lock);
  
  	uint32_t hash = HASH_HANDLE(s, handle);
  	struct skynet_context * ctx = s->slot[hash];
  	if (ctx && skynet_context_handle(ctx) == handle) {
  		result = ctx;
  		skynet_context_grab(result);
  	}
  
  	rwlock_runlock(&s->lock);
  
  	return result;
  }
  
  uint32_t
  skynet_handle_findname(const char * name) {
  	struct handle_storage *s = H;
  
  	rwlock_rlock(&s->lock);
  
  	uint32_t handle = 0;
  
  	int begin = 0;
  	int end = s->name_count - 1;
  	while (begin<=end) {
  		int mid = (begin+end)/2;
  		struct handle_name *n = &s->name[mid];
  		int c = strcmp(n->name, name);
  		if (c==0) {
  			handle = n->handle;
  			break;
  		}
  		if (c<0) {
  			begin = mid + 1;
  		} else {
  			end = mid - 1;
  		}
  	}
  
  	rwlock_runlock(&s->lock);
  
  	return handle;
  }
  
  static void
  _insert_name_before(struct handle_storage *s, char *name, uint32_t handle, int before) {
  	if (s->name_count >= s->name_cap) {
  		s->name_cap *= 2;
  		assert(s->name_cap <= MAX_SLOT_SIZE);
  		struct handle_name * n = skynet_malloc(s->name_cap * sizeof(struct handle_name));
  		int i;
  		for (i=0;i<before;i++) {
  			n[i] = s->name[i];
  		}
  		for (i=before;i<s->name_count;i++) {
  			n[i+1] = s->name[i];
  		}
  		skynet_free(s->name);
  		s->name = n;
  	} else {
  		int i;
  		for (i=s->name_count;i>before;i--) {
  			s->name[i] = s->name[i-1];
  		}
  	}
  	s->name[before].name = name;
  	s->name[before].handle = handle;
  	s->name_count ++;
  }
  
  static const char *
  _insert_name(struct handle_storage *s, const char * name, uint32_t handle) {
  	int begin = 0;
  	int end = s->name_count - 1;
  	while (begin<=end) {
  		int mid = (begin+end)/2;
  		struct handle_name *n = &s->name[mid];
  		int c = strcmp(n->name, name);
  		if (c==0) {
  			return NULL;
  		}
  		if (c<0) {
  			begin = mid + 1;
  		} else {
  			end = mid - 1;
  		}
  	}
  	char * result = skynet_strdup(name);
  
  	_insert_name_before(s, result, handle, begin);
  
  	return result;
  }
  
  const char *
  skynet_handle_namehandle(uint32_t handle, const char *name) {
  	rwlock_wlock(&H->lock);
  
  	const char * ret = _insert_name(H, name, handle);
  
  	rwlock_wunlock(&H->lock);
  
  	return ret;
  }
  
  void
  skynet_handle_init(int harbor) {
  	assert(H==NULL);
  	struct handle_storage * s = skynet_malloc(sizeof(*H));
  	s->slot_size = DEFAULT_SLOT_SIZE;
  	s->slot = skynet_malloc(s->slot_size * sizeof(struct skynet_context *));
  	memset(s->slot, 0, s->slot_size * sizeof(struct skynet_context *));
  
  	rwlock_init(&s->lock);
  	// reserve 0 for system
  	s->harbor = (uint32_t) (harbor & 0xff) << HANDLE_REMOTE_SHIFT;
  	s->handle_index = 1;
  	s->name_cap = 2;
  	s->name_count = 0;
  	s->name = skynet_malloc(s->name_cap * sizeof(struct handle_name));
  
  	H = s;
  
  	// Don't need to free H
  }
  
  