blob: 764e323aeb6f14f3f509179e4ade13c5dc8abefa [file] [log] [blame]
#include "QueueLock.h"
template<class data_val_type> class ConcSegHashTable
{
data_val_type **hash_tables;
QueueLock *read_lock_queues;
QueueLock *write_lock_queues;
int number_of_segments;
int number_of_buckets;
int last_insert_segment;
public:
ConcSegHashTable(int m,int n)
{
int i;
int j;
i = 0;
j = 0;
number_of_segments = n;
number_of_buckets = m;
last_insert_segment = -1;
hash_tables = new data_val_type*[n];
for(i = 0;i < n;i++)
{
*(hash_tables + i) = new data_val_type[m];
for(j = 0;j < m;j++)
{
*(*(hash_tables + i) + j) = 0;
}
}
read_lock_queues = new QueueLock[m * n];
write_lock_queues = new QueueLock[m * n];
read_lock_queues->SetTimeOutPeriod(3.0);
write_lock_queues->SetTimeOutPeriod(3.0);
}
int HashVal(data_val_type val)
{
return ((val/3) + 1);
}
int GetReadLock(int seg_index, int pos, char *name1)
{
QueueLock *current_write = write_lock_queues + (seg_index + pos);
QueueLock *current_read = read_lock_queues + (seg_index + pos);
const volatile int *p_write_lock_flag = current_write->GetPointerToFlag();
if(current_write->CheckLockIsAcquired() == 1)
{
while(*(p_write_lock_flag) != 0)
{
//Spinning waiting for write lock to release
}
}
return (current_read->GetLock(name1));
}
int GetWriteLock(int seg_index, int pos, char *name1)
{
QueueLock *current_write = write_lock_queues + (seg_index + pos);
QueueLock *current_read = read_lock_queues + (seg_index + pos);
const int *p_read_lock_flag = current_read->GetPointerToFlag();
if(current_read->CheckLockIsAcquired())
{
while(*(p_read_lock_flag) != 0)
{
//Spinning waiting for read lock to release
}
}
return (current_write->GetLock(name1));
}
void UpgradeLock(int seg_index, int pos, char *name1)
{
int i;
QueueLock *current_write = write_lock_queues + (seg_index + pos);
current_write->ForceLock(name1); //We need to immediately get a write lock in order to upgrade the lock.
ReleaseReadLock(name1);
}
void ReleaseWriteLock(int seg_index, int pos, char *name1)
{
QueueLock *current_write = write_lock_queues + (seg_index + pos);
current_write->ReleaseLock(name1);
cout<<"Write lock released"<<endl;
}
void ReleaseReadLock(int seg_index, int pos, char *name1)
{
QueueLock *current_read = read_lock_queues + (seg_index + pos);
current_read->ReleaseLock(name1);
}
int SegmentInsert(int seg_index, data_val_type val, int pos, bool ReplaceValue, char *name1)
{
int get_write_lock = 0;
int get_read_lock = 0;
int check_lock_status = 0;
check_lock_status = (write_lock_queues + (seg_index + pos))->CheckLockIsAcquired();
if(check_lock_status == 1)
{
cout<<"Lock already taken"<<endl;
}
else
{
get_write_lock = GetWriteLock(seg_index, pos, name1);
if(get_write_lock == 0)
{
cout<<"did not get lock"<<" "<<seg_index<<" "<<pos<<" "<<name1<<endl;
return (0);
}
if(*(*(hash_tables + seg_index) + pos) == 0 || ReplaceValue == true)
{
*(*(hash_tables + seg_index) + pos) = val;
ReleaseWriteLock(seg_index, pos, name1);
return (1);
}
}
return (0);
}
int InsertElement(data_val_type val, bool ReplaceValue, char *name1)
{
int i;
int k;
int j;
int pos = HashVal(val);
j = 0;
if(last_insert_segment == -1)
{
k = 0;
}
else
{
k = last_insert_segment;
}
for(i = k;i < number_of_segments;i++)
{
if(SegmentInsert(i, val, pos, false, name1) == 1)
{
cout<<"value inserted at"<<" "<<i<<" "<<pos<<endl;
last_insert_segment = i;
return 1;
}
}
for(i = 0;i < k;i++)
{
if(SegmentInsert(i, val, pos, false, name1) == 1)
{
cout<<"value inserted at"<<" "<<i<<" "<<pos<<endl;
last_insert_segment = i;
return 1;
}
}
for(i = k;i < number_of_segments;i++)
{
for(j = pos;j < number_of_buckets;j++)
{
if(SegmentInsert(i, val, j, false, name1) == 1)
{
cout<<"value inserted open addressing"<<" "<<i<<" "<<j<<endl;
return (1);
}
}
}
return (0);
}
void PrintValues()
{
int i;
int j;
i = 0;
j = 0;
for(i = 0;i < number_of_segments;i++)
{
for(j = 0;j < number_of_buckets;j++)
{
cout<<i<<" "<<j<<" "<<*(*(hash_tables + i) + j)<<endl;
}
}
}
~ConcSegHashTable()
{
delete hash_tables[number_of_segments];
delete[] read_lock_queues;
delete[] write_lock_queues;
}
};