blob: 7eed6db72263543939730001e0eaf0a724922782 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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;
}
};