//===------- LockedMap.h - A thread-safe map implementation ---------------===//
//
//                               N3
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef N3_LOCKED_MAP_H
#define N3_LOCKED_MAP_H

#include <map>


#include <string.h>

#include "mvm/Object.h"
#include "mvm/PrintBuffer.h"
#include "mvm/Threads/Locks.h"

#include "types.h"

#include "CLIString.h"
#include "VMArray.h"

#include "UTF8.h"

namespace n3 {

class Assembly;
class N3;
class VMClass;
class VMCommonClass;
class VMField;
class VMObject;
class VMMethod;
class VMField;

template<class Key, class Container, class Compare, class Upcall>
class LockedMap : public mvm::PermanentObject {
public:

  typedef typename std::map<const Key, Container*, Compare>::iterator iterator;
  typedef Container* (*funcCreate)(Key& V, Upcall* ass);

  mvm::Lock *lock;
  std::map<Key, Container*, Compare,
           gc_allocator<std::pair<const Key, Container*> > > map;

	LockedMap(mvm::Lock *lock) {
		this->lock = lock;
	}
  
  inline Container* lookupOrCreate(Key& V, Upcall* ass, funcCreate func) {
    lock->lock();
    iterator End = map.end();
    iterator I = map.find(V);
    if (I == End) {
      Container* res = func(V, ass);
      map.insert(std::make_pair(V, res));
      lock->unlock();
      return res;
    } else {
      lock->unlock();
      return ((Container*)(I->second));
    }
  }
  
  inline Container* lookupOrCreate(Key&V, Container* C) {
    lock->lock();
    iterator End = map.end();
    iterator I = map.find(V);
    if (I == End) {
      map.insert(std::make_pair(V, C));
      lock->unlock();
      return C;
    } else {
      lock->unlock();
      return ((Container*)(I->second));
    }
  }

  inline Container* lookup(Key& V) {
    lock->lock();
    iterator End = map.end();
    iterator I = map.find(V);
    lock->unlock();
    return I != End ? ((Container*)(I->second)) : 0; 
  }

  inline void hash(Key& k, Container* c) {
    lock->lock();
    map.insert(std::make_pair(k, c));
    lock->unlock();
  }

  virtual void tracer() {
    //lock->MARK_AND_TRACE;
    for (iterator i = map.begin(), e = map.end(); i!= e; ++i) {
      i->second->tracer();
    }
  }

  virtual void print(mvm::PrintBuffer* buf) const {
    buf->write("Hashtable<>");
  }

};

class ClassNameCmp {
public:
  const UTF8* name;
  const UTF8* nameSpace;

  ClassNameCmp(const UTF8* u, const UTF8* n) : name(u), nameSpace(n) {}

  inline bool operator<(const ClassNameCmp &cmp) const {
    if (name < cmp.name) return true;
    else if (name > cmp.name) return false;
    else return nameSpace < cmp.nameSpace;
  }
};


class ClassNameMap : public LockedMap<ClassNameCmp, VMCommonClass, std::less<ClassNameCmp>, Assembly > {
public:
	ClassNameMap() : LockedMap<ClassNameCmp, VMCommonClass, std::less<ClassNameCmp>, Assembly >(new mvm::LockNormal()) {}
};

class ClassTokenMap : public LockedMap<uint32, VMCommonClass, std::less<uint32>, Assembly > {
public:
	ClassTokenMap() : LockedMap<uint32, VMCommonClass, std::less<uint32>, Assembly >(new mvm::LockNormal()) {}
};

class FieldTokenMap : public LockedMap<uint32, VMField, std::less<uint32>, Assembly > {
public:
	FieldTokenMap() : LockedMap<uint32, VMField, std::less<uint32>, Assembly >(new mvm::LockNormal()) {}
};

class MethodTokenMap : public LockedMap<uint32, VMMethod, std::less<uint32>, Assembly > {
public:
	MethodTokenMap() : LockedMap<uint32, VMMethod, std::less<uint32>, Assembly >(new mvm::LockNormal()) {}
};

class AssemblyMap : public LockedMap<const UTF8*, Assembly, std::less<const UTF8*>, N3 > {
public:
	AssemblyMap() : LockedMap<const UTF8*, Assembly, std::less<const UTF8*>, N3 >(new mvm::LockNormal()) {}
};


class StringMap : public LockedMap<const UTF8*, CLIString, std::less<const UTF8*>, N3 > { 
public:
	StringMap() : LockedMap<const UTF8*, CLIString, std::less<const UTF8*>, N3 >(new mvm::LockRecursive()) {}
};

class FunctionMap : public LockedMap<llvm::Function*, VMMethod, std::less<llvm::Function*>, N3 > { 
public:
	FunctionMap() : LockedMap<llvm::Function*, VMMethod, std::less<llvm::Function*>, N3 >(new mvm::LockNormal()) {}
};

} // end namespace n3

#endif
